Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

Tere! Viimase aja jooksul on ilmunud palju Àgedaid automatiseerimise tööriistu nii Docker-piltide koostamiseks kui ka Kubernetesesse juurutamiseks. SeetÔttu otsustasin katsetada GitLabiga, uurida selle vÔimalusi ning muidugi seadistada pipeline'i.

Selle töö inspiratsiooniks sai veebileht kubernetes.io, mis genereeritakse allikatest automaatsete kaudu ning iga saadetud pull requesti puhul genereerib robot automaatselt saidi eelvaateversiooni koos teie muudatustega ja pakub seda vaatamiseks linki.

PĂŒĂŒdlesin sarnase protsessi loomise poole nullist, kuid tĂ€iesti suunatud GitLab CI-le ning vabadele tööriistadele, mida olen harjunud kasutama rakenduste juurutamiseks Kubernetesesse. TĂ€na jagan ma teiega nende kohta lĂ€hemalt.

Artiklis kÀsitletakse selliseid tööriistu nagu:
Hugo, git-crypt, kaniko, , mida kĂ€sitleti pĂ”hjalikult eelnevas artiklis. ja GitLab CI-d dĂŒnaamiliste keskkondade loomisel.

Sisukord

  1. Tutvumine Hugoga
  2. Dockerfile'i ettevalmistamine
  3. Tutvumine kanikoga
  4. Tutvumine qbeciga
  5. Proovime GitLab-runnereid Kubernetes-executoriga
  6. Helm-kartude juurutamine qbeciga
  7. Tutvumine git-cryptiga
  8. Loome toolbox-pildi
  9. Meie esimesed pipeline ja piltide koostamine siltide kaupa
  10. Juurutamise automatiseerimine
  11. Artefaktid ja koostamine masterisse pushimise korral
  12. DĂŒnaamilised keskkonnad
  13. Review Apps

1. Tutvumine Hugoga

Meie projekti nĂ€itena proovime luua dokumentatsiooni avaldamiseks mĂ”eldud saiti, mis on ĂŒles ehitatud Hugole. Hugo on staatiline sisu genereerija.

Neile, kes pole staatiliste generaatoritega tuttavad, rÀÀgin neist pisut lÀhemalt. Erinevalt tavapÀrastest andmebaasi pÔhistest veebilehtedest ja mingist php-st, mis genereerivad kasutaja pÀringute korral lehti reaalajas, on staatilised generaatorid korraldatud veidi teisiti. Need vÔimaldavad vÔtta lÀhtefailid, tavaliselt on need Markdown-formaadis failide kogum ja malli mÀÀratlused, ning koostada need tÀielikult valmis veebileheks.

See tĂ€hendab, et tulemuseks on kaustastruktuur ja kogum genereeritud HTML-faile, mille saab lihtsalt ĂŒles laadida mistahes odavale hostimise teenusele ja saada töötav veebileht.

Hugo saab paigaldada kohalikult ja proovida seda praktikas:

Loodame uue saidi:

hugo new site docs.example.org

Ja ĂŒhtlasi git-reposiitori:

cd docs.example.org
git init

Praegu on meie sait puhas ja et midagi sinna ilmuks, peame kÔigepealt teema aktiveerima, teema on lihtsalt hulk malle ja mÀÀratletud reegleid, mille alusel meie saidi genereeritakse.

Teemana kasutame Learn, mis on minu arvates ideaalne dokumentatsioonilehe jaoks.

Tuleb eraldi tĂ€helepanu pöörata sellele, et me ei pea teema faile oma projekti hoidlas sĂ€ilitama, selle asemel saame lihtsalt selle ĂŒhendamisega kasutada git submodule:

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

Nii jÀÀvad meie hoidlas ainult failid, mis on otseselt seotud meie projektiga, ja ĂŒhendatud teema jÀÀb viitena konkreetsele hoidla ja commit'ile, seega saab selle alati originaalallikast vĂ€lja tĂ”mmata ja mitte kartma ĂŒhilduvuse muutusi.

Parandame konfiguratsiooni config.toml:

baseURL = "http://docs.example.org/"
languageCode = "en-us"
title = "Minu dokumentide leht"
theme = "learn"

Juba sellel etapil saame kÀivitada:

hugo server

Ja aadressil http://localhost:1313/ kontrollida meie just loodud veebilehte, kÔik muudatused kataloogis uuendavad automaatselt ka avatud lehte brauseris, vÀga mugav!

Proovime luua esilehe failis content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Kuvake just loodud lehe ekraanipilt

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

Veebilehe genereerimiseks piisab, kui kÀivitada:

hugo

Katalooge sisu public/ ja need saavad olema teie veebileht.
Jah, muide, lisagem see kohe .gitignore:

echo /public > .gitignore

Ärge unustage meie muudatusi commitida:

git add .
git commit -m "Uus veebileht loodud"

2. Dockerfile valmistamine

On aeg mÀÀrata meie hoidla struktuur. Tavaliselt kasutan midagi sellist:

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

  • dockerfiles/ — sisaldavad katalooge Dockerfile'ide ja kĂ”ike vajalikku meie docker-piltide koostamiseks.
  • deploy/ — sisaldab katalooge meie rakenduste juurutamiseks Kubernetesesse

Nii loome meie esimese Dockerfile'i teele 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" ]

Nagu te nÀete, Dockerfile sisaldab kahte KUST, see vÔimalus nimetatakse multi-stage build ja vÔimaldab vÀlistada lÔplikust docker-pildist kÔik mittevajalikud elemendid.
Nii sisaldab meie lĂ”plik pilt ainult darkhttpd (kerge HTTP-server) ja public/ — meie staatiliselt genereeritud veebilehe sisu.

Ärge unustage meie muudatusi commitida:

git add dockerfiles/website
git commit -m "Lisa Dockerfile veebilehe jaoks"

3. Tutvumine kanikoga

Docker- kujundaja eestkasutamise otsustasin kasutada kaniko, kuna selle tööks ei ole vaja docker-daemonit, ja kogu kogumise saab teha igasugusel masinal, hoides vahemĂ€lu otse registris, vabastades seelĂ€bi vajadusest omada tĂ€ielikku pĂŒsivat salvestust.

Pildi koostamiseks piisab, kui kÀivitada konteiner kaniko tÀitja ja edastada talle praegune koostamise kontekst, seda saab teha ka kohalikult, lÀbi 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

Kus registry.gitlab.com/ kvaps/ docs.example.org/ website — teie docker-pildi nimi, pĂ€rast koostamist pushitakse see automaatselt docker-registrisse.

Parameeter —cache vĂ”imaldab salvestada kihid docker registrisse, antud nĂ€ite puhul salvestatakse need registry.gitlab.com/ kvaps/ docs.example.org/ website/ cache, kuid vĂ”ite mÀÀrata ka teise tee parameetriga —cache-repo.

Docker-registri ekraanipilt

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

4. Qbeci tutvumine

Qbec on deployimise tööriist, mis vÔimaldab teie rakenduse manifestide deklaratiivset kirjeldamist ja nende kÀivitamist Kuberneteses. Jsonnet'i kasutamine pÔhikeelena lihtsustab erinevuste kirjeldamist erinevate keskkondade vahel ning peaaegu tÀielikult vabastab koodi kordumisest.

See vÔib olla eriti oluline juhtudel, kui peate rakenduse mitmetesse klastritesse erinevate parameetritega juurutama ja soovite neid Git'is deklaratiivselt kirjeldada.

Qbec vÔimaldab samuti renderdada Helm-diagramme, edastades neile vajalikud parameetrid, ja hiljem kÀsitleda neid nagu tavalisi manifeste, sealhulgas saab neile rakendada erinevaid mutatsioone, mis omakorda vabastab ChartMuseum'i kasutamise vajadusest. See tÀhendab, et saate diagramme hoida ja renderdada otse git's, kus need tÔeliselt kuuluvad.

Nagu ma varem ĂŒtlesin, hoiame kĂ”ik juurutamised kaustas deploy/:

mkdir deploy
cd deploy

Alustame oma esimest rakendust:

qbec init website
cd website

NĂŒĂŒd nĂ€eb meie rakenduse struktuur vĂ€lja jĂ€rgmine:

.
├── komponendid
├── keskkonnad
│ ├── base.libsonnet
│ └── default.libsonnet
├── params.libsonnet
└── qbec.yaml

vaatame faili qbec.yaml:

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

Siin huvitab meid eelkÔige spec.environments, qbec on juba loonud meie eest vaike keskkonna ja vÔtnud serveri aadressi, samuti nimistu meie praegusest kubeconfig'ist.
NĂŒĂŒd, kui me rakendame SeejĂ€rel kĂ€ivitame exec kĂ€su ja ootame 5000 sekundit, et jĂ€tkata jĂ€lgimist: keskkonda, rakendab qbec alati ainult mÀÀratud Kubernetes-klastrisse ja mÀÀratud nimistusse, mis tĂ€hendab, et teil ei ole enam vaja kontekste ja nimistusi vahetada, et rakendust kĂ€ivitada.
Vajadusel saate alati seda faili seadistusi uuendada.

KÔik teie keskkonnad on kirjeldatud qbec.yaml, ning failis params.libsonnet, kus on öeldud, kust tuleb neile parameetrid vÔtta.

JÀrgmine nÀeme kahte katalooge:

  • components/ — siia salvestatakse kĂ”ik manifeste meie rakenduse jaoks, need vĂ”ivad olla kirjutatud nii jsonnetis kui ka tavalistes yaml-failides
  • environments/ — siin kirjeldame kĂ”iki muutujaid (parameetreid) meie keskkondade jaoks.

Vaikimisi on meil kaks faili:

  • environments/base.libsonnet — see sisaldab kĂ”iki keskkondadele ĂŒhiseid parameetreid
  • environments/default.libsonnet — sisaldab ĂŒmberdefineeritud parameetreid keskkonna jaoks SeejĂ€rel kĂ€ivitame exec kĂ€su ja ootame 5000 sekundit, et jĂ€tkata jĂ€lgimist:

Avame nĂŒĂŒd environments/base.libsonnet ja lisame sinna parameetrid meie esimese komponendi jaoks:

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

Loomime ka meie esimese komponendi 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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

Selles failis oleme kirjeldanud kolm Kubernetes-ĂŒksust: Deployment, Teenused ja Ingress. Soovi korral oleksime vĂ”inud need erinevatesse komponentidesse jagada, kuid sellel etapil piisab meile ka ĂŒhest.

SĂŒntaks jsonnet on vĂ€ga sarnane tavalisest json failist, tegelikult on tavaline json juba kehtiv jsonnet, nii et esialgu vĂ”ib teid aidata kasutada selliseid veebiteenuseid nagu yaml2json , et konverteerida tuttav yaml json formatiks vĂ”i, kui teie komponendid ei sisalda mingeid muutujat, siis on need tĂ€iesti kirjeldatavad ka tavalise yaml kujul.

Töötades jsonnet Soovitan tungivalt installida teie redigeerijale pistikprogrammi:

NĂ€iteks vimile on olemas pistikprogramm vim-jsonnet, mis sisaldab sĂŒntaksikaitset ja kĂ€ivitab automaatselt jsonnet fmt igal salvestamisel (vajab installitud jsonnet'i).

KĂ”ik on valmis, nĂŒĂŒd saame alustama rakenduse juurutamist:

Et nÀha, mis meil on, kÀivitage:

qbec show default

VÀljastusel nÀete renderdatud yaml-manifesti, mis rakendatakse default klastrisse.

SuurepĂ€rane, nĂŒĂŒd rakendame:

qbec apply default

VÀljastusel nÀete alati, mida teie klastris tehakse, qbec palub teil nÔustuda muudatustega, sisestades y saate oma kavatsused kinnitada.

NĂŒĂŒd on meie rakendus juurutatud!

Muutatuste tegemisel vÔite alati teha:

qbec diff default

et nÀha, kuidas need muudatused mÔjutavad praegust deploy'd

Ärge unustage meie muudatusi commitida:

cd ..\/..
git add deploy\/website
git commit -m "Lisa deploy veebisaidile"

5. Proovime Gitlab-runnerit Kubernetes-executoriga

Kuni hiljuti kasutasin ainult tavapÀrast gitlab-runner ettevalmistatud masinas (LXC-konteineris) shell- vÔi docker-executoriga. Alguses oli meil mitu sellist runnerit, mis olid globaalselt mÀÀratud meie GitLabis. Need kogusid docker-pilte kÔigi projektide jaoks.

Kuid praktika nĂ€itas, et see valik ei ole kĂ”ige ideaalne, ei praktilisuse ega turvalisuse osas. Oluliselt parem ja ideoloogiliselt Ă”igesti on omada eraldi runner'eid, mis on deploy’dud iga projekti jaoks, kui ka igas keskkonnas.

Õnneks ei ole see probleem, kuna nĂŒĂŒd plaanime deploy'da gitlab-runner otse kui osa meie projektist otse Kubernetesesse.

GitLab pakub valmis helm-chart'i gitlab-runner'i deploy'imiseks Kubernetesesse. Seega on kĂ”ik, mida vajate, Ă”ppida registreerimise token meie projekti jaoks Settings —> CI \/ CD —> Runners ja edastada see helm'ile:

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

Kus:

  • https://gitlab.com — teie GitLab serveri aadress.
  • yga8y-jdCusVDn_t4Wxc — registraator token teie projekti jaoks.
  • rbac.create=true — annab runner'ile vajaliku hulga Ă”igusi, et luua pod'e meie ĂŒlesannete tĂ€itmiseks kubernetes-executor'i abil.

Kui kÔik on Ôigesti tehtud, peaksite nÀgema registreeritud runner'it jaotises Runners, teie projekti seadistustes.

KuvatÔmmis lisatud runner'ist

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

NiivĂ”rd lihtne? — jah, nii lihtne! Enam pole mingeid probleemide registreerimisel kĂ€sitsi, alates nĂŒĂŒd luuakse ja hĂ€vitatakse runner'id automaatselt.

6. Helm-chartide deploy QBEClt

Kuna oleme otsustanud lugeda gitlab-runner oma projekti osaks, on aeg see meie Git-repositooriumis kirja panna.

Me oleksime vĂ”inud seda kirjeldada kui eraldi komponenti veebisait, kuid tulevikus plaanime deploy'da erinevaid koopiaid veebisait vĂ€ga tihti, erinevalt gitlab-runner, mis deploy’dakse vaid ĂŒks kord igale Kubernetes'ile. Nii et laseme alustada eraldi rakenduse loomisega:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Seekord me ei kirjelda Kubernetes'i objekte kĂ€sitsi, vaid kasutame valmistehtud Helm chart'i. Üks qbec'i eeliseid on see, et saame renderdada Helm chart'e otse Git-repositooriumist.

Liitume sellega git alamhargiga:

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

NĂŒĂŒd kaust vendor/gitlab-runner sisaldab meie jaoks repositooriumi gitlab-runner'i chart'iga.

Sarnasel viisil saab liita ka teisi repositooriume, nÀiteks kogu repositooriumi ametlikest chart'idest. https://github.com/helm/charts

Kirjeldame komponenti 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,
  }
)

Esimese argumendina expandHelmTemplate anname tee chart'ini, seejÀrel params.values, mis tuleb keskkonnaparameetritest, seejÀrel tuleb objekt

  • nameTemplate — versiooni nimi
  • namespace — nĂ”utav hĂ€lve Helm'ile
  • thisFile — kohustuslik parameter, mis edastab tee praegusele failile
  • verbose — nĂ€itab kĂ€sku helm template koos kĂ”igi argumentidega chart'i renderdamisel.

NĂŒĂŒd kirjeldame meie komponentide parameetreid 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,
      },
    },
  },
}

