Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Bongu! Riċentement, ġew rilaxxati ħafna għodod ta 'awtomazzjoni friski kemm għall-bini ta' immaġini Docker kif ukoll għall-iskjerament fil-Kubernetes. F'dan ir-rigward, iddeċidejt li nilgħab ma' GitLab, nistudja bir-reqqa l-kapaċitajiet tagħha u, ovvjament, waqqaf il-pipeline.

Dan ix-xogħol kien ispirat mill-websajt kubernetes.io, li hija ġġenerata minn kodiċi tas-sors awtomatikament, u għal kull talba pool mibgħuta, ir-robot awtomatikament jiġġenera verżjoni preview tas-sit bil-bidliet tiegħek u jipprovdi link għall-wiri.

Ippruvajt nibni proċess simili mill-bidu, iżda mibni kompletament fuq Gitlab CI u għodod b'xejn li jien imdorri nuża biex niskjera applikazzjonijiet għal Kubernetes. Illum fl-aħħar se ngħidlek aktar dwarhom.

L-artiklu se jiddiskuti għodod bħal:
Hugo, qbec, kaniko, git-crypt и GitLab CI bil-ħolqien ta’ ambjenti dinamiċi.

Kontenut

  1. Iltaqa' ma' Hugo
  2. Tħejjija tad-Dockerfile
  3. Insiru nafu kaniko
  4. Insiru nafu qbec
  5. Jipprova Gitlab-runner ma Kubernetes-executor
  6. L-iskjerament ta' charts ta' Helm ma' qbec
  7. L-introduzzjoni ta' git-crypt
  8. Ħolqien ta 'immaġni ta' kaxxa tal-għodda
  9. L-ewwel pipeline tagħna u l-assemblaġġ ta 'immaġini permezz ta' tikketti
  10. Awtomazzjoni tal-iskjerament
  11. Artifacts u assemblaġġ meta timbotta biex kaptan
  12. Ambjenti dinamiċi
  13. Irrevedi l-Apps

1. Insiru nafu lil Hugo

Bħala eżempju tal-proġett tagħna, se nippruvaw noħolqu sit għall-pubblikazzjoni tad-dokumentazzjoni mibni fuq Hugo. Hugo huwa ġeneratur tal-kontenut statiku.

Għal dawk li mhumiex familjari mal-ġeneraturi statiċi, ngħidlek ftit aktar dwarhom. B'differenza mill-magni tal-websajt konvenzjonali b'database u xi PHP, li, meta mitluba minn utent, jiġġeneraw paġni fuq il-fly, ġeneraturi statiċi huma ddisinjati ftit differenti. Jippermettulek tieħu sorsi, ġeneralment sett ta 'fajls f'Markup Markdown u mudelli ta' temi, imbagħad jikkompilawhom f'websajt kompletament lesta.

Jiġifieri, bħala riżultat, inti tirċievi struttura ta 'direttorju u sett ta' fajls HTML iġġenerati, li tista 'sempliċement ittella' fi kwalunkwe hosting irħis u tikseb websajt li taħdem.

Tista' tinstalla Hugo lokalment u tipprovaha:

Inizjalizzazzjoni ta' sit ġdid:

hugo new site docs.example.org

U fl-istess ħin ir-repożitorju git:

cd docs.example.org
git init

S'issa, is-sit tagħna huwa verġni u sabiex tidher xi ħaġa fuqu, l-ewwel għandna bżonn nikkonnettjaw tema; tema hija biss sett ta 'mudelli u regoli speċifikati li skonthom jiġi ġġenerat is-sit tagħna.

Għat-tema se nużaw Tgħallem, li, fl-opinjoni tiegħi, hija perfettament adattata għal sit ta 'dokumentazzjoni.

Nixtieq nagħti attenzjoni speċjali lill-fatt li m'għandniex bżonn nissejvjaw il-fajls tat-tema fir-repożitorju tal-proġett tagħna; minflok, nistgħu sempliċiment nikkonnettjawha bl-użu sottomodulu git:

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

Għalhekk, ir-repożitorju tagħna se jkun fih biss fajls relatati direttament mal-proġett tagħna, u t-tema konnessa tibqa 'bħala link għal repożitorju speċifiku u impenn fih, jiġifieri, dejjem tista' tinġibed mis-sors oriġinali u ma tibżax minn bidliet inkompatibbli.

