Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Салам! Жакында, көптөгөн сонун автоматташтыруу куралдары Docker сүрөттөрүн куруу үчүн да, Kubernetesке жайылтуу үчүн да чыгарылды. Бул жагынан алганда, мен GitLab менен ойноп, анын мүмкүнчүлүктөрүн кылдат изилдеп жана, албетте, куурду орнотууну чечтим.

Бул иш веб-сайттан шыктандырылган kubernetes.io, андан түзүлөт булак коддору автоматтык түрдө жана жөнөтүлгөн ар бир бассейн суроосу үчүн робот автоматтык түрдө сиздин өзгөртүүлөрүңүз менен сайттын алдын ала көрүү версиясын жаратат жана көрүү үчүн шилтеме берет.

Мен ушундай процессти нөлдөн баштап түзүүгө аракет кылдым, бирок толугу менен Gitlab CI жана Kubernetesке тиркемелерди жайгаштыруу үчүн колдонуп жүргөн акысыз куралдарга курулган. Бүгүн мен акыры алар жөнүндө көбүрөөк айтып берем.

Макалада төмөнкү куралдар талкууланат:
Уго, qbec, kaniko, git-crypt и GitLab CI динамикалык чөйрөлөрдү түзүү менен.

Мазмун

  1. Уго менен таанышыңыз
  2. Докер файлын даярдоо
  3. Канико менен таанышуу
  4. qbec менен таанышуу
  5. Gitlab-жүргүчтү Kubernetes-аткаруучу менен сынап көрүү
  6. Helm диаграммаларын qbec менен жайылтуу
  7. git-crypt менен таанышуу
  8. Куралдар кутусунун сүрөтүн түзүү
  9. Биздин биринчи түтүк жана тегдер боюнча сүрөттөрдү чогултуу
  10. Жайгаштырууну автоматташтыруу
  11. Артефакттар жана монтаждоо мастерге түртүп жатканда
  12. Динамикалык чөйрөлөр
  13. Колдонмолорду карап чыгуу

1. Гюго менен таанышуу

Биздин долбоордун мисалы катары, биз Hugo боюнча курулган документтерди жарыялоо сайтын түзүүгө аракет кылабыз. Hugo статикалык мазмун генератору болуп саналат.

Статикалык генераторлор менен тааныш эмес адамдар үчүн, мен алар жөнүндө бир аз көбүрөөк айтып берем. Кадимки веб-сайт кыймылдаткычтарынан айырмаланып, маалымат базасы жана кээ бир PHP, алар колдонуучу суранганда, барактарды тез арада жаратат, статикалык генераторлор бир аз башкача иштелип чыккан. Алар булактарды, адатта Markdown белгилөөлөрүндөгү файлдардын топтомун жана тема шаблондорун алып, анан аларды толугу менен даяр веб-сайтка компиляциялоого мүмкүндүк берет.

Башкача айтканда, натыйжада сиз каталогдун түзүмүн жана түзүлгөн HTML файлдарынын топтомун аласыз, аларды каалаган арзан хостингге жүктөй аласыз жана жумушчу веб-сайт аласыз.

Сиз Hugo-ну жергиликтүү түрдө орнотуп, аны сынап көрүңүз:

Жаңы сайтты баштоо:

hugo new site docs.example.org

Жана ошол эле учурда git репозиторий:

cd docs.example.org
git init

Азырынча биздин сайт таза жана анда бир нерсе пайда болушу үчүн биринчиден теманы туташтырышыбыз керек; тема бул жөн гана калыптардын жыйындысы жана биздин сайт түзүлө турган көрсөтүлгөн эрежелер.

Биз колдоно турган тема үчүн үйрөнүү, менин оюмча, документация сайтына эң ылайыктуу.

Мен биздин долбоордун репозиторийинде тема файлдарын сактоонун кереги жок экендигине өзгөчө көңүл бургум келет; анын ордуна биз аны жөн гана колдонуу менен туташтыра алабыз. git субмодуль:

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

Ошентип, биздин репозиторийде биздин долбоорго түздөн-түз тиешелүү файлдар гана камтылат жана байланышкан тема белгилүү бир репозиторийге шилтеме жана андагы милдеттенме катары кала берет, башкача айтканда, аны ар дайым баштапкы булактан тартып алса болот жана коркпойт. туура келбеген өзгөрүүлөр.