Pange tÀhele runnerRegistrationToken saame vÀlist failist secrets/base.libsonnet, loome selle:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Kontrollime, kas kÔik töötab:

qbec show default

kui kÔik on korras, saame eemaldada meie varem Helm'i kaudu juurutatud versiooni:

helm uninstall gitlab-runner

ja juurutada sama, aga nĂŒĂŒd qbec'i kaudu:

qbec apply default

7. Tutvumine git-crypt'iga

Git-crypt on tööriist, mis vĂ”imaldab seadistada lĂ€bipaistvat krĂŒpteerimist teie repositooriumis.

Praegu nÀeb meie gitlab-runner'i kausta struktuur vÀlja selline:

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

Kuid saladuste hoidmine Git'is pole turvaline, eks? Nii et peame need korralikult krĂŒpteerima.

Ühe muutuja puhul ei ole see alati mĂ”istlik. Saate edastada saladusi git-crypt ja ka CI-sĂŒsteemid oma keskkonnamuutujate kaudu.
Kuid tasub mÀrkida, et on ka keerulisemaid projekte, mis vÔivad sisaldada palju rohkem salajasi andmeid, mille edastamine keskkonnamuutujate kaudu oleks ÀÀrmiselt keeruline.

Lisaks ei oleks ma sel juhul saanud rÀÀkida teile sellisest suurepÀrasest tööriistast nagu , mida kÀsitleti pÔhjalikult eelnevas artiklis..

, mida kĂ€sitleti pĂ”hjalikult eelnevas artiklis. on mugav ka selle poolest, et vĂ”imaldab salvestada kogu salajaste andmete ajalugu, samuti vĂ”rrelda, ĂŒhendada ja lahendada konflikte nii nagu me oleme harjunud seda tegema Git'i puhul.

Esimese asjana pÀrast installimist , mida kÀsitleti pÔhjalikult eelnevas artiklis. peame genereerima vÔtmed meie hoidla jaoks:

git crypt init

Kui teil on PGP-vÔti, siis saate kohe lisada end selle projekti partneriks:

git-crypt add-gpg-user kvapss@gmail.com

Nii saate alati dekrĂŒpteerida seda hoidlat, kasutades oma privaatvĂ”tit.

Kui aga teil ei ole PGP-vÔtit ja see ei ole plaanis, siis vÔite valida teise tee ja eksportida projekti vÔtme:

git crypt export-key /path/to/keyfile

Nii suudab igaĂŒks, kellel on eksporditud keyfile dekrĂŒpteerida teie hoidla.

On aeg seadistada meie esimene saladus.
Tuletan meelde, et me oleme endiselt kaustas deploy/gitlab-runner/, kus meil on kaust secrets/, alustame kĂ”igi failide krĂŒpteerimist, selleks loome faili secrets/.gitattributes sellise sisuga:

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

Kuidas nÀha sisu, kÔik failid, mis vastavad mustrile * moodustatakse lÀbi , mida kÀsitleti pÔhjalikult eelnevas artiklis., vÀlja arvatud fail .gitattributes

Saame seda kontrollida, kÀivitades:

git crypt status -e

Saame vĂ€ljundis loetelu kĂ”igist hoidla failidest, mille puhul on krĂŒpteerimine lubatud.

See on kĂ”ik, nĂŒĂŒd saame julgelt oma muudatusi commitida:

cd ../..
git add .
git commit -m "Lisa deploy gitlab-runner'ile"

Hoidla lukustamiseks piisab, kui kÀivitada:

git crypt lock

ja kĂ”ik krĂŒpteeritud failid muutuvad koheselt binaarseks nĂ€htamatuks, neid ei ole vĂ”imalik lugeda.
Hoidla dekrĂŒpteerimiseks kĂ€ivitage:

git crypt unlock

8. Loome toolbox-pildi

Toolbox-pilt on selline pilt koos kĂ”igi tööriistadega, mida kasutame meie projekti juurutamiseks. Seda kasutab gitlab-runner tĂŒĂŒpiliste juurutuste ĂŒlesannete tĂ€itmiseks.