Ejja nikkoreġu l-konfigurazzjoni konfig.toml:

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

Diġà f'dan l-istadju tista' tmexxi:

hugo server

U fl-indirizz http://localhost:1313/ iċċekkja l-websajt tagħna maħluqa ġdida, il-bidliet kollha li saru fid-direttorju jaġġornaw awtomatikament il-paġna miftuħa fil-browser, konvenjenti ħafna!

Ejja nippruvaw noħolqu paġna ta' qoxra content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Screenshot tal-paġna maħluqa ġdida

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Biex tiġġenera sit, mexxi:

hugo

Kontenut tad-direttorju pubbliku/ u se tkun il-websajt tiegħek.
Iva, mill-mod, ejja immedjatament żidha .gitignore:

echo /public > .gitignore

Tinsiex tikkommetti l-bidliet tagħna:

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

2. Tħejjija tad-Dockerfile

Wasal iż-żmien li tiddefinixxi l-istruttura tar-repożitorju tagħna. Normalment nuża xi ħaġa bħal:

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

  • dockerfiles/ — ikun fihom direttorji b'Dockerfiles u dak kollu meħtieġ għall-bini tal-immaġini Docker tagħna.
  • skjerament/ — fih direttorji għall-iskjerament tal-applikazzjonijiet tagħna fil-Kubernetes

Għalhekk, aħna se noħolqu l-ewwel Dockerfile tagħna tul it-triq dockerfiles/websajt/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" ]

Kif tistgħu taraw, id-Dockerfile fih tnejn MINN, din il-karatteristika tissejjaħ bini f'diversi stadji u jippermettilek teskludi dak kollu mhux meħtieġ mill-immaġni finali tad-docker.
Għalhekk, l-immaġni finali se jkun fiha biss dlamhttpd (server HTTP ħafif) u pubbliku/ — il-kontenut tal-websajt tagħna ġenerat b'mod statiku.

Tinsiex tikkommetti l-bidliet tagħna:

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

3. Insiru nafu kaniko

Bħala bennej tal-immaġni docker, iddeċidejt li nuża kaniko, peress li t-tħaddim tiegħu ma jeħtieġx docker daemon, u l-bini innifsu jista 'jitwettaq fuq kwalunkwe magna u l-cache tista' tinħażen direttament fir-reġistru, u b'hekk tiġi eliminata l-ħtieġa li jkun hemm ħażna persistenti sħiħa.

Biex tibni l-immaġini, mexxi l-kontenitur bi eżekutur kaniko u għaddih il-kuntest tal-bini attwali; dan jista' jsir ukoll lokalment, permezz ta' docker:

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 — l-isem tal-immaġni tad-docker tiegħek; wara li tinbena, tiġi mnedija awtomatikament fir-reġistru tad-docker.

Parametru --cache jippermettilek li tpoġġi saffi fil-cache fir-reġistru tad-docker; għall-eżempju mogħti, se jiġu ssejvjati fihom registry.gitlab.com/kvaps/docs.example.org/website/cache, iżda tista' tispeċifika mogħdija oħra billi tuża l-parametru --cache-repo.

Screenshot ta' docker-registry

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

4. Insiru nafu qbec

Qbec hija għodda ta' skjerament li tippermettilek tiddeskrivi b'mod dikjarattiv il-manifesti tal-applikazzjoni tiegħek u tiskjerahom fuq Kubernetes. L-użu ta 'Jsonnet bħala s-sintassi prinċipali jippermettilek tissimplifika bil-kbir id-deskrizzjoni tad-differenzi f'diversi ambjenti, u wkoll telimina kważi kompletament ir-repetizzjoni tal-kodiċi.

Dan jista 'jkun veru speċjalment f'każijiet fejn għandek bżonn tiskjera applikazzjoni għal diversi clusters b'parametri differenti u trid tiddeskrivihom b'mod dikjarattiv f'Git.

Qbec jippermettilek ukoll li tirrendi charts Helm billi tgħaddihom il-parametri meħtieġa u mbagħad tħaddem bl-istess mod bħal manifesti regolari, inkluż tista 'tapplika diversi mutazzjonijiet għalihom, u dan, imbagħad, jippermettilek teħles mill-ħtieġa li uża ChartMuseum. Jiġifieri, tista 'taħżen u tirrendi charts direttament minn git, fejn jappartjenu.