Конфигурацияны оңдойлу config.toml:

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

Бул этапта сиз чуркай аласыз:

hugo server

Жана адрес боюнча http://localhost:1313/ биздин жаңы түзүлгөн веб-сайтыбызды текшериңиз, каталогго киргизилген бардык өзгөртүүлөр браузерде ачык баракты автоматтык түрдө жаңыртыңыз, абдан ыңгайлуу!

ичинде мукаба баракты түзүүгө аракет кылалы content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Жаңы түзүлгөн барактын скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Сайт түзүү үчүн жөн гана иштетиңиз:

hugo

Каталог мазмуну коомдук/ жана сиздин веб-сайтыңыз болот.
Ооба, демек, дароо эле кошуп коёлу .gitignore:

echo /public > .gitignore

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

2. Докер файлын даярдоо

Биздин репозиторийдин структурасын аныктоого убакыт жетти. Мен, адатта, бир нерсени колдоном:

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

  • докер файлдары/ — Докер файлдары бар каталогдорду жана биздин Docker сүрөттөрүн курууга керектүү нерселердин бардыгын камтыйт.
  • жайылтуу/ — биздин тиркемелерди Kubernetesке жайгаштыруу үчүн каталогдорду камтыйт

Ошентип, биз жол боюнча биринчи Dockerfile түзөбүз dockerfiles/website/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" ]

Көрүнүп тургандай, Dockerfile экиден турат FROM, бул мүмкүнчүлүк деп аталат көп этаптуу куруу жана акыркы докер сүрөтүнөн керексиз нерселердин баарын алып салууга мүмкүндүк берет.
Ошентип, акыркы сүрөт гана камтыйт darkhttpd (жеңил HTTP сервер) жана коомдук/ — биздин статикалык түрдө түзүлгөн веб-сайттын мазмуну.

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

3. Канико менен таанышуу

Докердин сүрөтүн куруучу катары мен колдонууну чечтим kaniko, анткени анын иштеши докер демонун талап кылбайт жана куруунун өзү каалаган машинада жүргүзүлүшү мүмкүн жана кэш түздөн-түз реестрде сакталышы мүмкүн, ошону менен толук кандуу туруктуу сактагычка ээ болуу зарылдыгы жок кылынат.

Сүрөттү түзүү үчүн, жөн гана контейнерди иштетиңиз канико аткаруучу жана ага учурдагы куруу контекстин өткөрүп бериңиз; муну докер аркылуу жергиликтүү түрдө да жасоого болот:

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

кайда registry.gitlab.com/kvaps/docs.example.org/website — докер сүрөтүңүздүн аты; кургандан кийин ал автоматтык түрдө докер реестрине киргизилет.

параметр --кэш Докер реестриндеги катмарларды кэш кылууга мүмкүндүк берет; берилген мисал үчүн алар сакталат registry.gitlab.com/kvaps/docs.example.org/website/cache, бирок сиз параметрди колдонуп башка жолду белгилей аласыз --cache-repo.

Докер реестринин скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

4. Qbec тили менен таанышуу

Qbec колдонмо манифесттериңизди декларативдик түрдө сүрөттөп, аларды Kubernetesке жайгаштырууга мүмкүндүк берген жайылтуу куралы. Jsonnetти негизги синтаксис катары колдонуу бир нече чөйрөдөгү айырмачылыктардын сүрөттөлүшүн абдан жөнөкөйлөтүүгө мүмкүндүк берет, ошондой эле коддун кайталанышын дээрлик толугу менен жок кылат.

Бул, өзгөчө, сиз тиркемени ар кандай параметрлери бар бир нече кластерлерге жайгаштырышыңыз керек болгон жана аларды Gitте декларативдик түрдө сүрөттөгүңүз келген учурларда туура болушу мүмкүн.

Qbec ошондой эле Helm диаграммаларын аларга керектүү параметрлерди берүү менен көрсөтүүгө жана андан кийин аларды кадимки манифесттер сыяктуу иштетүүгө мүмкүндүк берет, анын ичинде аларга ар кандай мутацияларды колдоно аласыз, жана бул, өз кезегинде, сизге керектөөдөн арылууга мүмкүндүк берет. ChartMuseum колдонуңуз. Башкача айтканда, сиз диаграммаларды түздөн-түз gitтен, алар таандык болгон жерде сактап, көрсөтө аласыз.