Siin on kÔik lihtne, loome uue dockerfiles/toolbox/Dockerfile sellise sisuga:

ALUSTADES 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

Nagu nÀete, installime selles pildis kÔik utiliidid, mida kasutasime meie rakenduse juurutamiseks. Me ei vaja siin ainult kubectl, kuid vÔib-olla soovite sellega mÀngida toru seadistamise etapis.

Samuti, et suhelda Kubernetesega ja seal juurutada, peame seadistama rolli gitlab-runner'i genereeritud pod'idele.

Selleks liigume gitlab-runner'i katalooge:

cd deploy/gitlab-runner

ja lisame uue komponendi 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,
      },
    ],
  },
]

Samuti kirjeldame uusi parameetreid failis environments/base.libsonnet, mis nĂŒĂŒd nĂ€eb vĂ€lja selline:

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

Pange tÀhele $.components.rbac.name viitab nimi komponendile rbac

Kontrollime, mis muutunud on:

qbec diff default

ja rakendame meie muudatused Kubernetesesse:

qbec apply default

Ärge unustage ka meie muudatusi git'i salvestada:

cd ../..
git add dockerfiles/toolbox
git commit -m "Lisa Dockerfile tööriistakasti jaoks"
git add deploy/gitlab-runner
git commit -m "Seadista gitlab-runner tööriistakasti kasutamiseks"

9. Meie esimene toru ja piltide ehitamine siltide jÀrgi

Loome projekti juurtas. .gitlab-ci.yml sellise sisuga:

.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

Pöörake tÀhelepanu, et me kasutame GIT_SUBMODULE_STRATEGY: normal neid tööde jaoks, kus on vajalik alamsubmodulite selge initsialiseerimine enne tÀitmist.

Ärge unustage meie muudatusi commitida:

git add .gitlab-ci.yml
git commit -m "Automatiseerige Docker'i koostamine"

Arvan, et seda vÔib julgelt nimetada versiooniks v0.0.1 ja mÀÀrata sildi:

git tag v0.0.1

Sildid mÀÀratakse iga kord, kui on vaja vabastada uus versioon. Docker'i piltidele mÀÀratud sildid seotakse Git'i siltidega. Iga puhverdamine uue sildiga kÀivitab selle sildiga seotud piltide koostamise.

TĂ€itke git push —tags, ja vaatame meie esimest pipelinet:

Esimese pipelini ekraanipilt

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

MÀrkimisvÀÀrne on see, et silte pidi olema hea Docker'i piltide koostamiseks, kuid ei sobi rakenduse paigaldamiseks Kubernetesesse. Kuna uusi silte vÔib mÀÀrata ka vanadele muudatustele, pÔhjustab nendele algatamine vana versiooni paigaldamist.

Selle probleemi lahendamiseks seotakse tavaliselt Docker'i piltide koostamine siltide, rakenduse paigaldamine aga harudega, mastermilles on kÔvasti mÀÀratud koostatud piltide versioonid. Just sellsisel juhul suudate algatada tagasiviimise lihtsa tagasivÔtmisega master-harule.

10. Paigaldamise automatiseerimine

Et Gitlab-runner suudaks meie saladusi deƥifreerida, peame eksportima repositooriumi vÔtme ja lisama selle meie CI keskkonnamuutujatesse:

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

Saadud stringi salvestame Gitlabi, selleks liikume meie projekti seadete juurde:
Seaded -> CI / CD -> Muutujad

Ja loome uue muutuja:

TĂŒĂŒp
Ava
VÀÀrtus
Kaitstud
Maskeeritud
Ulatus

Fail
GITCRYPT_KEY
<your string>
true (Ôppimise ajaks vÔib ka false)
true
KÔik keskkonnad

Lisatud muutuja ekraanipilt

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

NĂŒĂŒd uuendame meie .gitlab-ci.yml lisades sellele:

.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