Kif għedt qabel, aħna se naħżnu l-iskjeramenti kollha f'direttorju skjerament/:

mkdir deploy
cd deploy

Ejja inizjalizzaw l-ewwel applikazzjoni tagħna:

qbec init website
cd website

Issa l-istruttura tal-applikazzjoni tagħna tidher bħal din:

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

ejja nħarsu lejn il-fajl qbec.yaml:

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

Hawnhekk aħna primarjament interessati spec.ambjenti, qbec diġà ħoloq ambjent default għalina u ħa l-indirizz tas-server, kif ukoll namespace mill-kubeconfig attwali tagħna.
Issa meta skjerament għal inadempjenza ambjent, qbec dejjem se juża biss għall-cluster Kubernetes speċifikat u għall-ispazju tal-isem speċifikat, jiġifieri, m'għadx ikollok għalfejn taqleb bejn kuntesti u spazji tal-isem sabiex twettaq skjerament.
Jekk meħtieġ, tista' dejjem taġġorna s-settings f'dan il-fajl.

L-ambjenti kollha tiegħek huma deskritti fi qbec.yaml, u fil-fajl params.libsonnet, fejn jgħid fejn tikseb il-parametri għalihom.

Imbagħad naraw żewġ direttorji:

  • komponenti / — Il-manifesti kollha għall-applikazzjoni tagħna se jinħażnu hawn; jistgħu jiġu deskritti kemm f'fajls jsonnet kif ukoll f'fajls yaml regolari
  • ambjenti/ — hawnhekk se niddeskrivu l-varjabbli (parametri) kollha għall-ambjenti tagħna.

B'mod awtomatiku għandna żewġ fajls:

  • ambjenti/base.libsonnet - se jkun fih parametri komuni għall-ambjenti kollha
  • ambjenti/default.libsonnet — fih parametri magħluba għall-ambjent inadempjenza

ejja niftħu ambjenti/base.libsonnet u żid parametri għall-ewwel komponent tagħna hemmhekk:

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

Ejja noħolqu wkoll l-ewwel komponent tagħna komponenti/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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

F'dan il-fajl iddeskrivejna tliet entitajiet Kubernetes f'daqqa, dawn huma: iskjerament, servizz и Ingress. Jekk ridna, nistgħu npoġġuhom f'komponenti differenti, iżda f'dan l-istadju wieħed ikun biżżejjed għalina.

sintassi jsonnet huwa simili ħafna għal json regolari, fil-prinċipju, json regolari huwa diġà jsonnet validu, għalhekk għall-ewwel jista 'jkun aktar faċli għalik li tuża servizzi online bħal yaml2json biex tikkonverti l-yaml tas-soltu tiegħek f'json, jew, jekk il-komponenti tiegħek ma fihom l-ebda varjabbli, allura jistgħu jiġu deskritti fil-forma ta 'yaml regolari.

Meta taħdem magħha jsonnet Nirrakkomanda ħafna li tinstalla plugin għall-editur tiegħek

Per eżempju, hemm plugin għal vim vim-jsonnet, li tixgħel l-enfasi tas-sintassi u tesegwixxi awtomatikament jsonnet fmt kull darba li tiffranka (jeħtieġ jsonnet installat).

Kollox lest, issa nistgħu nibdew niskjeraw:

Biex naraw dak li ksibna, ejja niġru:

qbec show default

Fl-output, se tara manifesti yaml mogħtija li se jiġu applikati għall-cluster default.

Kbir, issa applika:

qbec apply default

Fl-output dejjem se tara x'se jsir fil-cluster tiegħek, qbec se jgħidlek biex taqbel mal-bidliet billi ttajpja y inti tkun kapaċi tikkonferma l-intenzjonijiet tiegħek.

L-applikazzjoni tagħna hija lesta u skjerata!

Jekk tagħmel bidliet, dejjem tista' tagħmel:

qbec diff default

biex tara kif dawn il-bidliet se jaffettwaw l-iskjerament attwali

Tinsiex tikkommetti l-bidliet tagħna:

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