Жогоруда айткандай, биз бардык жайылтууларды каталогдо сактайбыз жайылтуу/:

mkdir deploy
cd deploy

Биринчи колдонмобузду инициализация кылалы:

qbec init website
cd website

Эми биздин колдонмонун структурасы төмөнкүдөй көрүнөт:

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

файлды карап көрөлү qbec.yaml:

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

Бул жерде биз биринчи кезекте кызыкдарбыз өзгөчө.чөйрөлөр, qbec мурунтан эле биз үчүн демейки чөйрөнү түзүп, сервердин дарегин, ошондой эле учурдагы kubeconfigден ат мейкиндигин алган.
Азыр жайгаштыруу учурунда жарыяланбаган чөйрөдө, qbec ар дайым көрсөтүлгөн Kubernetes кластерине жана көрсөтүлгөн аттар мейкиндигине гана жайылтылат, башкача айтканда, жайылтууну аткаруу үчүн мындан ары контексттер менен аттар мейкиндигине которулушуңуз керек эмес.
Зарыл болсо, бул файлдагы орнотууларды ар дайым жаңырта аласыз.

Бардык чөйрөлөрүңүз сүрөттөлөт qbec.yaml, жана файлда params.libsonnet, алар үчүн параметрлерди кайдан алуу керектиги жазылган.

Андан кийин биз эки каталогду көрөбүз:

  • компоненттери / — биздин тиркеме үчүн бардык манифесттер бул жерде сакталат; аларды jsonnet жана кадимки yaml файлдарында сүрөттөсө болот
  • чөйрөлөр/ — бул жерде биз чөйрөлөрүбүз үчүн бардык өзгөрмөлөрдү (параметрлерди) сүрөттөйбүз.

Демейки боюнча бизде эки файл бар:

  • environments/base.libsonnet - ал бардык чөйрөлөр үчүн жалпы параметрлерди камтыйт
  • environments/default.libsonnet — айлана-чөйрө үчүн жокко чыгарылган параметрлерди камтыйт жарыяланбаган

ачалы environments/base.libsonnet жана ал жерде биздин биринчи компонент үчүн параметрлерди кошуу:

{
  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',
    },
  },
}

Келгиле, биринчи компонентибизди да түзөлү components/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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

Бул файлда биз бир эле учурда үч Kubernetes объектисин сүрөттөп бердик, булар: жайылтуу, кызмат и өтүшү. Кааласак, аларды ар кандай компоненттерге салмакпыз, бирок бул этапта бизге бирөө жетиштүү болот.

синтаксиси jsonnet кадимки jsonга абдан окшош, негизи, кадимки json мурунтан эле жарактуу jsonnet, андыктан алгач сиз сыяктуу онлайн кызматтарды колдонуу оңой болушу мүмкүн. yaml2json кадимки ямлды jsonга айландыруу үчүн, же эгерде сиздин компоненттериңизде эч кандай өзгөрмөлөр жок болсо, анда аларды кадимки ямл түрүндө сүрөттөсө болот.

Менен иштегенде jsonnet Мен сиздин редакторуңузга плагин орнотууну сунуштайм

Мисалы, vim үчүн плагин бар vim-jsonnet, ал синтаксисти бөлүп көрсөтүүнү күйгүзөт жана автоматтык түрдө аткарылат jsonnet fmt сактаган сайын (jsonnet орнотулушун талап кылат).

Баары даяр, азыр биз жайылтууга киришсек болот:

Бизде эмне бар экенин көрүү үчүн, чуркайлы:

qbec show default

Чыгуу учурунда сиз демейки кластерге колдонула турган көрсөтүлгөн yaml манифесттерин көрөсүз.

Жакшы, азыр колдонуңуз:

qbec apply default

Чыгуу учурунда сиз ар дайым кластериңизде эмне жасалаарын көрөсүз, qbec терүү менен өзгөртүүлөргө макул болушуңузду суранат. y ниетиңизди ырастай аласыз.

Биздин колдонмо даяр жана жайгаштырылган!

Өзгөртүүлөрдү киргизсеңиз, ар дайым жасай аласыз:

qbec diff default

