Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Salom! So'nggi paytlarda Docker tasvirlarini yaratish va Kubernetes-ga joylashtirish uchun ko'plab ajoyib avtomatlashtirish vositalari chiqarildi. Shu munosabat bilan men GitLab bilan o'ynashga, uning imkoniyatlarini chuqur o'rganishga va, albatta, quvurni o'rnatishga qaror qildim.

Ushbu ish veb-saytdan ilhomlangan kubernetes.iodan hosil qilingan manba kodlari avtomatik ravishda va yuborilgan har bir hovuz so'rovi uchun robot avtomatik ravishda o'zgartirishlaringiz bilan saytning oldindan ko'rish versiyasini yaratadi va ko'rish uchun havolani taqdim etadi.

Men shunga o'xshash jarayonni noldan qurishga harakat qildim, lekin butunlay Gitlab CI va Kubernetes-ga ilovalarni joylashtirish uchun ishlatadigan bepul vositalar asosida qurilgan. Bugun men nihoyat sizga ular haqida ko'proq ma'lumot beraman.

Maqolada quyidagi vositalar muhokama qilinadi:
Hugo, qbec, kaniko, git-crypt и GitLab CI dinamik muhitlarni yaratish bilan.

Tarkib

  1. Hugo bilan tanishing
  2. Docker faylini tayyorlash
  3. Kaniko bilan tanishish
  4. Qbec bilan tanishish
  5. Gitlab-runnerni Kubernetes-ijrochi bilan sinab ko'rish
  6. Qbec bilan Helm diagrammalarini joylashtirish
  7. Git-crypt bilan tanishtirish
  8. Asboblar qutisi tasvirini yaratish
  9. Bizning birinchi quvurimiz va teglar bo'yicha tasvirlarni yig'ish
  10. Joylashtirishni avtomatlashtirish
  11. O'zlashtirishga surish paytida artefaktlar va yig'ish
  12. Dinamik muhitlar
  13. Ilovalarni ko'rib chiqish

1. Gyugo bilan tanishish

Loyihamizga misol sifatida biz Hugo asosida qurilgan hujjatlarni nashr qilish saytini yaratishga harakat qilamiz. Hugo statik tarkib generatoridir.

Statik generatorlar bilan tanish bo'lmaganlar uchun men sizga ular haqida bir oz ko'proq ma'lumot beraman. Ma'lumotlar bazasi va foydalanuvchi tomonidan so'ralganda tezda sahifalar yaratadigan ba'zi PHP-ga ega an'anaviy veb-sayt dvigatellaridan farqli o'laroq, statik generatorlar biroz boshqacha tarzda ishlab chiqilgan. Ular sizga manbalarni, odatda Markdown belgilari va mavzu shablonlaridagi fayllar to'plamini olish imkonini beradi, keyin ularni to'liq tayyor veb-saytga kompilyatsiya qiladi.

Ya'ni, natijada siz katalog tuzilishi va yaratilgan HTML-fayllar to'plamini olasiz, ularni oddiygina istalgan arzon hostingga yuklashingiz va ishlaydigan veb-saytga ega bo'lishingiz mumkin.

Siz Hugo-ni mahalliy sifatida o'rnatishingiz va uni sinab ko'rishingiz mumkin:

Yangi sayt ishga tushirilmoqda:

hugo new site docs.example.org

Va ayni paytda git ombori:

cd docs.example.org
git init

Hozircha bizning saytimiz toza va unda biror narsa paydo bo'lishi uchun birinchi navbatda mavzuni bog'lashimiz kerak; mavzu shunchaki shablonlar to'plami va saytimiz yaratiladigan belgilangan qoidalardir.

Mavzu uchun biz foydalanamiz bilib oling, bu, mening fikrimcha, hujjatlar sayti uchun juda mos keladi.

Bizga alohida e'tibor qaratmoqchimanki, biz mavzu fayllarini loyihamiz omborida saqlashimiz shart emas; buning o'rniga biz uni oddiygina yordamida ulashimiz mumkin. git submodul:

git submodule add https://github.com/matcornic/hugo-theme-learn themes/learn

Shunday qilib, bizning omborimiz faqat loyihamiz bilan bevosita bog'liq bo'lgan fayllarni o'z ichiga oladi va ulangan mavzu ma'lum bir omborga havola va undagi majburiyat sifatida qoladi, ya'ni uni har doim asl manbadan olish mumkin va qo'rqmaslik kerak. mos kelmaydigan o'zgarishlar.

Keling, konfiguratsiyani to'g'rilaymiz config.toml:

baseURL = "http://docs.example.org/"
languageCode = "en-us"
title = "My Docs Site"
theme = "learn"

Ushbu bosqichda siz ishga tushirishingiz mumkin:

hugo server

Va manzilda http://localhost:1313/ bizning yangi yaratilgan veb-saytimizni tekshiring, katalogdagi barcha o'zgarishlar brauzerda ochiq sahifani avtomatik ravishda yangilaydi, juda qulay!

Keling, muqova sahifasini yaratishga harakat qilaylik content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Yangi yaratilgan sahifaning skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Sayt yaratish uchun quyidagi amallarni bajaring:

hugo

Katalog tarkibi tomoshabinlar/ va sizning veb-saytingiz bo'ladi.
Ha, aytmoqchi, darhol uni qo'shamiz .gitignore:

echo /public > .gitignore

O'zgarishlarimizni amalga oshirishni unutmang:

git add .
git commit -m "New site created"

2. Docker faylini tayyorlash

Bizning omborimiz tuzilishini aniqlash vaqti keldi. Men odatda shunga o'xshash narsalarni ishlataman:

.
├── deploy
│   ├── app1
│   └── app2
└── dockerfiles
    ├── image1
    └── image2

  • dockerfiles/ — Dockerfiles bilan kataloglarni va bizning Docker tasvirlarimizni yaratish uchun zarur bo'lgan barcha narsalarni o'z ichiga oladi.
  • joylashtirish/ — ilovalarimizni Kubernetes-ga joylashtirish uchun kataloglarni o'z ichiga oladi

Shunday qilib, biz yo'l bo'ylab birinchi Docker faylimizni yaratamiz dockerfiles/veb-sayt/Dockerfile

FROM alpine:3.11 as builder
ARG HUGO_VERSION=0.62.0
RUN wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz -C /usr/local/bin
ADD . /src
RUN hugo -s /src

FROM alpine:3.11
RUN apk add --no-cache darkhttpd
COPY --from=builder /src/public /var/www
ENTRYPOINT [ "/usr/bin/darkhttpd" ]
CMD [ "/var/www" ]

Ko'rib turganingizdek, Dockerfile ikkitadan iborat FROM, bu imkoniyat deyiladi ko'p bosqichli qurilish va oxirgi docker tasviridan keraksiz narsalarni chiqarib tashlashga imkon beradi.
Shunday qilib, yakuniy rasm faqat o'z ichiga oladi darkhttpd (engil HTTP serveri) va tomoshabinlar/ — statik tarzda yaratilgan veb-saytimizning mazmuni.

O'zgarishlarimizni amalga oshirishni unutmang:

git add dockerfiles/website
git commit -m "Add Dockerfile for website"

3. Kaniko bilan tanishish

Docker tasvir yaratuvchisi sifatida men foydalanishga qaror qildim kaniko, chunki uning ishlashi docker demonini talab qilmaydi va qurilishning o'zi har qanday mashinada amalga oshirilishi mumkin va kesh to'g'ridan-to'g'ri registrda saqlanishi mumkin, bu esa to'liq doimiy saqlashga ehtiyojni yo'q qiladi.

Tasvirni yaratish uchun konteynerni ishga tushirish kifoya kaniko ijrochisi va unga joriy kontekstni o'tkazing; buni mahalliy ravishda, docker orqali ham amalga oshirish mumkin:

docker run -ti --rm 
  -v $PWD:/workspace 
  -v ~/.docker/config.json:/kaniko/.docker/config.json:ro 
  gcr.io/kaniko-project/executor:v0.15.0 
  --cache 
  --dockerfile=dockerfiles/website/Dockerfile 
  --destination=registry.gitlab.com/kvaps/docs.example.org/website:v0.0.1

Qaerda registry.gitlab.com/kvaps/docs.example.org/website — docker tasviringiz nomi; qurilgandan so'ng u avtomatik ravishda docker registriga ishga tushiriladi.

Parametr --kesh docker registridagi qatlamlarni keshlash imkonini beradi; berilgan misol uchun ular saqlanadi registry.gitlab.com/kvaps/docs.example.org/website/cache, lekin parametr yordamida boshqa yo'lni belgilashingiz mumkin --kesh-repo.

Docker-registrning skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

4. Qbec tili bilan tanishish

Qbec ilova manifestlarini deklarativ tarzda tavsiflash va ularni Kubernetes-ga joylashtirish imkonini beruvchi joylashtirish vositasidir. Jsonnet-dan asosiy sintaksis sifatida foydalanish bir nechta muhitdagi farqlarning tavsifini sezilarli darajada soddalashtirishga imkon beradi, shuningdek, kod takrorlanishini deyarli butunlay yo'q qiladi.

Bu, ayniqsa, dasturni turli parametrlarga ega bo'lgan bir nechta klasterlarga joylashtirishingiz kerak bo'lgan va ularni Git-da deklarativ ravishda tavsiflashni xohlagan holatlarda to'g'ri kelishi mumkin.

Qbec shuningdek, Helm diagrammalarini kerakli parametrlarni o'tkazish orqali ko'rsatishga va keyin ularni oddiy manifestlar kabi ishlatishga imkon beradi, shu jumladan siz ularga turli xil mutatsiyalarni qo'llashingiz mumkin va bu, o'z navbatida, zaruratdan xalos bo'lishga imkon beradi. ChartMuseum-dan foydalaning. Ya'ni, siz diagrammalarni to'g'ridan-to'g'ri ular tegishli bo'lgan git-dan saqlashingiz va ko'rsatishingiz mumkin.

Yuqorida aytganimdek, biz barcha o'rnatishlarni katalogda saqlaymiz joylashtirish/:

mkdir deploy
cd deploy

Keling, birinchi dasturimizni ishga tushiramiz:

qbec init website
cd website

Endi dasturimizning tuzilishi quyidagicha ko'rinadi:

.
├── components
├── environments
│   ├── base.libsonnet
│   └── default.libsonnet
├── params.libsonnet
└── qbec.yaml

faylni ko'rib chiqaylik qbec.yaml:

apiVersion: qbec.io/v1alpha1
kind: App
metadata:
  name: website
spec:
  environments:
    default:
      defaultNamespace: docs
      server: https://kubernetes.example.org:8443
  vars: {}

Bu erda biz birinchi navbatda qiziqamiz spesifik. muhitlar, qbec allaqachon biz uchun standart muhit yaratgan va server manzilini, shuningdek, joriy kubeconfig dan nom maydonini olgan.
Endi tarqatish paytida default muhitda qbec har doim faqat belgilangan Kubernetes klasteriga va belgilangan nomlar maydoniga o'rnatiladi, ya'ni joylashtirishni amalga oshirish uchun endi kontekstlar va nomlar o'rtasida almashishingiz shart emas.
Agar kerak bo'lsa, siz ushbu fayldagi sozlamalarni har doim yangilashingiz mumkin.

Barcha muhitlaringiz ichida tasvirlangan qbec.yaml, va faylda params.libsonnet, bu erda ular uchun parametrlarni qaerdan olish kerakligi aytiladi.

Keyin biz ikkita katalogni ko'ramiz:

  • komponentlar/ — ilovamiz uchun barcha manifestlar shu yerda saqlanadi; ularni jsonnet va oddiy yaml fayllarida tasvirlash mumkin
  • muhitlar/ — bu yerda biz muhitimiz uchun barcha o‘zgaruvchilarni (parametrlarni) tasvirlab beramiz.

Odatiy bo'lib bizda ikkita fayl mavjud:

  • muhitlar/base.libsonnet - u barcha muhitlar uchun umumiy parametrlarni o'z ichiga oladi
  • muhitlar/default.libsonnet — muhit uchun bekor qilingan parametrlarni o'z ichiga oladi default

ochamiz muhitlar/base.libsonnet va u erda birinchi komponentimiz uchun parametrlarni qo'shing:

{
  components: {
    website: {
      name: 'example-docs',
      image: 'registry.gitlab.com/kvaps/docs.example.org/website:v0.0.1',
      replicas: 1,
      containerPort: 80,
      servicePort: 80,
      nodeSelector: {},
      tolerations: [],
      ingressClass: 'nginx',
      domain: 'docs.example.org',
    },
  },
}

Keling, birinchi komponentimizni ham yarataylik komponentlar/website.jsonnet:

local env = {
  name: std.extVar('qbec.io/env'),
  namespace: std.extVar('qbec.io/defaultNs'),
};
local p = import '../params.libsonnet';
local params = p.components.website;

[
  {
    apiVersion: 'apps/v1',
    kind: 'Deployment',
    metadata: {
      labels: { app: params.name },
      name: params.name,
    },
    spec: {
      replicas: params.replicas,
      selector: {
        matchLabels: {
          app: params.name,
        },
      },
      template: {
        metadata: {
          labels: { app: params.name },
        },
        spec: {
          containers: [
            {
              name: 'darkhttpd',
              image: params.image,
              ports: [
                {
                  containerPort: params.containerPort,
                },
              ],
            },
          ],
          nodeSelector: params.nodeSelector,
          tolerations: params.tolerations,
          imagePullSecrets: [{ name: 'regsecret' }],
        },
      },
    },
  },
  {
    apiVersion: 'v1',
    kind: 'Service',
    metadata: {
      labels: { app: params.name },
      name: params.name,
    },
    spec: {
      selector: {
        app: params.name,
      },
      ports: [
        {
          port: params.servicePort,
          targetPort: params.containerPort,
        },
      ],
    },
  },
  {
    apiVersion: 'extensions/v1beta1',
    kind: 'Ingress',
    metadata: {
      annotations: {
        'kubernetes.io/ingress.class': params.ingressClass,
      },
      labels: { app: params.name },
      name: params.name,
    },
    spec: {
      rules: [
        {
          host: params.domain,
          http: {
            paths: [
              {
                backend: {
                  serviceName: params.name,
                  servicePort: params.servicePort,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

Ushbu faylda biz bir vaqtning o'zida uchta Kubernetes ob'ektini tasvirlab berdik, bular: Tarqatish, xizmat и Kirish. Agar xohlasak, ularni turli qismlarga qo'yishimiz mumkin edi, ammo bu bosqichda biz uchun bittasi etarli bo'ladi.

sintaktik jsonnet oddiy json ga juda o'xshaydi, printsipial jihatdan, oddiy json allaqachon jsonnet hisoblanadi, shuning uchun dastlab siz kabi onlayn xizmatlardan foydalanish osonroq bo'lishi mumkin. yaml2json odatiy yamlni json ga aylantirish uchun yoki agar sizning komponentlaringizda hech qanday o'zgaruvchi bo'lmasa, ularni oddiy yaml shaklida tasvirlash mumkin.

Bilan ishlaganda jsonnet Men sizning muharriringiz uchun plaginni o'rnatishni tavsiya qilaman

Masalan, vim uchun plagin mavjud vim-jsonnet, bu sintaksisni ajratib ko'rsatishni yoqadi va avtomatik ravishda amalga oshiriladi jsonnet fmt har safar saqlaganingizda (jsonnet o'rnatilishini talab qiladi).

Hammasi tayyor, endi biz joylashtirishni boshlashimiz mumkin:

Bizda nima borligini ko'rish uchun yuguramiz:

qbec show default

Chiqishda siz standart klasterga qo'llaniladigan yaml manifestlarini ko'rasiz.

Ajoyib, endi murojaat qiling:

qbec apply default

Chiqishda siz doimo klasteringizda nima qilinishini ko'rasiz, qbec sizdan yozish orqali o'zgarishlarga rozi bo'lishingizni so'raydi. y niyatlaringizni tasdiqlay olasiz.

Ilovamiz tayyor va ishga tushirildi!

Agar siz o'zgartirish kiritsangiz, har doim shunday qilishingiz mumkin:

qbec diff default

ushbu o'zgarishlar joriy joylashtirishga qanday ta'sir qilishini ko'rish uchun

O'zgarishlarimizni amalga oshirishni unutmang:

cd ../..
git add deploy/website
git commit -m "Add deploy for website"

5. Gitlab-runner-ni Kubernetes-ijrochi bilan sinab ko'rish

Yaqin vaqtgacha men faqat muntazam foydalanardim gitlab-runner qobiq yoki docker-ijrochi bilan oldindan tayyorlangan mashinada (LXC konteyner). Dastlab, bizning gitlabimizda global miqyosda aniqlangan bir nechta shunday yuguruvchilar bor edi. Ular barcha loyihalar uchun docker tasvirlarini to'plashdi.

Ammo amaliyot shuni ko'rsatadiki, bu variant ham amaliylik, ham xavfsizlik nuqtai nazaridan eng ideal emas. Har bir loyiha yoki hatto har bir muhit uchun alohida yuguruvchilarni joylashtirish ancha yaxshi va g'oyaviy jihatdan to'g'riroq.

Yaxshiyamki, bu umuman muammo emas, chunki endi biz joylashtiramiz gitlab-runner bevosita Kubernetesdagi loyihamizning bir qismi sifatida.

Gitlab gitlab-runner-ni Kubernetes-ga joylashtirish uchun tayyor rul jadvalini taqdim etadi. Shunday qilib, siz qilishingiz kerak bo'lgan yagona narsa ro'yxatga olish belgisi bizning loyihamiz uchun Sozlamalar -> CI / CD -> Yuguruvchilar va uni rulga o'tkazing:

helm repo add gitlab https://charts.gitlab.io

helm install gitlab-runner 
  --set gitlabUrl=https://gitlab.com 
  --set runnerRegistrationToken=yga8y-jdCusVDn_t4Wxc 
  --set rbac.create=true 
  gitlab/gitlab-runner

Qaerda:

  • https://gitlab.com — Gitlab serveringiz manzili.
  • yga8y-jdCusVDn_t4Wxc — loyihangiz uchun roʻyxatdan oʻtish belgisi.
  • rbac.create=true — yuguruvchiga kubernetes-ijrochi yordamida vazifalarimizni bajarish uchun podlar yaratish imkoniyatiga ega bo'lish uchun kerakli miqdordagi imtiyozlarni beradi.

Agar hamma narsa to'g'ri bajarilgan bo'lsa, bo'limda ro'yxatdan o'tgan yuguruvchini ko'rishingiz kerak Runners, loyiha sozlamalaringizda.

Qo'shilgan yuguruvchining skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Shunchalik oddiymi? - Ha, bu juda oddiy! Yuguruvchilarni qo'lda ro'yxatdan o'tkazish bilan boshqa qiyinchilik yo'q, bundan buyon yuguruvchilar avtomatik ravishda yaratiladi va yo'q qilinadi.

6. QBEC bilan Helm diagrammalarini joylashtiring

Biz ko'rib chiqishga qaror qilganimizdan beri gitlab-runner loyihamizning bir qismi, uni Git omborimizda tasvirlash vaqti keldi.

Biz uni alohida komponent sifatida tasvirlashimiz mumkin Veb-sayt, lekin kelajakda biz turli nusxalarni joylashtirishni rejalashtirmoqdamiz Veb-sayt juda tez-tez, farqli o'laroq gitlab-runner, har bir Kubernetes klasteriga faqat bir marta joylashtiriladi. Keling, buning uchun alohida dasturni ishga tushiramiz:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Bu safar biz Kubernetes ob'ektlarini qo'lda tasvirlamaymiz, lekin tayyor Helm diagrammasini olamiz. Qbec ning afzalliklaridan biri bu Helm diagrammalarini to'g'ridan-to'g'ri Git omboridan ko'rsatish qobiliyatidir.

Keling, uni git submodul yordamida bog'laymiz:

git submodule add https://gitlab.com/gitlab-org/charts/gitlab-runner vendor/gitlab-runner

Endi katalog sotuvchi/gitlab-runner Bizda gitlab-runner uchun diagrammaga ega ombor mavjud.

Xuddi shunday, siz boshqa omborlarni, masalan, butun omborni rasmiy jadvallar bilan ulashingiz mumkin. https://github.com/helm/charts

Keling, komponentni tavsiflaymiz komponentlar/gitlab-runner.jsonnet:

local env = {
  name: std.extVar('qbec.io/env'),
  namespace: std.extVar('qbec.io/defaultNs'),
};
local p = import '../params.libsonnet';
local params = p.components.gitlabRunner;

std.native('expandHelmTemplate')(
  '../vendor/gitlab-runner',
  params.values,
  {
    nameTemplate: params.name,
    namespace: env.namespace,
    thisFile: std.thisFile,
    verbose: true,
  }
)

Birinchi dalil kengaytirishHelmTemplate biz diagrammaga yo'lni o'tamiz, keyin parametrlar.qiymatlar, biz atrof-muhit parametrlaridan olamiz, keyin ob'ekt bilan birga keladi

  • nom shablon - nashr sarlavhasi
  • nom maydoni — nomlar maydoni rulga o'tkazildi
  • bu fayl — joriy faylga yoʻlni oʻtuvchi talab qilinadigan parametr
  • batafsil - buyruqni ko'rsatadi rul shabloni diagrammani ko'rsatishda barcha argumentlar bilan

Endi bizning komponentimiz uchun parametrlarni tavsiflaymiz muhitlar/base.libsonnet:

local secrets = import '../secrets/base.libsonnet';

{
  components: {
    gitlabRunner: {
      name: 'gitlab-runner',
      values: {
        gitlabUrl: 'https://gitlab.com/',
        rbac: {
          create: true,
        },
        runnerRegistrationToken: secrets.runnerRegistrationToken,
      },
    },
  },
}

E'tibor bering runnerRegistrationToken biz tashqi fayldan olamiz secrets/base.libsonnet, keling, uni yaratamiz:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Keling, hamma narsa ishlayotganligini tekshirib ko'ramiz:

qbec show default

agar hamma narsa tartibda bo'lsa, biz Helm orqali ilgari o'rnatilgan nashrimizni o'chirib tashlashimiz mumkin:

helm uninstall gitlab-runner

va uni xuddi shu tarzda joylashtiring, lekin qbec orqali:

qbec apply default

7. Git-crypt bilan tanishtirish

Git-crypt sizning omboringiz uchun shaffof shifrlashni o'rnatish imkonini beruvchi vositadir.

Ayni paytda bizning gitlab-runner uchun katalog tuzilmasi quyidagicha ko'rinadi:

.
├── components
│   ├── gitlab-runner.jsonnet
├── environments
│   ├── base.libsonnet
│   └── default.libsonnet
├── params.libsonnet
├── qbec.yaml
├── secrets
│   └── base.libsonnet
└── vendor
    └── gitlab-runner (submodule)

Ammo Git-da sirlarni saqlash xavfsiz emas, shunday emasmi? Shuning uchun biz ularni to'g'ri shifrlashimiz kerak.

Odatda, bitta o'zgaruvchi uchun bu har doim ham mantiqiy emas. Siz sirlarni o'tkazishingiz mumkin qbec va CI tizimingizning muhit oʻzgaruvchilari orqali.
Ammo shuni ta'kidlash kerakki, yana ko'p sirlarni o'z ichiga olishi mumkin bo'lgan murakkabroq loyihalar mavjud; ularning barchasini atrof-muhit o'zgaruvchilari orqali uzatish juda qiyin bo'ladi.

Bundan tashqari, bu holda men sizga bunday ajoyib vosita haqida gapira olmayman git-crypt.

git-crypt Bundan tashqari, bu sizga sirlarning butun tarixini saqlashga, shuningdek, Git misolida odatlanganimizdek nizolarni solishtirish, birlashtirish va hal qilish imkonini berishi bilan ham qulay.

O'rnatishdan keyingi birinchi narsa git-crypt biz omborimiz uchun kalitlarni yaratishimiz kerak:

git crypt init

Agar sizda PGP kaliti bo'lsa, darhol o'zingizni ushbu loyiha uchun hamkor sifatida qo'shishingiz mumkin:

git-crypt add-gpg-user [email protected]

Shunday qilib, siz har doim shaxsiy kalitingiz yordamida ushbu omborni parolini hal qilishingiz mumkin.

Agar sizda PGP kaliti bo'lmasa va buni kutmasangiz, boshqa yo'l bilan borib, loyiha kalitini eksport qilishingiz mumkin:

git crypt export-key /path/to/keyfile

Shunday qilib, eksport qilingan har bir kishi kalit fayl sizning omboringiz shifrini ochish imkoniyatiga ega bo'ladi.

Birinchi sirimizni o'rnatish vaqti keldi.
Eslatib o'tamiz, biz hali ham katalogdamiz deploy/gitlab-runner/, bizda katalog mavjud sirlari/, undagi barcha fayllarni shifrlaymiz, buning uchun fayl yaratamiz sirlar/.gitattributes quyidagi tarkib bilan:

* filter=git-crypt diff=git-crypt
.gitattributes !filter !diff

Tarkibdan ko'rinib turibdiki, barcha fayllar niqoblangan * orqali haydaladi git-crypt, ko'pchilik bundan mustasno .gitattributes

Buni ishga tushirish orqali tekshirishimiz mumkin:

git crypt status -e

Chiqish shifrlash yoqilgan ombordagi barcha fayllar ro'yxati bo'ladi

Hammasi shu, endi biz xavfsiz o'zgarishlarni amalga oshirishimiz mumkin:

cd ../..
git add .
git commit -m "Add deploy for gitlab-runner"

Omborni bloklash uchun quyidagi amallarni bajaring:

git crypt lock

va darhol barcha shifrlangan fayllar ikkilik narsaga aylanadi, ularni o'qish mumkin bo'lmaydi.
Repozitoriy shifrini ochish uchun quyidagilarni bajaring:

git crypt unlock

8. Asboblar qutisi tasvirini yarating

Asboblar qutisi tasviri - bu loyihamizni joylashtirish uchun foydalanadigan barcha vositalarga ega tasvir. U Gitlab yuguruvchisi tomonidan odatiy joylashtirish vazifalarini bajarish uchun ishlatiladi.

Bu erda hamma narsa oddiy, keling, yangisini yarataylik dockerfiles/toolbox/Dockerfile quyidagi tarkib bilan:

FROM alpine:3.11

RUN apk add --no-cache git git-crypt

RUN QBEC_VER=0.10.3 
 && wget -O- https://github.com/splunk/qbec/releases/download/v${QBEC_VER}/qbec-linux-amd64.tar.gz 
     | tar -C /tmp -xzf - 
 && mv /tmp/qbec /tmp/jsonnet-qbec /usr/local/bin/

RUN KUBECTL_VER=1.17.0 
 && wget -O /usr/local/bin/kubectl 
      https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/linux/amd64/kubectl 
 && chmod +x /usr/local/bin/kubectl

RUN HELM_VER=3.0.2 
 && wget -O- https://get.helm.sh/helm-v${HELM_VER}-linux-amd64.tar.gz 
     | tar -C /tmp -zxf - 
 && mv /tmp/linux-amd64/helm /usr/local/bin/helm

Ko'rib turganingizdek, ushbu rasmda biz ilovamizni joylashtirishda foydalangan barcha yordamchi dasturlarni o'rnatamiz. Bizga bu yerda kerak emas ekan kubectl, lekin siz quvur liniyasini sozlash bosqichida u bilan o'ynashni xohlashingiz mumkin.

Shuningdek, Kubernetes bilan aloqa o'rnatish va unga o'rnatish uchun biz gitlab-runner tomonidan yaratilgan pods uchun rolni sozlashimiz kerak.

Buning uchun gitlab-runner bilan katalogga o'tamiz:

cd deploy/gitlab-runner

va yangi komponent qo'shing komponentlar/rbac.jsonnet:

local env = {
  name: std.extVar('qbec.io/env'),
  namespace: std.extVar('qbec.io/defaultNs'),
};
local p = import '../params.libsonnet';
local params = p.components.rbac;

[
  {
    apiVersion: 'v1',
    kind: 'ServiceAccount',
    metadata: {
      labels: {
        app: params.name,
      },
      name: params.name,
    },
  },
  {
    apiVersion: 'rbac.authorization.k8s.io/v1',
    kind: 'Role',
    metadata: {
      labels: {
        app: params.name,
      },
      name: params.name,
    },
    rules: [
      {
        apiGroups: [
          '*',
        ],
        resources: [
          '*',
        ],
        verbs: [
          '*',
        ],
      },
    ],
  },
  {
    apiVersion: 'rbac.authorization.k8s.io/v1',
    kind: 'RoleBinding',
    metadata: {
      labels: {
        app: params.name,
      },
      name: params.name,
    },
    roleRef: {
      apiGroup: 'rbac.authorization.k8s.io',
      kind: 'Role',
      name: params.name,
    },
    subjects: [
      {
        kind: 'ServiceAccount',
        name: params.name,
        namespace: env.namespace,
      },
    ],
  },
]

Shuningdek, biz yangi parametrlarni tasvirlab beramiz muhitlar/base.libsonnet, endi u quyidagicha ko'rinadi:

local secrets = import '../secrets/base.libsonnet';

{
  components: {
    gitlabRunner: {
      name: 'gitlab-runner',
      values: {
        gitlabUrl: 'https://gitlab.com/',
        rbac: {
          create: true,
        },
        runnerRegistrationToken: secrets.runnerRegistrationToken,
        runners: {
          serviceAccountName: $.components.rbac.name,
          image: 'registry.gitlab.com/kvaps/docs.example.org/toolbox:v0.0.1',
        },
      },
    },
    rbac: {
      name: 'gitlab-runner-deploy',
    },
  },
}

E'tibor bering $.components.rbac.name ga tegishli ism komponent uchun rbac

Keling, nima o'zgarganini tekshiramiz:

qbec diff default

va o'zgartirishlarimizni Kubernetesga qo'llang:

qbec apply default

Shuningdek, git-ga o'zgartirishlarimizni kiritishni unutmang:

cd ../..
git add dockerfiles/toolbox
git commit -m "Add Dockerfile for toolbox"
git add deploy/gitlab-runner
git commit -m "Configure gitlab-runner to use toolbox"

9. Bizning birinchi quvurimiz va teglar bo'yicha tasvirlarni yig'ish

Loyihaning ildizida biz yaratamiz .gitlab-ci.yml quyidagi tarkib bilan:

.build_docker_image:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug-v0.15.0
    entrypoint: [""]
  before_script:
    - echo "{"auths":{"$CI_REGISTRY":{"username":"$CI_REGISTRY_USER","password":"$CI_REGISTRY_PASSWORD"}}}" > /kaniko/.docker/config.json

build_toolbox:
  extends: .build_docker_image
  script:
    - /kaniko/executor --cache --context $CI_PROJECT_DIR/dockerfiles/toolbox --dockerfile $CI_PROJECT_DIR/dockerfiles/toolbox/Dockerfile --destination $CI_REGISTRY_IMAGE/toolbox:$CI_COMMIT_TAG
  only:
    refs:
      - tags

build_website:
  extends: .build_docker_image
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  script:
    - /kaniko/executor --cache --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/dockerfiles/website/Dockerfile --destination $CI_REGISTRY_IMAGE/website:$CI_COMMIT_TAG
  only:
    refs:
      - tags

E'tibor bering, biz foydalanamiz GIT_SUBMODULE_STRATEGY: normal bajarishdan oldin submodullarni aniq ishga tushirishingiz kerak bo'lgan ishlar uchun.

O'zgarishlarimizni amalga oshirishni unutmang:

git add .gitlab-ci.yml
git commit -m "Automate docker build"

O'ylaymanki, biz buni ishonch bilan versiya deb atashimiz mumkin v0.0.1 va teg qo'shing:

git tag v0.0.1

Biz yangi versiyani chiqarishimiz kerak bo'lganda teglar qo'shamiz. Docker rasmlaridagi teglar Git teglariga bog'lanadi. Yangi teg bilan har bir surish ushbu teg bilan tasvirlar tuzilishini ishga tushiradi.

Ijro eting git push - teglar, va keling, birinchi quvurimizni ko'rib chiqaylik:

Birinchi quvur liniyasining skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Teglar bo'yicha yig'ish docker tasvirlarini yaratish uchun mos, lekin Kubernetes-ga ilovani joylashtirish uchun mos emasligiga e'tiboringizni qaratish lozim. Eski topshiriqlarga yangi teglar tayinlanishi mumkinligi sababli, bu holda ular uchun quvur liniyasini ishga tushirish eski versiyani o'rnatishga olib keladi.

Ushbu muammoni hal qilish uchun odatda docker tasvirlarining tuzilishi teglar bilan bog'lanadi va dasturni filialga joylashtirish. usta, to'plangan tasvirlarning qaysi versiyalarida qattiq kodlangan. Bu yerda siz orqaga qaytarishni oddiy qaytarish bilan boshlashingiz mumkin usta-filiallar.

10. Joylashtirishni avtomatlashtirish

Gitlab-runner bizning sirlarimizni ochishi uchun biz ombor kalitini eksport qilishimiz va uni CI muhit o'zgaruvchilarimizga qo'shishimiz kerak:

git crypt export-key /tmp/docs-repo.key
base64 -w0 /tmp/docs-repo.key; echo

Olingan qatorni Gitlab-da saqlaymiz; buning uchun loyiha sozlamalarimizga o'tamiz:
Sozlamalar -> CI / CD -> O'zgaruvchilar

Va keling, yangi o'zgaruvchi yarataylik:

Shrift
kalit
qiymati
himoyalangan
niqobli
Tortib

File
GITCRYPT_KEY
<your string>
true (mashg'ulot paytida siz mumkin false)
true
All environments

Qo'shilgan o'zgaruvchining skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Endi bizni yangilaymiz .gitlab-ci.yml unga qo'shish:

.deploy_qbec_app:
  stage: deploy
  only:
    refs:
      - master

deploy_gitlab_runner:
  extends: .deploy_qbec_app
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  before_script:
    - base64 -d "$GITCRYPT_KEY" | git-crypt unlock -
  script:
    - qbec apply default --root deploy/gitlab-runner --force:k8s-context __incluster__ --wait --yes

deploy_website:
  extends: .deploy_qbec_app
  script:
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes

Bu erda biz qbec uchun bir nechta yangi variantlarni yoqdik:

  • --root some/app — muayyan ilovaning katalogini aniqlash imkonini beradi
  • --force:k8s-kontekst __incluster__ - bu sehrli o'zgaruvchi bo'lib, joylashtirish gtilab-runner ishlaydigan bir xil klasterda sodir bo'lishini aytadi. Bu zarur, chunki aks holda qbec kubekonfigingizda mos Kubernetes serverini topishga harakat qiladi.
  • --Kutmoq — qbec-ni u yaratgan resurslar Tayyor holatga o'tguncha kutishga majbur qiladi va shundan keyingina muvaffaqiyatli chiqish kodi bilan chiqing.
  • -ha - shunchaki interaktiv qobiqni o'chiradi Ishonchingiz komilmi? joylashtirilganda.

O'zgarishlarimizni amalga oshirishni unutmang:

git add .gitlab-ci.yml
git commit -m "Automate deploy"

Va keyin git surish ilovalarimiz qanday joylashtirilganini ko'ramiz:

Ikkinchi quvur liniyasining skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

11. Magistrga surishda artefaktlar va yig'ish

Odatda, yuqorida tavsiflangan qadamlar deyarli har qanday mikroservisni yaratish va etkazib berish uchun etarli, ammo biz har safar saytni yangilashimiz kerak bo'lganda teg qo'shishni xohlamaymiz. Shuning uchun, biz yanada dinamik marshrutni tanlaymiz va asosiy filialda dayjestni joylashtirishni o'rnatamiz.

Fikr oddiy: endi bizning suratimiz Veb-sayt har safar kirganingizda qayta quriladi usta, va keyin avtomatik ravishda Kubernetes-ga o'rnating.

Keling, ushbu ikkita ish joyini yangilaymiz .gitlab-ci.yml:

build_website:
  extends: .build_docker_image
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  script:
    - mkdir -p $CI_PROJECT_DIR/artifacts
    - /kaniko/executor --cache --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/dockerfiles/website/Dockerfile --destination $CI_REGISTRY_IMAGE/website:$CI_COMMIT_REF_NAME --digest-file $CI_PROJECT_DIR/artifacts/website.digest
  artifacts:
    paths:
      - artifacts/
  only:
    refs:
      - master
      - tags

deploy_website:
  extends: .deploy_qbec_app
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST"

Iltimos, biz mavzu qo'shdik usta к ref ish o'rinlari uchun build_website va biz hozir foydalanamiz $CI_COMMIT_REF_NAME o'rniga $CI_COMMIT_TAG, ya'ni biz Git-dagi teglardan uzildik va endi biz quvur liniyasini ishga tushirgan commit filiali nomi bilan rasmni suramiz. Shuni ta'kidlash kerakki, bu teglar bilan ham ishlaydi, bu bizga docker-registrda ma'lum bir versiyaga ega saytning oniy rasmlarini saqlashga imkon beradi.

Saytning yangi versiyasi uchun docker tegining nomi o'zgarmas bo'lishi mumkin bo'lsa, biz hali ham Kubernetes-dagi o'zgarishlarni tasvirlashimiz kerak, aks holda u dasturni yangi rasmdan qayta joylashtirmaydi, chunki u rasmda hech qanday o'zgarishlarni sezmaydi. joylashtirish manifestidir.

Variant —vm:ext-str digest=”$DIGEST” qbec uchun - jsonnet ga tashqi o'zgaruvchini o'tkazish imkonini beradi. Biz ilovamizning har bir chiqarilishi bilan uni klasterda qayta joylashtirishni xohlaymiz. Biz endi o'zgarmas bo'lishi mumkin bo'lgan teg nomidan foydalana olmaymiz, chunki biz tasvirning ma'lum bir versiyasiga bog'lanishimiz va u o'zgarganda joylashtirishni ishga tushirishimiz kerak.

Bu erda bizga Kanikoning dayjest tasvirini faylga saqlash qobiliyati yordam beradi (variant --digest-fayl)
Keyin biz ushbu faylni uzatamiz va uni joylashtirish vaqtida o'qiymiz.

Biz uchun parametrlarni yangilaymiz deploy/website/environments/base.libsonnet bu endi shunday ko'rinadi:

{
  components: {
    website: {
      name: 'example-docs',
      image: 'registry.gitlab.com/kvaps/docs.example.org/website@' + std.extVar('digest'),
      replicas: 1,
      containerPort: 80,
      servicePort: 80,
      nodeSelector: {},
      tolerations: [],
      ingressClass: 'nginx',
      domain: 'docs.example.org',
    },
  },
}

Bajarildi, endi har qanday majburiyat qabul qilinadi usta uchun docker tasvirini yaratishni ishga tushiradi Veb-sayt, va keyin uni Kubernetes-ga joylashtiring.

O'zgarishlarimizni amalga oshirishni unutmang:

git add .
git commit -m "Configure dynamic build"

Keyinroq tekshiramiz git surish biz shunga o'xshash narsani ko'rishimiz kerak:

Magistr uchun quvur liniyasining skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Aslida, biz har bir surishda gitlab-runner-ni qayta joylashtirishimiz shart emas, agar uning konfiguratsiyasida hech narsa o'zgarmasa, keling, uni tuzatamiz. .gitlab-ci.yml:

deploy_gitlab_runner:
  extends: .deploy_qbec_app
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  before_script:
    - base64 -d "$GITCRYPT_KEY" | git-crypt unlock -
  script:
    - qbec apply default --root deploy/gitlab-runner --force:k8s-context __incluster__ --wait --yes
  only:
    changes:
      - deploy/gitlab-runner/**/*

o'zgarishlar dagi oʻzgarishlarni kuzatish imkonini beradi deploy/gitlab-runner/ va agar mavjud bo'lsa, bizning ishimizni ishga tushiradi

O'zgarishlarimizni amalga oshirishni unutmang:

git add .gitlab-ci.yml
git commit -m "Reduce gitlab-runner deploy"

git surish, shunday yaxshiroq:

Yangilangan quvur liniyasining skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

12. Dinamik muhitlar

Quvurimizni dinamik muhit bilan diversifikatsiya qilish vaqti keldi.

Birinchidan, keling, ishni yangilaymiz build_website bizning .gitlab-ci.yml, undan blokni olib tashlash faqat, bu Gitlabni har qanday filialga har qanday majburiyatda uni ishga tushirishga majbur qiladi:

build_website:
  extends: .build_docker_image
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  script:
    - mkdir -p $CI_PROJECT_DIR/artifacts
    - /kaniko/executor --cache --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/dockerfiles/website/Dockerfile --destination $CI_REGISTRY_IMAGE/website:$CI_COMMIT_REF_NAME --digest-file $CI_PROJECT_DIR/artifacts/website.digest
  artifacts:
    paths:
      - artifacts/

Keyin ishni yangilang deploy_website, u erda blok qo'shing atrof-muhit:

deploy_website:
  extends: .deploy_qbec_app
  environment:
    name: prod
    url: https://docs.example.org
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST"

Bu Gitlabga ishni bog'lash imkonini beradi prod muhit va unga to'g'ri havolani ko'rsating.

Endi yana ikkita ishni qo'shamiz:

deploy_website:
  extends: .deploy_qbec_app
  environment:
    name: prod
    url: https://docs.example.org
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST"

deploy_review:
  extends: .deploy_qbec_app
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: http://$CI_ENVIRONMENT_SLUG.docs.example.org
    on_stop: stop_review
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply review --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST" --vm:ext-str subdomain="$CI_ENVIRONMENT_SLUG" --app-tag "$CI_ENVIRONMENT_SLUG"
  only:
    refs:
    - branches
  except:
    refs:
      - master

stop_review:
  extends: .deploy_qbec_app
  environment:
    name: review/$CI_COMMIT_REF_NAME
    action: stop
  stage: deploy
  before_script:
    - git clone "$CI_REPOSITORY_URL" master
    - cd master
  script:
    - qbec delete review --root deploy/website --force:k8s-context __incluster__ --yes --vm:ext-str digest="$DIGEST" --vm:ext-str subdomain="$CI_ENVIRONMENT_SLUG" --app-tag "$CI_ENVIRONMENT_SLUG"
  variables:
    GIT_STRATEGY: none
  only:
    refs:
    - branches
  except:
    refs:
      - master
  when: manual

Ular masterdan tashqari istalgan filiallarga bosilgandan so'ng ishga tushiriladi va saytning oldindan ko'rish versiyasini joylashtiradi.

Biz qbec uchun yangi variantni ko'rmoqdamiz: --app-teg — bu sizga ilovaning oʻrnatilgan versiyalarini belgilash va faqat shu teg ichida ishlash imkonini beradi; Kubernetesda resurslarni yaratish va yoʻq qilishda qbec faqat ular bilan ishlaydi.
Shunday qilib, biz har bir ko'rib chiqish uchun alohida muhit yarata olmaymiz, shunchaki bir xil muhitdan qayta foydalanamiz.

Bu erda biz ham foydalanamiz qbec murojaat ko'rib chiqisho'rniga qbec sukut bo'yicha amal qiladi - Aynan o'sha paytda biz muhitimizdagi farqlarni tasvirlashga harakat qilamiz (ko'rib chiqish va sukut bo'yicha):

Qo'shaylik sharh ichidagi muhit deploy/website/qbec.yaml

spec:
  environments:
    review:
      defaultNamespace: docs
      server: https://kubernetes.example.org:8443

Keyin biz buni e'lon qilamiz deploy/website/params.libsonnet:

local env = std.extVar('qbec.io/env');
local paramsMap = {
  _: import './environments/base.libsonnet',
  default: import './environments/default.libsonnet',
  review: import './environments/review.libsonnet',
};

if std.objectHas(paramsMap, env) then paramsMap[env] else error 'environment ' + env + ' not defined in ' + std.thisFile

Va buning uchun maxsus parametrlarni yozing deploy/website/environments/review.libsonnet:

// this file has the param overrides for the default environment
local base = import './base.libsonnet';
local slug = std.extVar('qbec.io/tag');
local subdomain = std.extVar('subdomain');

base {
  components+: {
    website+: {
      name: 'example-docs-' + slug,
      domain: subdomain + '.docs.example.org',
    },
  },
}

Keling, jobu ni ham batafsil ko'rib chiqaylik to'xtatish_ko'rib chiqish, u filial o'chirilganda ishga tushadi va gitlab uni tekshirishga urinmasligi uchun ishlatiladi GIT_STRATEGY: yo'q, keyinchalik biz klonlashtiramiz usta-filial va u orqali sharhni o'chirish.
Bu biroz chalkash, lekin men hali chiroyliroq yo'l topmadim.
Har bir sharhni har doim butunlay buzib tashlash mumkin bo'lgan mehmonxona nomlari maydoniga joylashtirish muqobil variant bo'ladi.

O'zgarishlarimizni amalga oshirishni unutmang:

git add .
git commit -m "Enable automatic review"

git surish, git checkout -b testi, git push kelib chiqishi testi, tekshiring:

Gitlab-da yaratilgan muhitlarning skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Hammasi ishlayaptimi? - ajoyib, test bo'limimizni o'chirib tashlang: git to'lov ustasi, git push kelib chiqishi: test, biz muhitni o'chirish ishlari xatosiz ishlaganligini tekshiramiz.

Bu erda men darhol aniqlik kiritmoqchimanki, loyihadagi har qanday ishlab chiquvchi filiallarni yaratishi mumkin, u ham o'zgarishi mumkin .gitlab-ci.yml fayl va maxfiy o'zgaruvchilarga kirish.
Shuning uchun ularni faqat himoyalangan novdalar uchun ishlatishga ruxsat berish tavsiya etiladi, masalan usta, yoki har bir muhit uchun alohida oʻzgaruvchilar toʻplamini yarating.

13. Ilovalarni ko'rib chiqing

Ilovalarni ko'rib chiqish Bu GitLab xususiyati boʻlib, u oʻrnatilgan muhitda uni tezda koʻrish uchun ombordagi har bir faylga tugma qoʻshish imkonini beradi.

Ushbu tugmalar paydo bo'lishi uchun siz fayl yaratishingiz kerak .gitlab/route-map.yml va undagi barcha yo'l o'zgarishlarini tavsiflang; bizning holatlarimizda bu juda oddiy bo'ladi:

# Indices
- source: /content/(.+?)_index.(md|html)/ 
  public: '1'

# Pages
- source: /content/(.+?).(md|html)/ 
  public: '1/'

O'zgarishlarimizni amalga oshirishni unutmang:

git add .gitlab/
git commit -m "Enable review apps"

git surish, va tekshiring:

Ilovani ko'rib chiqish tugmasi skrinshoti

Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Ish tugadi!

Loyiha manbalari:

E'tiboringiz uchun rahmat, sizga yoqdi degan umiddaman Kubernetes-da joylashtirishni yaratish va avtomatlashtirish uchun yangi vositalar sinab ko'rilmoqda

Manba: www.habr.com

a Izoh qo'shish