5. Jippruvaw Gitlab-runner b'Kubernetes-executor

Sa ftit ilu użajt biss regolari gitlab-runner fuq magna ppreparata minn qabel (kontenitur LXC) bil-qoxra jew docker-executor. Inizjalment, kellna diversi runners bħal dawn definiti globalment fil-gitlab tagħna. Ġabru immaġini docker għall-proġetti kollha.

Iżda kif wriet il-prattika, din l-għażla mhix l-aktar ideali, kemm f'termini ta 'prattiċità kif ukoll ta' sigurtà. Huwa ħafna aħjar u ideoloġikament aktar korrett li jkun hemm runners separati skjerati għal kull proġett, jew saħansitra għal kull ambjent.

Fortunatament, din mhi problema xejn, peress li issa se niskjeraw gitlab-runner direttament bħala parti mill-proġett tagħna dritt f'Kubernetes.

Gitlab jipprovdi tabella tat-tmun lesta għall-iskjerament ta' gitlab-runner għal Kubernetes. Allura kull ma trid tagħmel hu li ssir taf token tar-reġistrazzjoni għall-proġett tagħna fi Settings -> CI / CD -> Runners u għaddih għat-tmun:

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

Fejn:

  • https://gitlab.com — l-indirizz tas-server Gitlab tiegħek.
  • yga8y-jdCusVDn_t4Wxc — token ta' reġistrazzjoni għall-proġett tiegħek.
  • rbac.create=veru — jipprovdi lir-runner bl-ammont meħtieġ ta’ privileġġi biex ikun jista’ joħloq pods biex iwettaq il-kompiti tagħna bl-użu ta’ kubernetes-executor.

Jekk kollox isir b'mod korrett, għandek tara runner reġistrat fit-taqsima Runners, fis-settings tal-proġett tiegħek.

Screenshot tar-runner miżjud

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Huwa daqshekk sempliċi? - iva, hekk sempliċi! M'hemmx aktar battikata bir-reġistrazzjoni manwalment tar-runners, minn issa r-runners se jinħolqu u jinqerdu awtomatikament.

6. Uża charts Helm mal-QBEC

Peress li ddeċidejna li nikkunsidraw gitlab-runner parti mill-proġett tagħna, wasal iż-żmien li niddeskrivuha fir-repożitorju Git tagħna.

Nistgħu niddeskrivuha bħala komponent separat websajt, iżda fil-futur qed nippjanaw li niskjeraw kopji differenti websajt ħafna drabi, b'differenza gitlab-runner, li se jiġu skjerati darba biss għal kull cluster Kubernetes. Mela ejja inizjalizza applikazzjoni separata għaliha:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Din id-darba mhux se niddeskrivu l-entitajiet Kubernetes manwalment, iżda se nieħdu chart Helm lest. Wieħed mill-vantaġġi ta 'qbec huwa l-abbiltà li tirrendi mapep Helm direttament minn repożitorju Git.

Ejja nqabbduha billi tuża git submodule:

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

Issa d-direttorju bejjiegħ/gitlab-runner Għandna repożitorju bi chart għal gitlab-runner.

B'mod simili, tista 'tqabbad repożitorji oħra, pereżempju, ir-repożitorju kollu ma' charts uffiċjali https://github.com/helm/charts

Ejja niddeskrivu l-komponent komponenti/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,
  }
)

L-ewwel argument biex expandHelmTemplate aħna ngħaddu t-triq lejn iċ-ċart, imbagħad params.values, li nieħdu mill-parametri ambjentali, imbagħad jiġi l-oġġett ma '

  • nameTemplate — isem tar-rilaxx
  • spazju ta 'l-ismijiet — l-ispazju tal-isem trasferit għat-tmun
  • dan il-Fajl — parametru meħtieġ li jgħaddi l-mogħdija għall-fajl kurrenti
  • verbose - juri l-kmand mudell tat-tmun bl-argumenti kollha meta tirrendi ċ-ċart

Issa ejja niddeskrivu l-parametri għall-komponent tagħna fi ambjenti/base.libsonnet:

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

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

Oqgħod attent runnerRegistrationToken nieħdu minn fajl estern sigrieti/base.libsonnet, ejja noħolquha:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Ejja niċċekkjaw jekk kollox jaħdem:

qbec show default

jekk kollox huwa fl-ordni, allura nistgħu nħassru r-rilaxx tagħna skjerat qabel permezz ta' Helm:

helm uninstall gitlab-runner

u użah bl-istess mod, iżda permezz tal-qbec:

qbec apply default

7. Introduzzjoni għal git-crypt

Git-kripto hija għodda li tippermettilek li twaqqaf encryption trasparenti għar-repożitorju tiegħek.

Bħalissa, l-istruttura tad-direttorju tagħna għal gitlab-runner tidher bħal din:

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

Imma l-ħażna tas-sigrieti fil-Git mhix sigura, hux? Allura għandna bżonn nikkriptawhom kif suppost.

Normalment, għall-fini ta 'varjabbli waħda, dan mhux dejjem jagħmel sens. Tista 'tittrasferixxi sigrieti lil qbec u permezz tal-varjabbli ambjentali tas-sistema CI tiegħek.
Iżda ta 'min jinnota li hemm ukoll proġetti aktar kumplessi li jista' jkun fihom ħafna aktar sigrieti; it-trasferiment tagħhom kollha permezz ta 'varjabbli ambjentali se jkun estremament diffiċli.

Barra minn hekk, f'dan il-każ ma nkunx kapaċi ngħidilkom dwar għodda tant mill-isbaħ bħal git-crypt.

git-crypt Huwa wkoll konvenjenti peress li jippermettilek li tissejvja l-istorja kollha tas-sigrieti, kif ukoll tqabbel, tgħaqqad u ssolvi l-kunflitti bl-istess mod kif imdorrijin nagħmlu fil-każ ta 'Git.

L-ewwel ħaġa wara l-installazzjoni git-crypt għandna bżonn niġġeneraw ċwievet għar-repożitorju tagħna:

git crypt init

Jekk għandek ċavetta PGP, allura tista' immedjatament iżżid lilek innifsek bħala kollaboratur għal dan il-proġett:

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

B'dan il-mod tista 'dejjem tiddekofra dan ir-repożitorju billi tuża ċ-ċavetta privata tiegħek.

Jekk ma jkollokx ċavetta PGP u ma tistenniex, allura tista' tmur in-naħa l-oħra u tesporta ċ-ċavetta tal-proġett:

git crypt export-key /path/to/keyfile

Għalhekk, kull min għandu esportat keyfile se jkun jista' jiddekofra r-repożitorju tiegħek.

Wasal iż-żmien li nwaqqfu l-ewwel sigriet tagħna.
Ħa nfakkarkom li għadna fid-direttorju deploy/gitlab-runner/, fejn għandna direttorju sigrieti/, ejja nikkriptaw il-fajls kollha fiha, għal dan se noħolqu fajl sigrieti/.gitattributes bil-kontenut li ġej:

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

Kif jidher mill-kontenut, il-fajls kollha huma mgħottija * se jiġu misjuqa permezz git-crypt, ħlief għall-aktar .gitattributes

Nistgħu niċċekkjaw dan billi nħaddmu:

git crypt status -e

L-output se jkun lista tal-fajls kollha fir-repożitorju li għalihom l-encryption hija attivata

Dak kollu, issa nistgħu nwettqu l-bidliet tagħna b'mod sikur:

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

Biex timblokka repożitorju, mexxi:

git crypt lock

u immedjatament il-fajls kriptati kollha jinbidlu f'xi ħaġa binarja, ikun impossibbli li taqrahom.
Biex tiddeċifra r-repożitorju, mexxi:

git crypt unlock

8. Oħloq immaġni tal-kaxxa tal-għodda

Immaġini ta' kaxxa tal-għodda hija immaġni bl-għodod kollha li se nużaw biex niskjeraw il-proġett tagħna. Se jintuża mir-runner ta' Gitlab biex iwettaq kompiti ta' skjerament tipiċi.

Hawnhekk kollox huwa sempliċi, ejja noħolqu waħda ġdida dockerfiles/toolbox/Dockerfile bil-kontenut li ġej:

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

Kif tistgħu taraw, f'din l-immaġni aħna ninstallaw l-utilitajiet kollha li użajna biex inħaddmu l-applikazzjoni tagħna. M'għandniex bżonnha hawn sakemm kubectl, iżda tista' tkun trid tilgħab magħha matul il-fażi ta' twaqqif tal-pipeline.