бул өзгөртүүлөр учурдагы жайылтууга кандай таасир этээрин көрүү үчүн

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

5. Kubernetes-аткаруучу менен Gitlab-чуркоочу аракет кылуу

Акыркы убакка чейин мен кадимки эле колдончумун gitlab-runner кабык же докер-аткаруучу менен алдын ала даярдалган машинада (LXC контейнер). Башында, биздин gitlab'да глобалдуу түрдө аныкталган бир нече ушундай жөө күлүктөр бар болчу. Алар бардык долбоорлор үчүн докер сүрөттөрүн чогултушту.

Бирок практика көрсөткөндөй, бул параметр практикалык жактан да, коопсуздук жагынан да эң идеалдуу эмес. Ар бир долбоор үчүн, жада калса ар бир чөйрө үчүн өзүнчө жөө күлүктөрдү жайгаштыруу алда канча жакшыраак жана идеологиялык жактан туурараак.

Бактыга жараша, бул эч кандай көйгөй эмес, анткени азыр биз жайгаштырабыз gitlab-runner түздөн-түз Kubernetes биздин долбоордун бир бөлүгү катары.

Gitlab Gitlab-Runnerди Кубернетеске жайылтуу үчүн даяр руль диаграммасын берет. Демек, сиз эмне кылышыңыз керек болсо, ошонун бардыгын билүү каттоо белгиси биздин долбоор үчүн Орнотуулар -> CI / CD -> Runners жана аны рулга бериңиз:

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

мында:

  • https://gitlab.com — Gitlab сервериңиздин дареги.
  • yga8y-jdCusVDn_t4Wxc — сиздин долбооруңуз үчүн каттоо белгиси.
  • rbac.create=true — күлүккө kubernetes-executor аркылуу биздин тапшырмаларды аткаруу үчүн поддондорду түзө алуу үчүн керектүү өлчөмдөгү артыкчылыктарды берет.

Эгер баары туура аткарылса, бөлүмдө катталган жөө күлүктү көрүшүңүз керек орун, долбоордун жөндөөлөрүңүздө.

Кошулган күлүктүн скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Ушунчалык жөнөкөйбү? - Ооба, бул жөнөкөй! Жөө күлүктөрдү кол менен каттоодон башка эч кандай кыйынчылык болбойт, мындан ары күлүктөр автоматтык түрдө түзүлүп, жок кылынат.

6. QBEC менен Helm диаграммаларын жайылтыңыз

Биз карап чыгууну чечтик gitlab-runner биздин долбоордун бир бөлүгү, аны Git репозиторийибизде сүрөттөөгө убакыт келди.

Биз аны өзүнчө компонент катары сүрөттөсө болот сайты, бирок келечекте биз ар кандай нускаларды жайылтууну пландап жатабыз сайты абдан көп, айырмаланып gitlab-runner, ал ар бир Kubernetes кластерине бир жолу гана орнотулат. Ошентип, ал үчүн өзүнчө колдонмону инициализациялайлы:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Бул жолу биз Kubernetes объекттерин кол менен сүрөттөбөйбүз, бирок даяр Helm диаграммасын алабыз. Qbecтин артыкчылыктарынын бири - Гит репозиторийинен Helm диаграммаларын түз көрсөтүү мүмкүнчүлүгү.

Келгиле, аны git субмодулунун жардамы менен туташтыралы:

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

Азыр каталог vendor/gitlab-runner Бизде gitlab-runner үчүн диаграммасы бар репозиторий бар.

Ушундай эле жол менен сиз башка репозиторийлерди, мисалы, бүт репозиторийди расмий диаграммалар менен туташтыра аласыз. https://github.com/helm/charts

Компонентти сүрөттөп көрөлү components/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,
  }
)

Биринчи аргумент expandHelmTemplate анда биз диаграммага жолду өтөбүз параметрлер.баалуулуктар, аны биз чөйрөнүн параметрлеринен алабыз, андан кийин объект келет

  • name Template - чыгаруу аталышы
  • Аталыштар мейкиндиги — аттар мейкиндиги рулга которулду
  • бул файл — учурдагы файлга жолду өткөрүүчү талап кылынган параметр
  • кенен - буйругун көрсөтөт рул шаблону диаграмманы көрсөтүүдө бардык аргументтер менен

Эми биздин компоненттин параметрлерин сүрөттөп көрөлү environments/base.libsonnet:

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

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

көңүл буруңуздар runnerRegistrationToken биз тышкы файлдан алабыз secrets/base.libsonnet, келгиле, аны түзөлү:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Келгиле, баары иштеп жатканын текшерип көрөлү:

qbec show default

баары жайында болсо, анда биз Helm аркылуу мурда орнотулган чыгарууну жок кыла алабыз:

helm uninstall gitlab-runner

жана аны ошол эле жол менен жайгаштырыңыз, бирок qbec аркылуу:

qbec apply default

7. Гит-криптке киришүү

Git-crypt репозиторийиңиз үчүн ачык шифрлөө орнотууга мүмкүндүк берүүчү курал.

Азыркы учурда, gitlab-runner үчүн каталог структурабыз төмөнкүдөй көрүнөт:

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

Бирок Гитте сырларды сактоо коопсуз эмес, туурабы? Андыктан биз аларды туура шифрлешибиз керек.

Адатта, бир өзгөрмө үчүн, бул дайыма эле мааниге ээ боло бербейт. Сиз сырларды которо аласыз qbec жана CI тутумуңуздун чөйрө өзгөрмөлөрү аркылуу.
Бирок, дагы көптөгөн сырларды камтышы мүмкүн болгон татаал долбоорлор бар экенин белгилей кетүү керек; алардын бардыгын айлана-чөйрөнүн өзгөрмөлөрү аркылуу өткөрүү өтө кыйын болот.

Анын үстүнө, бул учурда мен мындай сонун курал жөнүндө айта албайм git-crypt.

git-crypt Бул ошондой эле жашыруун сырлардын бүткүл тарыхын сактоого, ошондой эле биз Гиттин ишинде көнүп калгандай конфликттерди салыштырууга, бириктирүүгө жана чечүүгө мүмкүндүк бергендиги менен ыңгайлуу.

Орнотуудан кийин биринчи нерсе git-crypt биз репозиторийибиз үчүн ачкычтарды чыгарышыбыз керек:

git crypt init

Эгер сизде PGP ачкычы болсо, анда сиз дароо өзүңүздү бул долбоордун өнөктөшү катары кошсоңуз болот:

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

Ушундай жол менен сиз ар дайым жеке ачкычыңызды колдонуп бул репозиторийдин шифрин чече аласыз.

Эгер сизде PGP ачкычы жок болсо жана аны күтпөсөңүз, анда башка жол менен барып, долбоордун ачкычын экспорттой аласыз:

git crypt export-key /path/to/keyfile

Ошентип, экспорттолгон ар бир адам ачкыч файлы репозиторийиңизди чечмелей алат.

Биздин биринчи сырыбызды орнотууга убакыт келди.
Эсиңиздерге сала кетейин, биз дагы эле каталогдобуз deploy/gitlab-runner/, бизде каталог бар сырлар/, андагы бардык файлдарды шифрлейли, бул үчүн биз файл түзөбүз secrets/.gitattributes төмөнкү мазмун менен:

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

Мазмундан көрүнүп тургандай, бардык файлдар маскаланган * аркылуу айдалат git-crypt, көпчүлүгүнөн башкасы .gitattributes

Биз муну чуркап текшере алабыз:

git crypt status -e

Чыгуу репозиторийдеги шифрлөө иштетилген бардык файлдардын тизмеси болот

Болду, эми биз өзгөртүүлөрүбүздү коопсуз жасай алабыз:

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

Репозиторийди бөгөттөө үчүн жөн гана иштетиңиз:

git crypt lock

жана дароо бардык шифрленген файлдар бинардык нерсеге айланат, аларды окуу мүмкүн болбой калат.
Репозиторийдин шифрин чечмелөө үчүн:

git crypt unlock

8. Куралдар кутусунун сүрөтүн түзүңүз

Куралдар кутусунун сүрөтү - бул биздин долбоорду жайылтуу үчүн колдоно турган бардык куралдар менен сүрөт. Аны Gitlab жөө күлүгү типтүү жайылтуу тапшырмаларын аткаруу үчүн колдонот.

Бул жерде баары жөнөкөй, жаңысын түзөлү dockerfiles/toolbox/Dockerfile төмөнкү мазмун менен:

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

Көрүнүп тургандай, бул сүрөттө биз тиркемени жайылтуу үчүн колдонгон бардык утилиталарды орнотобуз. Бизге бул жерде кереги жок kubectl, бирок түтүктү орнотуу баскычында сиз аны менен ойногуңуз келиши мүмкүн.

Ошондой эле, Kubernetes менен байланышуу жана ага жайгаштыруу үчүн, биз gitlab-runner тарабынан түзүлгөн поддондор үчүн ролду конфигурациялашыбыз керек.

Бул үчүн, келгиле, gitlab-runner менен каталогго баралы:

cd deploy/gitlab-runner

жана жаңы компонентти кошуу components/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,
      },
    ],
  },
]

Биз ошондой эле жаңы параметрлерди сүрөттөп беребиз environments/base.libsonnet, ал азыр мындай көрүнөт:

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',
    },
  },
}

көңүл буруңуздар $.components.rbac.name билдирет ысым компоненти үчүн rbac

Эмне өзгөргөнүн текшерип көрөлү:

qbec diff default

жана биздин өзгөртүүлөрүбүздү Kubernetesке колдонуңуз:

qbec apply default

Ошондой эле, биздин өзгөртүүлөрүбүздү gitке киргизүүнү унутпаңыз:

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. Биздин биринчи түтүк жана теги боюнча сүрөттөрдү чогултуу

Долбоордун түбүндө биз түзөбүз .gitlab-ci.yml төмөнкү мазмун менен:

.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

Сураныч, биз колдонобуз GIT_SUBMODULE_STRATEGY: нормалдуу аткаруудан мурун субмодулдарды ачык инициализациялоо керек болгон жумуштар үчүн.

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

Мен муну коопсуз версия деп атасак болот деп ойлойм v0.0.1 жана тег кошуу:

git tag v0.0.1

Жаңы версияны чыгаруу керек болгондо тегдерди кошобуз. Docker сүрөттөрүндөгү тегдер Git тегдерине байланат. Жаңы тег менен ар бир түртүү бул тег менен сүрөттөрдүн түзүлүшүн инициализациялайт.

Келгиле, жасайлы git push --тегдер, жана биздин биринчи куурду карап көрөлү:

Биринчи түтүктүн скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Тегдер боюнча чогултуу докер сүрөттөрүн курууга ылайыктуу, бирок Kubernetesке тиркемени жайылтуу үчүн ылайыктуу эмес экендигине көңүлүңүздү буруп коюу керек. Жаңы тегдерди эски милдеттенмелерге ыйгаруу мүмкүн болгондуктан, бул учурда алар үчүн конвейерди инициализациялоо эски версияны жайылтууга алып келет.

Бул көйгөйдү чечүү үчүн, адатта, докердин сүрөттөрүн түзүү тегдерге жана тиркемени филиалга жайгаштыруу менен байланышкан. кожоюн, чогултулган сүрөттөрдүн кайсы версияларында катуу коддолгон. Бул жерде сиз жөнөкөй кайтаруу менен артка кайтарууну баштасаңыз болот кожоюн-филиалдар.

10. Жайгаштырууну автоматташтыруу

Gitlab-runner биздин сырларды чечмелеши үчүн, биз репозиторий ачкычын экспорттоп, аны CI чөйрө өзгөрмөлөрүбүзгө кошушубуз керек:

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

Алынган сызыкты Gitlabда сактайбыз; Бул үчүн, келгиле, долбоордун жөндөөлөрүнө өтөлү:
Орнотуулар -> CI / CD -> Өзгөрмөлөр

Жана жаңы өзгөрмө түзөлү:

түрү
ачкыч
маани
корголгон
беткапчан
масштабы

File
GITCRYPT_KEY
<your string>
true (тренинг учурунда сиз мүмкүн false)
true
All environments

Кошулган өзгөрмөнүн скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Эми жаңырталы .gitlab-ci.yml ага кошуп:

.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

Бул жерде биз qbec үчүн бир нече жаңы опцияларды иштеттик:

  • --root some/app — конкреттүү тиркеменин каталогун аныктоого мүмкүндүк берет
  • --force:k8s-контекст __incluster__ - бул сыйкырдуу өзгөрмө, анда жайылтуу gtilab-runner иштеп жаткан ошол эле кластерде болот. Бул зарыл, анткени антпесе qbec сиздин kubeconfigиңизден ылайыктуу Kubernetes серверин табууга аракет кылат
  • --күтө тур — qbecти ал түзгөн ресурстар Даяр абалына өткөнгө чейин күтүүгө жана андан кийин гана ийгиликтүү чыгуу коду менен чыгууга мажбурлайт.
  • -ооба - жөн гана интерактивдүү кабыкты өчүрөт Ишенесиңби? жайгаштырылганда.

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

Анан кийин Git Push биздин тиркемелерибиз кандайча орнотулганын көрөбүз:

Экинчи түтүктүн скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

11. Кожоюнга түртүп жатканда артефакттар жана чогултуу

Адатта, жогоруда сүрөттөлгөн кадамдар дээрлик бардык микросервисти куруу жана жеткирүү үчүн жетиштүү, бирок биз сайтты жаңырткан сайын тег кошкубуз келбейт. Ошондуктан, биз бир кыйла динамикалуу жолду тандап, башкы бутакта дайджест жайгаштырууну орнотобуз.

Идея жөнөкөй: азыр биздин образ сайты түрткөн сайын кайра курулат кожоюн, анан автоматтык түрдө Kubernetesке орнотулат.

Келгиле, бул эки жумушубузду жаңырталы .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"

Сураныч, биз жип кошконбуз кожоюн к рефер жумуш үчүн build_website жана биз азыр колдонобуз $CI_COMMIT_REF_NAME ордуна $CI_COMMIT_TAG, башкача айтканда, биз Гиттеги тегдерден бошондук жана азыр биз куурду инициализациялаган Commit бутагынын аты менен сүрөттү түртөбүз. Белгилей кетчү нерсе, бул тегдер менен да иштейт, бул бизге белгилүү бир версиясы бар сайттын сүрөттөрүн докер реестринде сактоого мүмкүндүк берет.

Сайттын жаңы версиясы үчүн докер тегинин аталышы өзгөрүүсүз калганда, биз дагы эле Kubernetesке өзгөртүүлөрдү сүрөттөшүбүз керек, антпесе ал жөн гана жаңы сүрөттөн тиркемени кайра жайгаштырбайт, анткени ал жаңы сүрөттө эч кандай өзгөрүүлөрдү байкабайт. жайылтуу манифести.

тандоо —vm:ext-str дайджест=”$DIGEST” qbec үчүн - сырткы өзгөрмөлөрдү jsonnetке өткөрүүгө мүмкүндүк берет. Колдонмобуздун ар бир чыгарылышы менен анын кластерде кайра жайгаштырылышын каалайбыз. Биз мындан ары тег атын колдоно албайбыз, ал эми өзгөрүлбөйт, анткени биз сүрөттүн белгилүү бир версиясына байланып, ал өзгөргөндө жайылтууну баштообуз керек.

Бул жерде бизге Каниконун дайджест сүрөтүн файлга сактоо жөндөмү жардам берет (вариант --digest-файл)
Андан кийин биз бул файлды өткөрүп, жайылтуу учурунда окуйбуз.

Биздин параметрлерди жаңырталы deploy/website/environments/base.libsonnet ал азыр мындай болот:

{
  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',
    },
  },
}

Бүттү, азыр кимдир бирөө киришет кожоюн үчүн докер сүрөтүнүн түзүлүшүн инициализациялайт сайты, анан аны Kubernetesке жайгаштырыңыз.

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

Кийинчерээк текшеребиз Git Push биз бул сыяктуу бир нерсени көрүшүбүз керек:

Мастер үчүн куурдун скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Негизи, биз ар бир түртүү менен gitlab-runnerди кайра жайгаштыруунун кереги жок, эгерде анын конфигурациясында эч нерсе өзгөрбөсө, анда аны оңдойлу .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/**/*

өзгөрүүлөр өзгөрүүлөрдү көзөмөлдөөгө мүмкүндүк берет deploy/gitlab-runner/ жана алар болгондо гана биздин жумушубузду козгойт

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

Git Push, бул жакшыраак:

Жаңыртылган куурдун скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

12. Динамикалык чөйрөлөр

Биздин куурду динамикалык чөйрөлөр менен диверсификациялоого убакыт келди.

Биринчиден, жумушту жаңырталы build_website биздин .gitlab-ci.yml, андан блокту алып салуу гана, бул Gitlabди кандайдыр бир филиалга ар кандай милдеттенмеде ишке киргизүүгө мажбурлайт:

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/

Андан кийин жумушту жаңыртыңыз deploy_website, ал жерге блок кошуу айлана-чөйрө:

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"

Бул Gitlabге жумушту байланыштырууга мүмкүндүк берет продукт чөйрө жана ага туура шилтемени көрсөтүү.

Эми дагы эки жумушту кошолу:

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

Алар мастерден башка бардык бутактарга түртүлгөндө ишке киргизилет жана сайттын алдын ала көрүү версиясын жайылтат.

Биз qbec үчүн жаңы вариантты көрүп жатабыз: --app-teg — бул колдонмонун орнотулган версияларын белгилөөгө жана ушул тегдин ичинде гана иштөөгө мүмкүндүк берет; Kubernetesте ресурстарды түзүп жана жок кылганда, qbec алар менен гана иштейт.
Ошентип, биз ар бир карап чыгуу үчүн өзүнчө чөйрө түзө албайбыз, бирок жөн гана бир эле нерсени кайра колдонобуз.

Бул жерде биз да колдонобуз qbec карап чыгуу, ордуна qbec демейки колдонулат - дал ушул учур, биз чөйрөлөрүбүз үчүн айырмачылыктарды сүрөттөөгө аракет кылабыз (карап чыгуу жана демейки):

кошолу кароо чөйрөсүндө deploy/website/qbec.yaml

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

Андан кийин биз аны жарыялайбыз 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

Жана ага ылайыкташтырылган параметрлерди жазыңыз 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',
    },
  },
}

Келгиле, жумушту дагы жакшыраак карап көрөлү кароону_ токтотуу, ал бутак жок кылынганда иштетилет жана gitlab аны текшерүүгө аракет кылбашы үчүн колдонулат GIT_STRATEGY: жок, кийинчерээк клондобуз кожоюн-филиал жана ал аркылуу кароону жок кылуу.
Бул бир аз түшүнүксүз, бирок мен дагы сулуураак жолун таба элекмин.
Альтернативдик вариант ар бир кароону мейманкананын аталыш мейкиндигине жайгаштыруу болуп саналат, ал ар дайым толугу менен жок кылынышы мүмкүн.

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

Git Push, git checkout -b тести, git push келип чыгыш тести, текшерүү:

Gitlabда түзүлгөн чөйрөлөрдүн скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Баары иштейт? - сонун, биздин тест тармагын жок кылыңыз: git checkout master, git push origin :test, чөйрөнү жок кылуу жумуштары катасыз иштегенин текшеребиз.

Бул жерде мен дароо эле бир долбоордун ар кандай иштеп бутактарды түзө алат, ал да өзгөртө алат деп түшүндүргүм келет .gitlab-ci.yml файл жана кирүү жашыруун өзгөрмөлөр.
Ошондуктан, аларды корголгон бутактар ​​үчүн гана колдонууга уруксат берүү сунушталат, мисалы кожоюн, же ар бир чөйрө үчүн өзгөрмөлөрдүн өзүнчө топтомун түзүңүз.

13. Колдонмолорду карап чыгуу

Колдонмолорду карап чыгуу Бул жайгаштырылган чөйрөдө аны тез көрүү үчүн репозиторийдеги ар бир файл үчүн баскычты кошууга мүмкүндүк берген GitLab өзгөчөлүгү.

Бул баскычтар пайда болушу үчүн, сиз файл түзүшүңүз керек .gitlab/route-map.yml жана андагы бардык жол трансформацияларын сүрөттөп бериңиз; биздин учурда бул абдан жөнөкөй болот:

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

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

Өзгөртүүлөрүбүздү жасоону унутпаңыз:

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

Git Push, жана текшерүү:

Колдонмону карап чыгуу баскычынын скриншоту

Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Жумуш бүттү!

Долбоор булактары:

Көңүл бурганыңыз үчүн рахмат, сизге жакты деп ишенем Kubernetes'те жайгаштырууну куруу жана автоматташтыруу үчүн жаңы куралдарды сынап көрүү

Source: www.habr.com

Комментарий кошуу