Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Hei! Viime aikoina on julkaistu monia hienoja automaatiotyökaluja sekä Docker-kuvien rakentamiseen että Kubernetesin käyttöönottoon. Tältä osin päätin leikkiä GitLabin kanssa, tutkia perusteellisesti sen ominaisuuksia ja tietysti perustaa putkilinjan.

Tämä työ on saanut inspiraationsa verkkosivustosta kubernetes.io, joka on luotu lähdekoodeja automaattisesti, ja jokaiselle lähetetylle poolipyynnölle robotti luo automaattisesti esikatseluversion sivustosta muutoksineen ja tarjoaa linkin katselua varten.

Yritin rakentaa samanlaisen prosessin tyhjästä, mutta se rakentui kokonaan Gitlab CI:lle ja ilmaisille työkaluille, joita olen tottunut käyttämään sovellusten asentamiseen Kubernetesiin. Tänään vihdoin kerron sinulle lisää heistä.

Artikkelissa käsitellään työkaluja, kuten:
Hugo, qbec, kaniko, git-crypt и GitLab CI dynaamisten ympäristöjen luomisen kanssa.

Sisältö

  1. Tapaa Hugo
  2. Valmistellaan Docker-tiedostoa
  3. Kanikoon tutustuminen
  4. qbeciin tutustuminen
  5. Kokeillaan Gitlab-runneria Kubernetes-executorin kanssa
  6. Helm-kaavioiden käyttöönotto qbec:llä
  7. Esittelyssä git-crypt
  8. Työkalulaatikon kuvan luominen
  9. Ensimmäinen putkistomme ja kuvien kokoaminen tunnisteiden mukaan
  10. Käyttöönoton automatisointi
  11. Artefaktit ja kokoonpano masteriin työnnettäessä
  12. Dynaamiset ympäristöt
  13. Tarkista sovellukset

1. Hugoon tutustuminen

Esimerkkinä projektistamme yritämme luoda Hugolle rakennetun dokumentaation julkaisusivuston. Hugo on staattisen sisällön luoja.

Niille, jotka eivät tunne staattisia generaattoreita, kerron niistä hieman lisää. Toisin kuin perinteiset verkkosivustomoottorit, joissa on tietokanta ja PHP, jotka käyttäjän pyynnöstä luovat sivuja lennossa, staattiset generaattorit on suunniteltu hieman eri tavalla. Niiden avulla voit ottaa lähteet, yleensä joukon tiedostoja Markdown-merkinnöissä ja teemamalleissa, ja koota ne sitten kokonaan valmiiksi verkkosivustoksi.

Tämä tarkoittaa, että saat hakemistorakenteen ja joukon luotuja HTML-tiedostoja, jotka voit yksinkertaisesti ladata mihin tahansa halvaan hosting-palveluun ja saada toimivan verkkosivuston.

Voit asentaa Hugon paikallisesti ja kokeilla sitä:

Uuden sivuston alustaminen:

hugo new site docs.example.org

Ja samalla git-arkisto:

cd docs.example.org
git init

Sivustomme on toistaiseksi koskematon ja jotta siihen ilmestyisi jotain, meidän on ensin yhdistettävä teema; teema on vain joukko malleja ja määritettyjä sääntöjä, joiden mukaan sivustomme luodaan.

Käytämme teemana Oppia, joka mielestäni sopii täydellisesti dokumentaatiosivustolle.

Haluan kiinnittää erityistä huomiota siihen, että meidän ei tarvitse tallentaa teematiedostoja projektiarkistoon, vaan voimme yksinkertaisesti yhdistää ne käyttämällä git-alimoduuli:

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

Siten arkistossamme tulee olemaan vain suoraan projektiimme liittyviä tiedostoja ja yhdistetty teema säilyy linkkinä tiettyyn arkistoon ja sitoutumiseen siinä, eli se voidaan aina noutaa alkuperäisestä lähteestä eikä pelätä yhteensopimattomia muutoksia.

Korjataan konfiguraatio config.toml:

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

Jo tässä vaiheessa voit ajaa:

hugo server

Ja osoitteessa http://localhost:1313/ Tarkista äskettäin luotu verkkosivustomme, kaikki hakemistoon tehdyt muutokset päivittävät automaattisesti avoimen sivun selaimessa, erittäin kätevää!

Yritetään luoda kansilehti content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Kuvakaappaus äskettäin luodusta sivusta

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Luo sivusto suorittamalla:

hugo

Hakemiston sisältö julkinen/ ja tulee olemaan verkkosivustosi.
Kyllä, muuten, lisätään se heti .gitignore:

echo /public > .gitignore

Älä unohda tehdä muutoksiamme:

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

2. Docker-tiedoston valmistelu

On aika määritellä arkistomme rakenne. Käytän yleensä jotain tällaista:

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

  • dockerfiles/ — sisältää hakemistoja, joissa on Docker-tiedostoja ja kaikkea mitä tarvitaan Docker-kuvien rakentamiseen.
  • ottaa käyttöön/ - sisältää hakemistoja sovelluksiemme käyttöönottoa varten Kubernetesiin

Näin ollen luomme ensimmäisen Docker-tiedoston polun varrella 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" ]

Kuten näet, Dockerfile sisältää kaksi FROM, tätä mahdollisuutta kutsutaan monivaiheinen rakennus ja voit jättää kaiken tarpeettoman pois lopullisesta telakointikuvasta.
Siten lopullinen kuva sisältää vain tummahttpd (kevyt HTTP-palvelin) ja julkinen/ — staattisesti luodun verkkosivustomme sisältö.

Älä unohda tehdä muutoksiamme:

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

3. Kanikoon tutustuminen

Docker-kuvanrakentajana päätin käyttää kaniko, koska sen toiminta ei vaadi Docker-daemonia, ja itse koonti voidaan suorittaa millä tahansa koneella ja välimuisti voidaan tallentaa suoraan rekisteriin, jolloin ei tarvita täysimittaista pysyvää tallennustilaa.

Luo kuva ajamalla säilön kanssa kanikon toimeenpanija ja välitä se nykyinen rakennuskonteksti; tämä voidaan tehdä myös paikallisesti Dockerin kautta:

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

jossa registry.gitlab.com/kvaps/docs.example.org/website - Docker-kuvasi nimi; rakentamisen jälkeen se käynnistetään automaattisesti telakointiaseman rekisteriin.

Parametri --kätkö antaa sinun tallentaa tasot välimuistiin Docker-rekisterissä; annetussa esimerkissä ne tallennetaan registry.gitlab.com/kvaps/docs.example.org/website/cache, mutta voit määrittää toisen polun parametrilla --cache-repo.

Näyttökuva Docker-rekisteristä

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

4. qbeciin tutustuminen

Qbec on käyttöönottotyökalu, jonka avulla voit kuvata sovellusluettelosi deklaratiivisesti ja ottaa ne käyttöön Kubernetesissa. Jsonnetin käyttäminen pääsyntaksina mahdollistaa huomattavasti useiden ympäristöjen erojen kuvauksen yksinkertaistamisen ja eliminoi myös koodin toiston lähes kokonaan.

Tämä voi olla erityisen totta tapauksissa, joissa sinun on otettava sovellus käyttöön useille klustereille, joilla on eri parametrit, ja haluat kuvata ne deklaratiivisesti Gitissä.

Qbec antaa sinun myös renderoida Helm-kaavioita antamalla niille tarvittavat parametrit ja sitten käyttää niitä samalla tavalla kuin tavallisia manifesteja, mukaan lukien voit soveltaa niihin erilaisia ​​mutaatioita, ja tämä puolestaan ​​antaa sinun päästä eroon tarpeesta käytä ChartMuseumia. Eli voit tallentaa ja hahmontaa kaavioita suoraan gitistä, minne ne kuuluvat.

Kuten aiemmin sanoin, tallennamme kaikki käyttöönotot hakemistoon ottaa käyttöön/:

mkdir deploy
cd deploy

Alustetaan ensimmäinen sovelluksemme:

qbec init website
cd website

Nyt sovelluksemme rakenne näyttää tältä:

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

katsotaan tiedostoa qbec.yaml:

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

Täällä meitä kiinnostaa ensisijaisesti spec.environments, qbec on jo luonut meille oletusympäristön ja ottanut palvelimen osoitteen sekä nimitilan nykyisestä kubeconfig-tiedostostamme.
Nyt käyttöönoton yhteydessä oletusarvo ympäristössä, qbec ottaa aina käyttöön vain määritettyyn Kubernetes-klusteriin ja määritettyyn nimiavaruuteen, eli sinun ei enää tarvitse vaihtaa kontekstien ja nimiavaruuksien välillä käyttöönoton suorittamiseksi.
Tarvittaessa voit aina päivittää tämän tiedoston asetukset.

Kaikki ympäristösi on kuvattu kohdassa qbec.yaml, ja tiedostossa params.libsonnet, jossa lukee, mistä saa parametrit niille.

Seuraavaksi näemme kaksi hakemistoa:

  • komponentit / — kaikki sovelluksemme manifestit tallennetaan tänne; ne voidaan kuvata sekä jsonnet- että tavallisissa yaml-tiedostoissa
  • ympäristöt/ — Tässä kuvataan kaikki ympäristöjemme muuttujat (parametrit).

Oletuksena meillä on kaksi tiedostoa:

  • Environments/base.libsonnet - Se sisältää yhteiset parametrit kaikille ympäristöille
  • Environments/default.libsonnet — sisältää ympäristölle ohitettuja parametreja oletusarvo

avataan Environments/base.libsonnet ja lisää parametrit ensimmäiselle komponentillemme:

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

Luodaan myös ensimmäinen komponenttimme komponentit/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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

Tässä tiedostossa kuvailimme kolme Kubernetes-yksikköä kerralla, nämä ovat: käyttöönoton, Palvelu и Sisääntulo. Jos haluaisimme, voisimme laittaa ne eri komponentteihin, mutta tässä vaiheessa yksi riittää meille.

syntaksi jsonnet on hyvin samanlainen kuin tavallinen json, periaatteessa tavallinen json on jo kelvollinen jsonnet, joten aluksi voi olla helpompaa käyttää verkkopalveluita, kuten yaml2json muuntaa tavallinen yaml jsoniksi, tai jos komponentit eivät sisällä muuttujia, ne voidaan kuvata tavallisen yamlin muodossa.

Kun työskentelet jsonnet Suosittelen lämpimästi lisäosan asentamista editoriin

Esimerkiksi vimille on lisäosa vim-jsonnet, joka ottaa syntaksin korostuksen käyttöön ja suorittaa sen automaattisesti jsonnet fmt aina, kun tallennat (vaatii jsonnet-asennuksen).

Kaikki on valmis, nyt voimme aloittaa käyttöönoton:

Katsotaan, mitä meillä on, ajamalla:

qbec show default

Tulosteessa näet renderoidut yaml-luettelot, joita sovelletaan oletusklusteriin.

Hienoa, hae nyt:

qbec apply default

Tulosteessa näet aina mitä klusterissasi tehdään, qbec pyytää sinua hyväksymään muutokset kirjoittamalla y voit vahvistaa aikeesi.

Sovelluksemme on valmis ja otettu käyttöön!

Jos teet muutoksia, voit aina tehdä:

qbec diff default

nähdäksesi, kuinka nämä muutokset vaikuttavat nykyiseen käyttöön

Älä unohda tehdä muutoksiamme:

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

5. Gitlab-runnerin kokeilu Kubernetes-executorin kanssa

Viime aikoihin asti käytin vain tavallista gitlab-runner esivalmistetulla koneella (LXC-säiliö), jossa on kuori tai telakointikone. Aluksi meillä oli useita tällaisia ​​juoksijoita maailmanlaajuisesti määriteltynä gitlabissamme. He keräsivät telakointikuvia kaikkiin projekteihin.

Mutta kuten käytäntö on osoittanut, tämä vaihtoehto ei ole ihanteellisin sekä käytännöllisyyden että turvallisuuden kannalta. On paljon parempi ja ideologisesti oikeampi ottaa käyttöön erilliset juoksijat jokaiseen projektiin tai jopa jokaiseen ympäristöön.

Onneksi tämä ei ole ollenkaan ongelma, koska nyt otamme käyttöön gitlab-runner suoraan osana projektiamme aivan Kubernetesissä.

Gitlab tarjoaa valmiin ruorikaavion gitlab-runnerin käyttöönottoa varten Kubernetesiin. Joten sinun tarvitsee vain ottaa selvää rekisteröintitunnus projektiamme varten Asetukset -> CI / CD -> Runners ja anna se ruoriin:

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

Missä:

  • https://gitlab.com — Gitlab-palvelimesi osoite.
  • yga8y-jdCusVDn_t4Wxc — rekisteröintitunnus projektillesi.
  • rbac.create=true — tarjoaa juoksijalle tarvittavan määrän oikeuksia, jotta hän voi luoda podeja tehtäviemme suorittamiseksi kubernetes-executorin avulla.

Jos kaikki on tehty oikein, sinun pitäisi nähdä rekisteröitynyt juoksija osiossa Runners, projektiasetuksissa.

Kuvakaappaus lisätystä juoksijasta

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Onko se niin yksinkertaista? - Kyllä, se on niin yksinkertaista! Ei enää hässäkkää juoksijoiden manuaalisen rekisteröinnin kanssa, tästä lähtien juoksijat luodaan ja tuhotaan automaattisesti.

6. Ota ruorikaaviot käyttöön QBEC:n avulla

Koska päätimme harkita gitlab-runner osa projektiamme, on aika kuvata se Git-varastossamme.

Voisimme kuvata sitä erilliseksi komponentiksi verkkosivusto, mutta tulevaisuudessa aiomme ottaa käyttöön erilaisia ​​kopioita verkkosivusto hyvin usein, toisin kuin gitlab-runner, joka otetaan käyttöön vain kerran Kubernetes-klusteria kohden. Joten alustetaan sille erillinen sovellus:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Tällä kertaa emme kuvaa Kubernetes-kokonaisuuksia manuaalisesti, vaan otamme valmiin Helm-kaavion. Yksi qbecin eduista on kyky renderoida Helm-kaavioita suoraan Git-arkistosta.

Yhdistetään se git-alimoduulilla:

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

Nyt hakemisto myyjä/gitlab-runner Meillä on arkisto, jossa on kaavio gitlab-runnerille.

Samalla tavalla voit yhdistää muita arkistot, esimerkiksi koko arkiston virallisiin kaavioihin https://github.com/helm/charts

Kuvataan komponentti komponentit/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,
  }
)

Ensimmäinen argumentti expandHelmTemplate siirrämme sitten polun kaavioon parametrit.arvot, jonka otamme ympäristöparametreista, sitten tulee objektin kanssa

  • nimimalli - julkaisun nimi
  • nimiavaruus — nimiavaruus siirretty ruoriin
  • Tämä tiedosto — pakollinen parametri, joka välittää polun nykyiseen tiedostoon
  • jaaritteleva - näyttää komennon ruorin malli kaikki argumentit kaaviota hahmonnettaessa

Kuvataan nyt komponenttimme parametrit 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,
      },
    },
  },
}

Kiinnitä huomiota runnerRegistrationToken otamme ulkoisesta tiedostosta Secrets/base.libsonnet, luodaan se:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Katsotaan toimiiko kaikki:

qbec show default

Jos kaikki on kunnossa, voimme poistaa aiemmin käyttöönotetun julkaisumme Helmin kautta:

helm uninstall gitlab-runner

ja ota se käyttöön samalla tavalla, mutta qbecin kautta:

qbec apply default

7. Esittelyssä git-crypt

Git-crypt on työkalu, jonka avulla voit määrittää läpinäkyvän salauksen arkistollesi.

Tällä hetkellä gitlab-runnerin hakemistorakenne näyttää tältä:

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

Mutta salaisuuksien tallentaminen Gitissä ei ole turvallista, eihän? Joten meidän on salattava ne kunnolla.

Yleensä yhden muuttujan vuoksi tämä ei aina ole järkevää. Voit siirtää salaisuuksia qbec ja CI-järjestelmäsi ympäristömuuttujien kautta.
Mutta on syytä huomata, että on myös monimutkaisempia projekteja, jotka voivat sisältää paljon enemmän salaisuuksia, joiden siirtäminen ympäristömuuttujien kautta on erittäin vaikeaa.

Lisäksi tässä tapauksessa en voisi kertoa sinulle niin upeasta työkalusta kuin git-crypt.

git-crypt Se on myös kätevä siinä mielessä, että sen avulla voit tallentaa koko salaisuuksien historian sekä vertailla, yhdistää ja ratkaista konflikteja samalla tavalla kuin olemme tottuneet tekemään Gitin tapauksessa.

Ensimmäinen asia asennuksen jälkeen git-crypt meidän on luotava avaimet arkistollemme:

git crypt init

Jos sinulla on PGP-avain, voit heti lisätä itsesi tämän projektin yhteistyökumppaniksi:

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

Tällä tavalla voit aina purkaa tämän arkiston salauksen yksityisellä avaimellasi.

Jos sinulla ei ole PGP-avainta etkä odota sitä, voit mennä toiseen suuntaan ja viedä projektiavaimen:

git crypt export-key /path/to/keyfile

Siten kuka tahansa, jolla on vienti avaintiedosto voi purkaa arkistosi salauksen.

On aika avata ensimmäinen salaisuutemme.
Haluan muistuttaa, että olemme edelleen hakemistossa käyttöönotto/gitlab-runner/, jossa meillä on hakemisto salaisuudet/, salataan kaikki siinä olevat tiedostot, tätä varten luomme tiedoston salaisuudet/.gitattributes seuraavalla sisällöllä:

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

Kuten sisällöstä näkyy, kaikki tiedostot on peitetty * ajetaan läpi git-crypt, paitsi suurin osa .gitattributes

Voimme tarkistaa tämän suorittamalla:

git crypt status -e

Tulos on luettelo kaikista arkiston tiedostoista, joiden salaus on käytössä

Siinä kaikki, nyt voimme turvallisesti tehdä muutokset:

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

Voit estää arkiston suorittamalla:

git crypt lock

ja välittömästi kaikki salatut tiedostot muuttuvat binäärisiksi, niitä on mahdotonta lukea.
Pura arkiston salaus suorittamalla:

git crypt unlock

8. Luo työkalupakin kuva

Työkalulaatikon kuva on kuva, jossa on kaikki työkalut, joita käytämme projektimme käyttöönotossa. Gitlab-apuohjelma käyttää sitä tyypillisten käyttöönottotehtävien suorittamiseen.

Täällä kaikki on yksinkertaista, luodaan uusi Dockerfiles/Toolbox/Dockerfile seuraavalla sisällöllä:

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

Kuten näet, tässä kuvassa asennamme kaikki apuohjelmat, joita käytimme sovelluksemme käyttöönotossa. Emme tarvitse sitä täällä, ellemme kubectl, mutta saatat haluta leikkiä sillä liukuhihnan asennusvaiheessa.

Lisäksi, jotta voimme kommunikoida Kubernetesin kanssa ja ottaa sen käyttöön, meidän on määritettävä rooli gitlab-runnerin luomille podille.

Tätä varten mennään gitlab-runnerin hakemistoon:

cd deploy/gitlab-runner

ja lisää uusi komponentti komponentit/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,
      },
    ],
  },
]

Kuvaamme myös uudet parametrit Environments/base.libsonnet, joka näyttää nyt tältä:

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

Kiinnitä huomiota $.components.rbac.name viittaa nimi komponentille rbac

Katsotaan mikä on muuttunut:

qbec diff default

ja ota muutokset käyttöön Kubernetesiin:

qbec apply default

Älä myöskään unohda sitoa muutoksiamme gitiin:

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. Ensimmäinen putkistomme ja kuvien kokoaminen tunnisteiden mukaan

Projektin ytimessä luomme .gitlab-ci.yml seuraavalla sisällöllä:

.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

Huomaa, että käytämme GIT_SUBMODULE_STRATEGY: normaali niille töille, joissa alimoduulit on ensin alustettava ennen suorittamista.

Älä unohda tehdä muutoksiamme:

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

Uskon, että voimme turvallisesti kutsua tätä versioksi v0.0.1 ja lisää tagi:

git tag v0.0.1

Lisäämme tunnisteita aina, kun meidän on julkaistava uusi versio. Docker-kuvien tunnisteet sidotaan Git-tageihin. Jokainen uuden tunnisteen painallus alustaa kuvien rakentamisen tällä tunnisteella.

Tehdään se git push --tags, ja katsotaanpa ensimmäistä putkistoamme:

Kuvakaappaus ensimmäisestä putkistosta

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Kannattaa kiinnittää huomio siihen, että tagien kokoonpano soveltuu telakointikuvien rakentamiseen, mutta ei sovellu sovelluksen käyttöönottoon Kubernetesiin. Koska uusia tunnisteita voidaan määrittää myös vanhoille toimituksille, tässä tapauksessa niiden liukuhihnan alustaminen johtaa vanhan version käyttöönottoon.

Tämän ongelman ratkaisemiseksi yleensä Docker-kuvien rakentaminen sidotaan tunnisteisiin ja sovelluksen käyttöönotto haaraan mestari, jossa kerättyjen kuvien versiot on koodattu. Täällä voit alustaa palautuksen yksinkertaisella palautustoiminnolla mestari-oksat.

10. Käyttöönoton automatisointi

Jotta Gitlab-runner voi purkaa salaisuuksiamme, meidän on vietävä arkiston avain ja lisättävä se CI-ympäristömuuttujiimme:

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

Tallennamme tuloksena olevan rivin Gitlabiin; tätä varten siirrymme projektiasetuksiin:
Asetukset -> CI / CD -> Muuttujat

Ja luodaan uusi muuttuja:

Tyyppi
avain
Arvo
Suojattu
naamioitu
Laajuus

File
GITCRYPT_KEY
<your string>
true (koulutuksen aikana voit false)
true
All environments

Kuvakaappaus lisätystä muuttujasta

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Päivitetään nyt omaa .gitlab-ci.yml lisäämällä siihen:

.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

Tässä olemme ottaneet käyttöön useita uusia vaihtoehtoja qbec:lle:

  • --root some/app — voit määrittää tietyn sovelluksen hakemiston
  • --force:k8s-context __incluster__ - Tämä on maaginen muuttuja, joka sanoo, että käyttöönotto tapahtuu samassa klusterissa, jossa gtilab-runner on käynnissä. Tämä on välttämätöntä, koska muuten qbec yrittää löytää sopivan Kubernetes-palvelimen kubeconfigistasi
  • --odota — pakottaa qbecin odottamaan, kunnes sen luomat resurssit siirtyvät Valmis-tilaan ja vasta sitten poistumaan onnistuneella poistumiskoodilla.
  • -Joo - yksinkertaisesti poistaa interaktiivisen kuoren käytöstä Oletko varma? käyttöönoton yhteydessä.

Älä unohda tehdä muutoksiamme:

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

Ja sen jälkeen git push näemme kuinka sovelluksemme on otettu käyttöön:

Kuvakaappaus toisesta putkesta

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

11. Artefaktit ja kokoonpano, kun työnnetään masteriin

Yleensä yllä kuvatut vaiheet riittävät lähes minkä tahansa mikropalvelun rakentamiseen ja toimittamiseen, mutta emme halua lisätä tunnistetta aina, kun meidän on päivitettävä sivusto. Siksi valitsemme dynaamisemman reitin ja määritämme tiivistelmän käyttöönoton päähaarassa.

Idea on yksinkertainen: nyt kuva meistä verkkosivusto rakennetaan uudelleen joka kerta kun työnnät sisään mestarija ota sitten automaattisesti käyttöön Kubernetes.

Päivitetään nämä kaksi työpaikkaamme .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"

Huomaa, että olemme lisänneet ketjun mestari к refs työpaikkoja varten build_website ja käytämme nyt $CI_COMMIT_REF_NAME sen sijasta $CI_COMMIT_TAG, eli meidät on irrotettu tageista Gitissä ja nyt työnnämme kuvan, jossa on sen toimitushaaran nimi, joka alustasi liukuhihnan. On syytä huomata, että tämä toimii myös tunnisteiden kanssa, mikä antaa meille mahdollisuuden tallentaa tilannekuvia sivustosta tietyllä versiolla Docker-rekisteriin.

Kun sivuston uuden version Docker-tunnisteen nimi voi olla muuttumaton, meidän on silti kuvattava muutokset Kubernetesiin, muuten se ei yksinkertaisesti ota sovellusta uudelleen käyttöön uudesta kuvasta, koska se ei huomaa muutoksia käyttöönottoluettelo.

Vaihtoehto —vm:ext-str digest=”$DIGEST” for qbec - voit välittää ulkoisen muuttujan jsonnetille. Haluamme, että se sijoitetaan uudelleen klusteriin jokaisen sovelluksemme julkaisun yhteydessä. Emme voi enää käyttää tunnisteen nimeä, jota ei voi nyt muuttaa, koska meidän täytyy olla sidottu tiettyyn kuvan versioon ja käynnistää käyttöönotto, kun se muuttuu.

Tässä meitä auttaa Kanikon kyky tallentaa tiivistelmäkuva tiedostoon (valinnainen --Digest-tiedosto)
Sitten siirrämme tämän tiedoston ja luemme sen käyttöönoton yhteydessä.

Päivitetään meidän parametrit deploy/website/environments/base.libsonnet joka näyttää nyt tältä:

{
  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, nyt kaikki sitoumukset mestari alustaa Docker-kuvan koontiversion verkkosivusto, ja ota se sitten käyttöön Kubernetesissa.

Älä unohda tehdä muutoksiamme:

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

Tarkistamme myöhemmin git push meidän pitäisi nähdä jotain tällaista:

Kuvakaappaus putkistosta masterille

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Periaatteessa meidän ei tarvitse ottaa gitlab-runneria uudelleen käyttöön jokaisella painalluksella, ellei sen kokoonpanossa ole tietenkään muuttunut, korjataan se .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/**/*

muutokset avulla voit seurata muutoksia käyttöönotto/gitlab-runner/ ja käynnistää työmme vain, jos niitä on

Älä unohda tehdä muutoksiamme:

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

git push, tuo on parempi:

Kuvakaappaus päivitetystä putkistosta

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

12. Dynaamiset ympäristöt

On aika monipuolistaa tuotantoketjuamme dynaamisilla ympäristöillä.

Ensin päivitetään työ build_website meidän .gitlab-ci.yml, poistamalla lohkon siitä vain, joka pakottaa Gitlabin käynnistämään sen missä tahansa sitoumuksessa mihin tahansa haaraan:

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/

Päivitä sitten työ käyttöönotto_verkkosivusto, lisää sinne lohko ympäristö:

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"

Tämä antaa Gitlabille mahdollisuuden yhdistää työn tuot ympäristöön ja näytä oikea linkki siihen.

Lisätään nyt vielä kaksi työpaikkaa:

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

Ne käynnistetään, kun ne lähetetään kaikille sivuhaaroille, paitsi pääkoneelle, ja ne ottavat käyttöön sivuston esikatseluversion.

Näemme uuden vaihtoehdon qbec:lle: --sovellus-tunniste — sen avulla voit merkitä sovelluksen käyttöönotetut versiot ja työskennellä vain tämän tunnisteen sisällä; kun luot ja tuhoat resursseja Kubernetesissa, qbec toimii vain niiden kanssa.
Näin emme voi luoda jokaiselle arvostelulle erillistä ympäristöä, vaan käyttää samaa ympäristöä uudelleen.

Täällä myös käytetään qbec soveltaa tarkistustasen sijasta qbec käytä oletusarvoa - Tämä on juuri se hetki, jolloin yritämme kuvata ympäristöjemme eroja (tarkistus ja oletus):

lisätä arviot ympäristö sisään deploy/website/qbec.yaml

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

Ilmoitamme sen sitten 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 kirjoita sen mukautetut parametrit muistiin 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',
    },
  },
}

Katsotaanpa myös työpaikkaa tarkemmin stop_review, se laukeaa kun haara poistetaan ja jotta gitlab ei yritä kassata sitä käytetään GIT_STRATEGY: ei mitään, kloonaamme myöhemmin mestari-haara ja poista arvostelu sen kautta.
Se on hieman hämmentävää, mutta en ole vielä löytänyt kauniimpaa tapaa.
Vaihtoehtoinen vaihtoehto olisi sijoittaa jokainen arvostelu hotellin nimiavaruuteen, joka voidaan aina purkaa kokonaan.

Älä unohda tehdä muutoksiamme:

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

git push, git checkout -b testi, git push -alkuperätesti, tarkistaa:

Kuvakaappaus luoduista ympäristöistä Gitlabissa

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Kaikki toimii? - hienoa, poista testihaaramme: git checkout master, git push origin :test, tarkistamme, että ympäristön poistotyöt toimivat virheettömästi.

Haluaisin tässä heti selventää, että jokainen projektin kehittäjä voi luoda haaroja, hän voi myös muuttaa .gitlab-ci.yml tiedostoa ja käyttää salaisia ​​muuttujia.
Siksi on erittäin suositeltavaa sallia niiden käyttö vain suojatuissa oksissa, esim mestaritai luo erillinen muuttujajoukko kullekin ympäristölle.

13. Tarkista sovellukset

Tarkista sovellukset Tämä on GitLab-ominaisuus, jonka avulla voit lisätä painikkeen jokaiselle arkiston tiedostolle nähdäksesi sen nopeasti käyttöönotetussa ympäristössä.

Jotta nämä painikkeet tulevat näkyviin, sinun on luotava tiedosto .gitlab/route-map.yml ja kuvaile kaikki polun muunnokset siinä; meidän tapauksessamme se on hyvin yksinkertaista:

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

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

Älä unohda tehdä muutoksiamme:

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

git pushja tarkista:

Kuvakaappaus Review App -painikkeesta

Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Työ on tehty!

Hankkeen lähteet:

Kiitos huomiosta, toivottavasti pidit siitä Kokeile uusia työkaluja käyttöönoton rakentamiseen ja automatisoimiseen Kubernetesissa

Lähde: will.com

Lisää kommentti