Ukoll, sabiex inkunu nistgħu nikkomunikaw ma 'Kubernetes u niskjeraw għalih, għandna bżonn nikkonfiguraw rwol għall-imżiewed iġġenerati minn gitlab-runner.

Biex tagħmel dan, ejja mmorru fid-direttorju b'gitlab-runner:

cd deploy/gitlab-runner

u żid komponent ġdid komponenti/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,
      },
    ],
  },
]

Se niddeskrivu wkoll il-parametri l-ġodda fi ambjenti/base.libsonnet, li issa tidher bħal din:

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

Oqgħod attent $.components.rbac.name jirreferi għal isem għall-komponent rbac

Ejja niċċekkjaw x'inbidel:

qbec diff default

u applika l-bidliet tagħna għal Kubernetes:

qbec apply default

Ukoll, tinsiex tikkommetti l-bidliet tagħna għal 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. L-ewwel pipeline tagħna u assemblaġġ ta 'immaġini permezz ta' tikketti

Fl-għerq tal-proġett se noħolqu .gitlab-ci.yml bil-kontenut li ġej:

.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

Jekk jogħġbok innota li nużaw GIT_SUBMODULE_STRATEGY: normali għal dawk l-impjiegi fejn għandek bżonn inizjalizza espliċitament is-submoduli qabel l-eżekuzzjoni.

Tinsiex tikkommetti l-bidliet tagħna:

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

Naħseb li nistgħu nsejħulha b'mod sikur verżjoni v0.0.1 u żid it-tikketta:

git tag v0.0.1

Aħna se nżidu tikketti kull meta jkollna bżonn nirrilaxxaw verżjoni ġdida. It-tikketti fl-immaġini Docker se jkunu marbuta mat-tikketti Git. Kull push b'tikketta ġdida se initialize l-bini ta 'immaġini b'din it-tikketta.

Ejja nagħmluha git push --tags, u ejja nħarsu lejn l-ewwel pipeline tagħna:

Screenshot tal-ewwel pipeline

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Ta 'min jiġbed l-attenzjoni tiegħek għall-fatt li l-assemblaġġ permezz ta' tikketti huwa adattat għall-bini ta 'immaġini ta' docker, iżda mhuwiex adattat għall-iskjerament ta 'applikazzjoni għal Kubernetes. Peress li tikketti ġodda jistgħu jiġu assenjati għal kommessi qodma, f'dan il-każ, l-inizjalizzazzjoni tal-pipeline għalihom se twassal għall-iskjerament tal-verżjoni l-antika.

Biex issolvi din il-problema, normalment il-bini ta 'immaġini docker huwa marbut ma' tikketti, u l-iskjerament tal-applikazzjoni għal fergħa kaptan, li fiha l-verżjonijiet tal-immaġini miġbura huma hardcoded. Dan huwa fejn tista 'inizjalizza rollback b'reverse sempliċi kaptan-fergħat.

10. Awtomazzjoni tal-iskjerament

Sabiex Gitlab-runner jiddeċifra s-sigrieti tagħna, ikollna bżonn nesportaw iċ-ċavetta tar-repożitorju u nżiduha mal-varjabbli tal-ambjent CI tagħna:

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

Aħna ser insalvaw il-linja li tirriżulta f'Gitlab; biex tagħmel dan, ejja mmorru fis-settings tal-proġett tagħna:
Settings -> CI / CD -> Varjabbli

U ejja noħolqu varjabbli ġdida:

tip
Ewlenin
valur
protetti
Masked
Ambitu

File
GITCRYPT_KEY
<your string>
true (matul it-taħriġ tista' false)
true
All environments

Screenshot tal-varjabbli miżjuda

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Issa ejja naġġornaw tagħna .gitlab-ci.yml iżżid miegħu:

.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

Hawnhekk ippermettejna diversi għażliet ġodda għal qbec:

  • --root xi/app — jippermettilek tiddetermina d-direttorju ta’ applikazzjoni speċifika
  • --force:k8s-context __incluster__ - din hija varjabbli maġika li tgħid li l-iskjerament se jseħħ fl-istess cluster li fih qed jaħdem gtilab-runner. Dan huwa meħtieġ għax inkella qbec jipprova jsib server Kubernetes xieraq fil-kubeconfig tiegħek
  • --stenna — iġiegħel lil qbec jistenna sakemm ir-riżorsi li joħloq jidħlu fl-istat Ready u mbagħad biss joħorġu b'exit-code ta' suċċess.
  • —iva - sempliċement tiddiżattiva l-qoxra interattiva Żgur? meta skjerat.

Tinsiex tikkommetti l-bidliet tagħna:

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

U wara git push se naraw kif l-applikazzjonijiet tagħna ġew skjerati:

Screenshot tat-tieni pipeline

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

11. Artifacts u assemblaġġ meta timbotta biex kaptan

Tipikament, il-passi deskritti hawn fuq huma biżżejjed biex nibnu u nwasslu kważi kull mikroservizz, iżda ma rridux inżidu tikketta kull darba li jkollna bżonn naġġornaw is-sit. Għalhekk, se nieħdu rotta aktar dinamika u nwaqqfu skjerament diġest fil-fergħa kaptan.

L-idea hija sempliċi: issa l-immaġni ta 'tagħna websajt se jerġgħu jinbnew kull darba li timbotta kaptan, u mbagħad awtomatikament skjerati għal Kubernetes.

Ejja naġġornaw dawn iż-żewġ impjiegi fil tagħna .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"

Jekk jogħġbok innota li żidna ħajta kaptan к ref għall-impjiegi build_website u issa nużaw $CI_COMMIT_REF_NAME minflok $CI_COMMIT_TAG, jiġifieri, aħna maħlula minn tikketti f'Git u issa se nimbottaw immaġini bl-isem tal-fergħa tal-kommit li inizjalizza l-pipeline. Ta 'min jinnota li dan se jaħdem ukoll b'tikketti, li jippermettulna nsalvaw snapshots ta' sit b'verżjoni speċifika fid-docker-reġistru.

Meta l-isem tat-tag docker għal verżjoni ġdida tas-sit jista’ ma jinbidilx, għad irridu niddeskrivu l-bidliet f’Kubernetes, inkella sempliċement ma jerġax jiġi skjerat l-applikazzjoni mill-immaġni l-ġdida, peress li ma tinnota l-ebda tibdil fil- manifest tal-iskjerament.

Għażla —vm:ext-str digest="$DIGEST" għal qbec - jippermettilek tgħaddi varjabbli estern lil jsonnet. Irridu li jiġi skjerat mill-ġdid fil-cluster ma 'kull rilaxx tal-applikazzjoni tagħna. Ma nistgħux nibqgħu nużaw l-isem tat-tikketta, li issa jista' ma jinbidilx, peress li jeħtieġ li nkunu marbuta ma' verżjoni speċifika tal-immaġni u nixprunaw l-iskjerament meta tinbidel.

Hawnhekk se nkunu megħjunin mill-abbiltà ta’ Kaniko li jiffrankaw immaġini diġestiva f’fajl (għażla --digest-file)
Imbagħad aħna se tittrasferixxi dan il-fajl u naqrawh fil-ħin tal-iskjerament.

Ejja naġġornaw il-parametri għal tagħna deploy/website/environments/base.libsonnet li issa se tidher bħal din:

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

Magħmul, issa kull impenn fi kaptan initializes il-bini tal-immaġni docker għal websajt, u mbagħad tiskjeraha f'Kubernetes.

Tinsiex tikkommetti l-bidliet tagħna:

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

Niċċekkjaw aktar tard git push għandna naraw xi ħaġa bħal din:

Screenshot tal-pipeline għall-kaptan

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Fil-prinċipju, m'għandniex bżonn nerġgħu niskjeraw gitlab-runner ma' kull spinta, sakemm, ovvjament, ma nbidilx xejn fil-konfigurazzjoni tiegħu, ejja nirranġawha .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/**/*

bidliet se jippermettilek tissorvelja l-bidliet fil deploy/gitlab-runner/ u se jqanqal ix-xogħol tagħna biss jekk ikun hemm

Tinsiex tikkommetti l-bidliet tagħna:

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

git push, dak aħjar:

Screenshot tal-pipeline aġġornat

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

12. Ambjenti dinamiċi

Wasal iż-żmien li niddiversifikaw il-pipeline tagħna b'ambjenti dinamiċi.

L-ewwel, ejja naġġornaw ix-xogħol build_website fil tagħna .gitlab-ci.yml, tneħħi l-blokka minnha biss, li se jġiegħel lil Gitlab iqanqalha fuq kwalunkwe impenn għal kwalunkwe fergħa:

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/

Imbagħad aġġorna l-impjieg deploy_website, żid blokka hemmhekk ambjent:

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"

Dan se jippermetti lil Gitlab jassoċja l-impjieg ma ' produzzjoni ambjent u turi l-link korrett għalih.

Issa ejja nżidu żewġ impjiegi oħra:

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

Dawn se jiġu mnedija malli jimbuttaw lejn kwalunkwe fergħa ħlief kaptan u se jużaw il-verżjoni preview tas-sit.

Naraw għażla ġdida għal qbec: --app-tag — jippermettilek li ttikketta verżjonijiet skjerati tal-applikazzjoni u taħdem biss f'din it-tikketta; meta toħloq u teqred ir-riżorsi f'Kubernetes, qbec se jopera biss magħhom.
Dan il-mod ma nistgħux noħolqu ambjent separat għal kull reviżjoni, iżda sempliċement nużaw mill-ġdid l-istess wieħed.

Hawnhekk nużaw ukoll qbec japplikaw reviżjoni, minflok qbec japplikaw default - dan huwa eżattament il-mument meta se nippruvaw niddeskrivu d-differenzi għall-ambjenti tagħna (reviżjoni u default):

Żid tirrevedi ambjent fi deploy/website/qbec.yaml

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

Imbagħad se niddikjarawha fi 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

U ikteb il-parametri tad-dwana għaliha 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',
    },
  },
}

Ejja nagħtu wkoll ħarsa aktar mill-qrib lejn jobu stop_review, se tiġi attivata meta l-fergħa titħassar u sabiex gitlab ma jipprovax jagħmel checkout huwa użat GIT_STRATEGY: xejn, aktar tard aħna klonu kaptan-fergħa u ħassar reviżjoni permezz tagħha.
Huwa ftit konfuż, imma għadni ma sibtx mod aktar sabiħ.
Għażla alternattiva tkun li kull reviżjoni tiġi skjerata fi spazju tal-isem tal-lukanda, li dejjem jista' jitwaqqa' għal kollox.

Tinsiex tikkommetti l-bidliet tagħna:

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

git push, git checkout -b test, test tal-oriġini git push, iċċekkja:

Screenshot ta' ambjenti maħluqa f'Gitlab

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Kollox qed jaħdem? - kbir, ħassar il-fergħa tat-test tagħna: git checkout kaptan, git push origin :test, niċċekkjaw li l-impjiegi tat-tħassir tal-ambjent ħadmu mingħajr żbalji.

Hawnhekk nixtieq niċċara immedjatament li kwalunkwe żviluppatur fi proġett jista 'joħloq fergħat, jista' wkoll jinbidel .gitlab-ci.yml fajl u aċċess għal varjabbli sigrieti.
Għalhekk, huwa rakkomandat ħafna li jitħallew l-użu tagħhom biss għal fergħat protetti, pereżempju fil kaptan, jew toħloq sett separat ta' varjabbli għal kull ambjent.

13. Irrevedi l-Apps

Irrevedi l-Apps Din hija karatteristika GitLab li tippermettilek iżżid buttuna għal kull fajl fir-repożitorju biex tarah malajr f'ambjent skjerat.

Sabiex dawn il-buttuni jidhru, trid toħloq fajl .gitlab/route-map.yml u ddeskrivi t-trasformazzjonijiet kollha tal-passaġġ fiha; fil-każ tagħna se jkun sempliċi ħafna:

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

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

Tinsiex tikkommetti l-bidliet tagħna:

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

git push, u ċċekkja:

Screenshot tal-buttuna Review App

Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Xogħol lest!

Sorsi tal-proġett:

Grazzi tal-attenzjoni tiegħek, nispera li għoġobkom Jippruvaw għodod ġodda għall-bini u l-awtomatizzazzjoni tal-iskjerament f'Kubernetes

Sors: www.habr.com

Żid kumment