Siin oleme kasutanud mitmeid uusi valikuid qbec'i jaoks:

  • —root some/app — vĂ”imaldab mÀÀrata konkreetse rakenduse kausta
  • —force:k8s-context __incluster__ — see on maagiline muutuja, mis ĂŒtleb, et deploy toimub samas klastris, kus gitlab-runner on kĂ€imas. See on vajalik, sest vastasel juhul pĂŒĂŒab qbec leida sobivat Kubernetes- serverit teie kubeconfigist
  • —wait — sunnib qbec'it ootama, kuni loodud ressursid saavad valmis olekusse Ready, ja alles siis lĂ”petatakse edukalt exit-koodiga.
  • —yes — lihtsalt keelab interaktiivse shelli Kas oled kindel? deploy'i ajal.

Ärge unustage meie muudatusi commitida:

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

Ja pÀrast git push nÀeme, kuidas meie rakendused on deployitud:

Teise pipeline'i ekraanipilt

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

11. Artefaktid ja ehitamine masterisse push'i ajal

Tavaliselt piisab eespool kirjeldatud sammudest peaaegu igasuguste mikroteenuste ehitamiseks ja tarnimiseks, kuid me ei soovi iga kord, kui peame saiti vĂ€rskendama, sildistada. SeetĂ”ttu valime dĂŒnaamilisema lĂ€henemise ja seadistame deploy'i digest'i alusel master haru.

Idee on lihtne: nĂŒĂŒd meie veebisait kujundatakse ĂŒmber iga kord, kui push'ime master, ja sonra automaatselt deploy'itakse Kubernetes'sse.

Uuendame nĂŒĂŒd neid kahte tööd meie .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"

Pange tĂ€hele, et oleme lisanud haru master aadressile refs the töö jaoks build_website ja nĂŒĂŒd kasutame $CI_COMMIT_REF_NAME asemel $CI_COMMIT_TAG, st eraldame end Git'i siltidest ja nĂŒĂŒd push'ime pildi, mille nimi on commit'i haru nimi, mis kĂ€ivitas pipeline'i. Tuleb mĂ€rkida, et see töötab ka siltide puhul, mis vĂ”imaldab meil sĂ€ilitada saidi versiooni kindla versiooniga docker-registry's.

Kui docker-tagi nimi uue saidi versioonile vÔib muutumatuna jÀÀda, peame ikkagi kirjeldama muudatusi Kuberneteses, vastasel juhul ei redeploy'ita rakendust uue pildiga, kuna muudatusi deploymendi manifestis ei mÀrgita.

Valik —vm:ext-str digest=»$DIGEST» qbeci jaoks — vĂ”imaldab vĂ€lise muutuja edastamist jsonnetis. Tahame, et meie rakenduse iga vĂ€ljalase redeploy'itaks klastris. Me ei saa nĂŒĂŒd kasutada nime, mis vĂ”ib jÀÀda muutumatuks, kuna peame siduma konkreetse pildiversiooniga ja kĂ€ivitama deployment'i, kui see muutub.

Siin aitab meid Kaniko suutlikkus salvestada pildi digesti faili (valik —digest-file)
SeejÀrel edastame ja loeme selle faili deploymendi hetkel.

Uuendame meie deploy/website/environments/base.libsonnet mis nĂ€eb nĂŒĂŒd vĂ€lja jĂ€rgmiselt:

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

Valmis, nĂŒĂŒd kĂ€ivitab iga commit master docker-pildi koostamise veebisait, seejĂ€rel selle deploy Kubernetese keskkonda.

Ärge unustage meie muudatusi commitida:

git add .
git commit -m "Konfigureeri dĂŒnaamiline koostamine"

Kontrollime, pÀrast git push peame nÀgema midagi sellist:

Pipelines'i ekraanipilt masterist

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

PÔhimÔtteliselt ei ole meil vaja gitlab-runnerit iga push'i korral redeploy'ida, kui selle konfiguratsioonis midagi ei muutu, parandame selle .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/**/*

changes aitab jÀlgida muudatusi deploy/gitlab-runner/ ja kÀivitab meie töö ainult siis, kui nii on

Ärge unustage meie muudatusi commitida:

git add .gitlab-ci.yml
git commit -m "VĂ€henda gitlab-runneri deploy'd"

git push, nii on parem:

Uuendatud pipelines'i ekraanipilt

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

12. DĂŒnaamilised keskkonnad

On aeg muuta meie pipelines dĂŒnaamilisteks keskkondadeks.

Esialgu uuendame töö build_website meie .gitlab-ci.yml, eemaldades sellest ploki only, mis sunnib Gitlab'i seda kÀivitama igal commit'il igas harus:

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/

SeejÀrel uuendame töö deploy_website, lisame sinna ploki keskkond:

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"

See vÔimaldab Gitlabil siduda töökoha prod keskkonnaga ja kuvada sellele Ôige lingi.

NĂŒĂŒd lisame veel kaks tööd:

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

Need kÀivitatakse, kui pushitakse mis tahes harudesse vÀlja arvatud master, ja need deployivad saidi eelvaate versiooni.

NĂ€eme uut vĂ”imalust qbec jaoks: —app-tag — see vĂ”imaldab mĂ€rgistada deployitud rakenduse versioone ja töötada ainult selle mĂ€rgise piires, Kuberneteses ressursside loomisel ja hĂ€vitamisel juhib qbec ainult neid.
Nii saame mitte luua eraldi keskkonda iga eelvaate jaoks, vaid lihtsalt kasutada sama.

Siin kasutame samuti qbec apply review, selle asemel qbec apply default — see on just see hetk, mil pĂŒĂŒame kirjeldada erinevusi meie keskkondade vahel (ĂŒlevaade ja vaikimisi):

Lisame ĂŒlevaate keskkonna deploy/website/qbec.yaml

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

Siis deklareerime selle 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

Ja kirjutame kohandatud parameetrid selle jaoks 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',
    },
  },
}

Vaadakem tÀhelepanelikumalt tööd stop_review, see on aktiveeritud haru kustutamisel ja et gitlab ei prooviks sellele checkouti teha, kasutatakse GIT_STRATEGY: none, hiljem kloonime master-okto ja kustutame arvustuse selle kaudu.
Veidi keeruline, kuid ma pole leidnud ilusamat viisi.
Alternatiivne variant vÔiks olla iga arvustuse suvandite eraldi nimelisse ruumi juurutamine, mille saab alati tÀielikult eemaldada.

Ärge unustage meie muudatusi commitida:

git add .
git commit -m "Luba automaatne arvustus"

git push, git checkout -b test, git push origin test, kontrollime:

Ekraanipilt loodud keskkondadest Gitlabis

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

Kas see töötab? — suurepĂ€rane, kustutame meie testimise haru: git checkout master, git push origin :test, kontrollime, et keskkonna kustutamise tööd töötasid ilma vigadeta.

Siin on kohe paslik tÀpsustada, et harude loomisega vÔib tegeleda iga arendaja projektis, ta vÔib ka muuta .gitlab-ci.yml faili ja saada juurdepÀÀsu salajastele muutujaile.
SeetÔttu on tungivalt soovitatav lubada nende kasutamine ainult kaitstud harude jaoks, nÀiteks master, vÔi luua eraldi muutuja komplekt iga keskkonna jaoks.

13. Arvustuse rakendused

Review Apps see on selline Gitlabi vÔimalus, mis vÔimaldab iga faili repositooriumis lisada nupu selle kiireks vaatamiseks juurutatud keskkonnas.

Selleks, et need nupud ilmuksid, tuleb luua fail .gitlab/route-map.yml ja kirjeldada seal kÔiki teepöördeid, meie puhul on see vÀga lihtne:

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

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

Ärge unustage meie muudatusi commitida:

git add .gitlab/
git commit -m "Luba arvustuse rakendused"

git push, ja kontrollime:

Ekraanipilt Review App nupust

Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

Töö on tehtud!

Projekti lÀhtekoodid:

AitÀh tÀhelepanu eest, loodan et see teile meeldis Katsetame uusi tööriistu Kubernetes'i kokkupanemiseks ja automaatimiseks

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster