Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Hallo! Baie oulike outomatiseringsinstrumente is die afgelope tyd vrygestel vir beide die bou van Docker-beelde en die implementering na Kubernetes. In hierdie verband het ek besluit om met Gitlab rond te speel, hoe om sy vermoëns te bestudeer en natuurlik 'n pyplyn op te stel.

Hierdie webwerf is geïnspireer deur kubernetes.io, wat gegenereer word uit bronkodes outomaties, en vir elke trekversoek wat gestuur word, genereer die robot outomaties 'n voorskouweergawe van die webwerf met jou veranderinge en verskaf 'n skakel vir besigtiging.

Ek het probeer om 'n soortgelyke proses van nuuts af te bou, maar volledig gebou op Gitlab CI en gratis gereedskap wat ek gebruik het om toepassings na Kubernetes te ontplooi. Vandag sal ek jou uiteindelik meer oor hulle vertel.

Die artikel sal gereedskap dek soos:
Hugo, qbec, kaniko, git-kript и GitLab CI met die skep van dinamiese omgewings.

Inhoud

  1. Hugo leer ken
  2. Berei die Dockerfile voor
  3. Kaniko leer ken
  4. Inleiding tot qbec
  5. Probeer Gitlab-runner met Kubernetes-uitvoerder
  6. Ontplooi Helm-kaarte met qbec
  7. Inleiding tot git-crypt
  8. Skep 'n toolbox-prent
  9. Ons eerste pyplyn en samestelling van beelde deur etikette
  10. Ontplooi outomatisering
  11. Artefakte en samestelling wanneer gedruk word om te bemeester
  12. Dinamiese omgewings
  13. Hersien toepassings

1. Om Hugo te leer ken

As 'n voorbeeld van ons projek, sal ons probeer om 'n dokumentasie-publiseringswerf te skep wat op Hugo gebou is. Hugo is 'n statiese inhoudgenerator.

Vir diegene wat nie vertroud is met statiese kragopwekkers nie, sal ek jou 'n bietjie meer daaroor vertel. Anders as gewone werf-enjins met 'n databasis en 'n soort php, wat, wanneer dit deur die gebruiker versoek word, bladsye op die vlug genereer, is statiese kragopwekkers 'n bietjie anders gerangskik. Hulle laat jou toe om die bronkode te neem, gewoonlik 'n stel lêers in Markdown-opmaak en temasjablone, en dan saam te stel in 'n heeltemal voltooide webwerf.

Dit wil sê, by die uitvoer sal jy 'n gidsstruktuur en 'n stel gegenereerde html-lêers kry wat jy eenvoudig kan oplaai na enige goedkoop hosting en 'n werkende webwerf kry.

Jy kan Hugo plaaslik installeer en dit uitprobeer:

Inisialiseer die nuwe webwerf:

hugo new site docs.example.org

En terselfdertyd die git-bewaarplek:

cd docs.example.org
git init

Tot dusver is ons webwerf ongerept en om iets daarop te laat verskyn, moet ons eers 'n tema koppel, 'n tema is net 'n stel sjablone en stel reëls waarvolgens ons webwerf gegenereer word.

As 'n tema wat ons sal gebruik Leer, wat na my mening die beste geskik is vir 'n webwerf met dokumentasie.

Ek wil graag spesiale aandag gee aan die feit dat ons nie die temalêers in die bewaarplek van ons projek hoef te stoor nie, maar ons kan dit eenvoudig verbind met git submodule:

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

Dus, slegs lêers wat direk met ons projek verband hou, sal in ons bewaarplek wees, en die gekoppelde tema sal bly as 'n skakel na 'n spesifieke bewaarplek en 'n commit daarin, dit wil sê, dit kan altyd uit die oorspronklike bron getrek word en nie bang wees nie van onversoenbare veranderinge.

Kom ons maak die konfigurasie reg config.toml:

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

Reeds op hierdie stadium kan jy hardloop:

hugo server

En by die adres http://localhost:1313/ kyk na ons nuutgeskepte webwerf, alle veranderinge wat in die gids gemaak word, werk outomaties die oop bladsy in die blaaier op, baie gerieflik!

Kom ons probeer om 'n titelbladsy in te skep inhoud/_indeks.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Skermskoot van die nuutgeskepte bladsy

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Om 'n webwerf te genereer, hardloop net:

hugo

Gids inhoud publiek/ en sal jou webwerf wees.
Ja, terloops, kom ons bring dit dadelik in .gitignore:

echo /public > .gitignore

Moenie vergeet om ons veranderinge toe te pas nie:

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

2. Berei die Docker-lêer voor

Dit is tyd om die struktuur van ons bewaarplek te definieer. Gewoonlik gebruik ek iets soos:

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

  • dockerfiles/ - bevat gidse met Dockerfiles en alles wat nodig is om ons docker-beelde te bou.
  • ontplooi/ - bevat gidse vir die implementering van ons toepassings in Kubernetes

Ons sal dus ons eerste Dockerfile langs die pad skep dockerfiles/webwerf/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" ]

Soos u kan sien, bevat die Dockerfile twee UIT, word hierdie moontlikheid genoem multi-stadium bou en laat jou toe om alles wat onnodig is uit te sluit van die finale docker-beeld.
Dus sal die finale prent slegs bevat donkerhttpd (liggewig HTTP-bediener) en publiek/ - die inhoud van ons staties gegenereerde webwerf.

Moenie vergeet om ons veranderinge toe te pas nie:

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

3. Om kaniko te leer ken

As 'n bouer van docker-beelde het ek besluit om te gebruik kaniko, aangesien dit nie 'n docker-demoon benodig om te werk nie, en die samestelling self kan op enige masjien uitgevoer word en die kas direk in die register stoor, en sodoende ontslae raak van die behoefte om 'n volwaardige aanhoudende berging te hê.

Om die beeld te bou, hardloop net die houer mee kaniko eksekuteur en gee die huidige boukonteks daaraan, jy kan dit plaaslik doen, via 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

waar registry.gitlab.com/kvaps/docs.example.org/webwerf - die naam van jou docker-beeld, nadat dit gebou is, sal dit outomaties in die docker-register bekendgestel word.

Parameter --kas laat jou toe om lae in die docker-register te kas, vir die gegewe voorbeeld sal hulle gestoor word registry.gitlab.com/kvaps/docs.example.org/website/cache, maar jy kan 'n ander pad met die parameter spesifiseer --kas-repo.

Skermskoot van docker-register

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

4. Inleiding tot qbec

Qbec is 'n ontplooiingsinstrument wat jou in staat stel om jou toepassingsmanifeste verklarend te beskryf en dit na Kubernetes te ontplooi. Die gebruik van Jsonnet as die hoofsintaksis maak dit baie maklik om die verskille vir veelvuldige omgewings te beskryf, en skakel ook kodeherhaling byna heeltemal uit.

Dit kan veral waar wees in gevalle waar u 'n toepassing in verskeie groepe met verskillende parameters moet ontplooi en dit verklarend in Git wil beskryf.

Qbec laat jou ook toe om Helm-kaarte weer te gee deur die nodige parameters aan hulle deur te gee en dan op dieselfde manier as gewone manifeste te werk, insluitend die vermoë om verskeie mutasies daarop toe te pas, en dit elimineer op sy beurt die behoefte om ChartMuseum te gebruik. Dit wil sê, jy kan kaarte direk vanaf git stoor en weergee, waar hulle hoort.

Soos ek voorheen gesê het, sal ons alle implementerings in die gids stoor ontplooi/:

mkdir deploy
cd deploy

Kom ons inisialiseer ons eerste toepassing:

qbec init website
cd website

Nou lyk die struktuur van ons toepassing soos volg:

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

kyk na die lêer qbec.yaml:

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

Hier stel ons hoofsaaklik belang spes.omgewings, qbec het reeds die verstekomgewing vir ons geskep en die bedieneradres en naamruimte van ons huidige kubeconfig geneem.
Nou wanneer dit ontplooi word na verstek omgewing, sal qbec altyd slegs na die gespesifiseerde Kubernetes-kluster en na die gespesifiseerde naamruimte ontplooi, dit wil sê jy hoef nie meer tussen kontekste en naamruimtes te wissel om te ontplooi nie.
Indien nodig, kan jy altyd die instellings in hierdie lêer opdateer.

Al jou omgewings word beskryf in qbec.yaml, en in die lêer params.libsonnet, wat sê waar jy die parameters vir hulle moet neem.

Volgende sien ons twee dopgehou:

  • komponente / - alle manifeste vir ons toepassing sal hier gestoor word, hulle kan beide in jsonnet en in gewone yaml-lêers beskryf word
  • omgewings/ - hier sal ons al die veranderlikes (parameters) vir ons omgewings beskryf.

By verstek het ons twee lêers:

  • omgewings/base.libsonnet - dit sal algemene parameters vir alle omgewings bevat
  • environments/default.libsonnet - bevat parameters wat herdefinieer is vir die omgewing verstek

kom ons maak oop omgewings/base.libsonnet en voeg parameters vir ons eerste komponent daar by:

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

Kom ons skep ook ons ​​eerste komponent komponente/webwerf.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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

In hierdie lêer het ons drie Kubernetes-entiteite gelyktydig beskryf, dit is: Ontplooiing, Diens и Ingang. As jy wil, kan ons hulle in verskillende komponente skuif, maar op hierdie stadium is een genoeg vir ons.

sintaksis jsonnet baie soortgelyk aan gewone json, in beginsel is gewone json reeds 'n geldige jsonnet, so dit kan aanvanklik vir jou makliker wees om aanlyndienste soos yaml2json om jou gewone yaml na json om te skakel, of as jou komponente geen veranderlikes bevat nie, dan kan hulle beskryf word in die vorm van gewone yaml.

By die werk met jsonnet Ek raai jou sterk aan om 'n inprop vir jou redigeerder te installeer

Daar is byvoorbeeld 'n inprop vir vim vim-jsonnet, wat sintaksis-verligting aanskakel en outomaties uitgevoer word jsonnet fmt op elke stoor (vereis dat jsonnet geïnstalleer moet word).

Alles is gereed, nou kan ons die ontplooiing begin:

Om te sien wat ons gekry het, kom ons hardloop:

qbec show default

By die afvoer sal jy die gelewerde yaml-manifeste sien wat op die verstekgroepering toegepas sal word.

Groot, pas nou toe:

qbec apply default

Op die afvoer sal jy altyd sien wat in jou cluster gedoen sal word, qbec sal jou vra om die veranderinge te aanvaar deur te tik y jy kan jou voornemens bevestig.

Klaar nou is ons toepassing ontplooi!

As veranderinge aangebring word, kan jy altyd hardloop:

qbec diff default

om te sien hoe hierdie veranderinge die huidige ontplooiing sal beïnvloed

Moenie vergeet om ons veranderinge toe te pas nie:

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

5. Probeer Gitlab-runner met Kubernetes-executor

Tot onlangs het ek net gereeld gebruik gitlab-runner op 'n vooraf voorbereide masjien (LXC-houer) met dop- of dokker-uitvoerder. Aanvanklik het ons verskeie van hierdie hardlopers wêreldwyd in ons gitlab gedefinieer. Hulle het docker-beelde vir alle projekte gebou.

Maar soos die praktyk getoon het, is hierdie opsie nie die mees ideale nie, beide in terme van praktiese en in terme van sekuriteit. Dit is baie beter en ideologies korrek om afsonderlike hardlopers vir elke projek, en selfs vir elke omgewing, te laat ontplooi.

Gelukkig is dit glad nie 'n probleem nie, aangesien ons nou sal ontplooi gitlab-runner direk as deel van ons projek reg in Kubernetes.

Gitlab bied 'n gereedgemaakte stuurkaart vir die implementering van gitlab-runner na Kubernetes. So al wat jy moet weet is registrasieteken vir ons projek in Instellings -> CI / CD -> Hardlopers en gee dit aan die stuur:

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

Waar:

  • https://gitlab.com is die adres van jou Gitlab-bediener.
  • yga8y-jdCusVDn_t4Wxc - registrasieteken vir jou projek.
  • rbac.create=waar - gee die hardloper die nodige aantal voorregte om peule te kan skep om ons take uit te voer met behulp van kubernetes-executor.

As alles korrek gedoen is, behoort jy die geregistreerde hardloper in die afdeling te sien Runners, in jou projekinstellings.

Skermskoot van die bygevoegde hardloper

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Is dit so eenvoudig? - ja, dit is so eenvoudig! Geen moeite om hardlopers met die hand te registreer nie, voortaan sal hardlopers outomaties geskep en vernietig word.

6. Ontplooi Helm-kaarte met QBEC

Aangesien ons besluit het om te oorweeg gitlab-runner deel van ons projek, is dit tyd om dit in ons Git-bewaarplek te beskryf.

Ons kan dit as 'n aparte komponent beskryf webwerf, maar in die toekoms beplan ons om verskillende kopieë te ontplooi webwerf baie dikwels, anders as gitlab-runner, wat slegs een keer per Kubernetes-kluster ontplooi sal word. Laat ons dus 'n aparte toepassing daarvoor inisialiseer:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Hierdie keer sal ons nie Kubernetes-entiteite met die hand beskryf nie, maar 'n klaargemaakte Helm-kaart neem. Een van die voordele van qbec is die vermoë om Helm-kaarte direk vanaf 'n Git-bewaarplek weer te gee.

Kom ons aktiveer dit met behulp van git submodule:

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

Nou die gids verkoper/gitlab-runner bevat ons bewaarplek met 'n grafiek vir gitlab-runner.

Ander bewaarplekke kan op 'n soortgelyke manier verbind word, byvoorbeeld die hele bewaarplek met amptelike kaarte https://github.com/helm/charts

Kom ons beskryf die komponent komponente/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,
  }
)

Die eerste argument om expandHelmTemplate ons slaag dan die pad na die grafiek params.waardes, wat ons van die omgewingsparameters neem, dan kom die voorwerp saam

  • naamSjabloon - vrystelling naam
  • naamruimte - naamruimte aan stuur oorgedra
  • hierdie lêer - 'n vereiste parameter wat die pad na die huidige lêer deurgee
  • verbose - wys opdrag stuur sjabloon met alle argumente wanneer 'n grafiek weergegee word

Kom ons beskryf nou die parameters vir ons komponent in omgewings/base.libsonnet:

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

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

Let wel hardloperregistrasietoken ons haal van eksterne lêer geheime/base.libsonnet, kom ons skep dit:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Kom ons kyk of alles werk:

qbec show default

as alles in orde is, dan kan ons ons vroeër ontplooide via Helm-vrystelling verwyder:

helm uninstall gitlab-runner

en ontplooi dit, maar deur qbec:

qbec apply default

7. Inleiding tot git-crypt

git-kript is 'n instrument waarmee u deursigtige enkripsie vir u bewaarplek kan opstel.

Op die oomblik lyk ons ​​gidsstruktuur vir gitlab-runner soos volg:

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

Maar om geheime in Git te stoor is nie veilig nie, is dit? Ons moet hulle dus behoorlik enkripteer.

Gewoonlik maak dit ter wille van een veranderlike nie altyd sin nie. Jy kan geheime oordra na qbec en deur die omgewingsveranderlikes van jou CI-stelsel.
Maar dit is opmerklik dat daar ook meer komplekse projekte is wat baie meer geheime kan bevat, dit sal uiters moeilik wees om hulle almal deur omgewingsveranderlikes te slaag.

Daarbenewens, in hierdie geval, sou ek nie in staat wees om jou te vertel oor so 'n wonderlike hulpmiddel soos git-kript.

git-kript Dit is ook gerieflik omdat dit jou toelaat om die hele geskiedenis van geheime te stoor, asook om konflikte te vergelyk, saam te smelt en op te los op dieselfde manier as wat ons dit in die geval van Git gedoen het.

Eerste ding na installasie git-kript ons moet sleutels genereer vir ons bewaarplek:

git crypt init

As jy 'n PGP-sleutel het, kan jy jouself dadelik as 'n medewerker vir hierdie projek byvoeg:

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

Op hierdie manier kan jy altyd hierdie bewaarplek dekripteer met jou private sleutel.

As jy nie 'n PGP-sleutel het nie en daar nie van jou verwag word nie, kan jy die ander kant toe gaan en die projeksleutel uitvoer:

git crypt export-key /path/to/keyfile

Dus, enigiemand wat 'n uitgevoer sleutellêer sal jou bewaarplek kan dekripteer.

Dit is tyd om ons eerste geheim op te stel.
Laat ek jou herinner dat ons nog in die gids is deploy/gitlab-runner/waar ons 'n gids het geheime/, kom ons enkripteer al die lêers daarin, hiervoor sal ons 'n lêer skep geheime/.gitattributes met inhoud soos hierdie:

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

Soos gesien kan word uit die inhoud, is alle lêers per masker * sal deurloop git-kript, met die uitsondering van die .gitattributes

Ons kan dit kontroleer deur te hardloop:

git crypt status -e

By die uitvoer kry ons 'n lys van alle lêers in die bewaarplek waarvoor enkripsie geaktiveer is

Dit is dit, nou kan ons veilig ons veranderinge pleeg:

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

Om die bewaarplek te blokkeer, is dit genoeg om uit te voer:

git crypt lock

en onmiddellik sal alle geïnkripteer lêers in 'n binêre iets verander, dit sal onmoontlik wees om dit te lees.
Om die bewaarplek te dekripteer, hardloop:

git crypt unlock

8. Skep 'n toolbox-beeld

'n Toolbox-prent is 'n prent met al die gereedskap wat ons sal gebruik om ons projek te ontplooi. Dit sal deur die gitlab-loper gebruik word om tipiese ontplooiingstake uit te voer.

Alles is eenvoudig hier, ons skep 'n nuwe dockerfiles/toolbox/Dockerfile met inhoud soos hierdie:

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

Soos u kan sien, installeer ons in hierdie prent al die nutsprogramme wat ons gebruik het om ons toepassing te ontplooi. Ons het nie hier nodig nie, tensy kubectl, maar jy wil dalk daarmee rondspeel wanneer jy die pyplyn opstel.

Ook, om met Kubernetes te kan kommunikeer en daarheen te kan ontplooi, moet ons 'n rol opstel vir die peule wat deur gitlab-runner gegenereer word.

Om dit te doen, gaan na die gids met gitlab-runner'om:

cd deploy/gitlab-runner

en voeg 'n nuwe komponent by komponente/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,
      },
    ],
  },
]

Ons beskryf ook die nuwe parameters in omgewings/base.libsonnet, wat nou so lyk:

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

Let wel $.components.rbac.name verwys na naam vir komponent rbac

Kom ons kyk wat verander het:

qbec diff default

en pas ons veranderinge toe op Kubernetes:

qbec apply default

Moet ook nie vergeet om ons veranderinge aan git te verbind nie:

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. Ons eerste pyplyn en samestelling van beelde deur etikette

Aan die wortel van die projek sal ons skep .gitlab-ci.yml met inhoud soos hierdie:

.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

Neem asseblief kennis dat ons gebruik GIT_SUBMODULE_STRATEGY: normaal vir daardie werke waar jy submodules eksplisiet moet inisialiseer voor uitvoering.

Moenie vergeet om ons veranderinge toe te pas nie:

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

Ek dink jy kan dit gerus 'n weergawe noem v0.0.1 en voeg 'n merker by:

git tag v0.0.1

Ons sal etikette ophang wanneer ons 'n nuwe weergawe moet vrystel. Merkers in Docker-beelde sal na Git-merkers gekarteer word. Elke druk met 'n nuwe merker sal 'n beeldbou met daardie merker inisialiseer.

Kom ons doen dit git push --tags, en kyk na ons eerste pyplyn:

Skermskoot van die eerste pyplyn

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Dit is die moeite werd om daarop te wys dat merkergebaseerde bouwerk goed is vir die bou van docker-beelde, maar nie vir die implementering van 'n toepassing na Kubernetes nie. Aangesien nuwe etikette ook aan ou commits toegewys kan word, sal in hierdie geval die inisiasie van die pyplyn daarvoor lei tot die ontplooiing van die ou weergawe.

Om hierdie probleem op te los, is die bou van docker-beelde gewoonlik gekoppel aan etikette, en die ontplooiing van die toepassing na die tak meester, waarin die weergawes van die versamelde beelde hardkodeer is. Dit is in hierdie geval dat jy terugrol kan inisialiseer met 'n eenvoudige terugstelling meester-takke.

10. Ontplooi outomatisering

Om vir Gitlab-runner ons geheime te dekripteer, moet ons die bewaarpleksleutel uitvoer en dit by ons CI-omgewingsveranderlikes voeg:

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

ons sal die gevolglike string in Gitlab stoor, hiervoor gaan ons na die instellings van ons projek:
Instellings —> CI / CD —> Veranderlikes

En skep 'n nuwe veranderlike:

Tipe
Sleutel
waarde
Beskerm
gemaskerde
Omvang

File
GITCRYPT_KEY
<your string>
true (ten tye van opleiding, kan jy false)
true
All environments

Skermskoot van die bygevoegde veranderlike

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Kom ons werk nou ons op .gitlab-ci.yml byvoeging daaraan:

.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

Hier het ons 'n paar nuwe opsies vir qbec geaktiveer:

  • --root sommige/app - laat jou toe om die gids van 'n spesifieke toepassing te definieer
  • --force:k8s-konteks __incluster__ - dit is 'n towerveranderlike wat sê dat die ontplooiing in dieselfde groep sal plaasvind waarin gtilab-runner loop. Dit is nodig, anders sal qbec probeer om 'n geskikte Kubernetes-bediener in jou kubeconfig te vind
  • -wag - dwing qbec om te wag totdat die hulpbronne wat dit skep in die Gereed-toestand gaan en dan eers voltooi met 'n suksesvolle uitgang-kode.
  • - ja - skakel net die interaktiewe dop uit Is jy seker? tydens ontplooiing.

Moenie vergeet om ons veranderinge toe te pas nie:

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

En nadat git push ons sal sien hoe ons toepassings ontplooi is:

Skermskoot van die tweede pyplyn

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

11. Artefakte en samestelling wanneer gedruk word om te bemeester

Gewoonlik is die bogenoemde stappe genoeg om byna enige mikrodiens te bou en te lewer, maar ons wil nie 'n merker byvoeg elke keer as ons die webwerf moet opdateer nie. Daarom sal ons op 'n meer dinamiese manier gaan en 'n digest-ontplooiing in die meestertak opstel.

Die idee is eenvoudig: nou die beeld van ons webwerf sal herbou word elke keer as jy druk meester, en ontplooi dan outomaties na Kubernetes.

Kom ons werk hierdie twee poste op in ons .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"

Neem asseblief kennis dat ons 'n tak bygevoeg het meester к verwysings vir werk bou_webwerf en ons gebruik nou $CI_COMMIT_REF_NAME in plaas van $CI_COMMIT_TAG, dit wil sê, ons raak ontslae van die etikette in Git en nou sal ons die prent stoot met die naam van die commit-tak wat jou pyplyn geïnitialiseer het. Dit is opmerklik dat dit ook met etikette sal werk, wat ons in staat sal stel om momentopnames van die webwerf met 'n spesifieke weergawe in die docker-register te stoor.

Wanneer die naam van die docker-tag vir die nuwe weergawe van die webwerf onveranderd kan wees, moet ons steeds die veranderinge vir Kubernetes beskryf, anders sal dit eenvoudig nie die toepassing vanaf die nuwe prent herontplooi nie, aangesien dit geen veranderinge in die ontplooiingsmanifes.

opsie --vm:ext-str digest="$DIGEST" vir qbec - laat jou toe om 'n eksterne veranderlike na jsonnet deur te gee. Ons wil hê dat ons toepassing met elke vrystelling in die groepering herontplooi moet word. Ons kan nie meer die merkernaam gebruik nie, wat nou onveranderd kan wees, aangesien ons na 'n spesifieke weergawe van die prent moet koppel en die ontplooiing aktiveer wanneer dit verander.

Hier sal Kaniko se vermoë om die samevatting van die prent in 'n lêer te stoor ons help (opsie --digest-lêer)
Dan sal ons hierdie lêer oordra en dit lees ten tyde van ontplooiing.

Kom ons werk die parameters vir ons op deploy/website/environments/base.libsonnet wat nou so sal lyk:

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

Klaar, nou enige commit in meester inisialiseer die bou van die docker-beeld vir webwerf, en ontplooi dit dan na Kubernetes.

Moenie vergeet om ons veranderinge toe te pas nie:

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

Kyk daarna git push ons behoort iets soos hierdie te sien:

Pyplyn-skermkiekie vir meester

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

In beginsel hoef ons nie gitlab-runner met elke druk te herontplooi nie, tensy natuurlik niks in sy konfigurasie verander het nie, kom ons maak dit reg in .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/**/*

veranderinge sal tred hou met veranderinge in deploy/gitlab-runner/ en sal ons werk net aktiveer as daar enige is

Moenie vergeet om ons veranderinge toe te pas nie:

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

git push, Dis beter:

Skermskoot van die opgedateerde pyplyn

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

12. Dinamiese omgewings

Dit is tyd om ons pyplyn te diversifiseer met dinamiese omgewings.

Kom ons werk eers die werk op bou_webwerf in ons .gitlab-ci.yml, en verwyder die blok daarvan net, wat Gitlab sal dwing om dit te aktiveer op enige verbintenis tot enige tak:

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/

Dateer dan die werk op ontplooi_webwerf, voeg 'n blok daar by omgewing:

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"

Dit sal Gitlab toelaat om die werk mee te assosieer prod omgewing en vertoon die korrekte skakel daarna.

Kom ons voeg nou nog twee werke by:

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

Hulle sal geaktiveer word deur druk na enige takke behalwe meester en sal 'n voorskouweergawe van die webwerf ontplooi.

Ons sien 'n nuwe opsie vir qbec: --app-tag - dit laat jou toe om ontplooide weergawes van die toepassing te merk en slegs binne hierdie merker te werk; wanneer bronne in Kubernetes geskep en vernietig word, sal qbec net daarop werk.
Ons kan dus nie 'n aparte omgewing vir elke resensie skep nie, maar net dieselfde een hergebruik.

Hier gebruik ons ​​ook qbec pas hersiening toe, in plaas van qbec pas verstek toe - dit is presies die oomblik wanneer ons die verskille vir ons omgewings sal probeer beskryf (hersiening en verstek):

Kom ons voeg by hersien omgewing in deploy/website/qbec.yaml

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

Dan verklaar ons dit in 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

En skryf persoonlike parameters daarvoor in 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',
    },
  },
}

Kom ons kyk ook na werk van nader stop_resensie, dit sal geaktiveer word wanneer die tak verwyder word en sodat gitlab nie daarop probeer afreken nie, word dit gebruik GIT_STRATEGY: geen, later kloon ons meester-vertak en verwyder resensie daardeur.
Bietjie verwarrend, maar ek het nog nie 'n mooier manier gevind nie.
'n Alternatiewe opsie sou wees om elke resensie na 'n hotelnaamruimte te ontplooi, wat altyd in sy geheel gesloop kan word.

Moenie vergeet om ons veranderinge toe te pas nie:

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

git push, git checkout -b toets, git push oorsprong toets, tjek:

Skermskoot van geskepte omgewings in Gitlab

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Werk alles? - wonderlik, vee ons toetstak uit: git checkout meester, git push oorsprong: toets, kyk ons ​​dat die take vir die verwydering van die omgewing sonder foute gewerk het.

Hier wil ek dadelik duidelik maak dat enige ontwikkelaar in die projek takke kan skep, hy kan ook verander .gitlab-ci.yml lêer en toegang tot geheime veranderlikes.
Daarom word dit sterk aanbeveel om die gebruik daarvan slegs vir beskermde takke toe te laat, byvoorbeeld in meester, of skep 'n aparte stel veranderlikes vir elke omgewing.

13 Hersien toepassings

Hersien toepassings dit is 'n gitlab-funksie waarmee u 'n knoppie vir elke lêer in die bewaarplek kan byvoeg om dit vinnig in die ontplooide omgewing te sien.

Om hierdie knoppies te laat verskyn, moet jy 'n lêer skep .gitlab/roete-kaart.yml en beskryf daarin al die transformasies van die paaie, in ons geval sal dit baie eenvoudig wees:

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

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

Moenie vergeet om ons veranderinge toe te pas nie:

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

git push, en kontroleer:

Skermskoot van die Review App Button

Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Job is gedoen!

Projekbronne:

Dankie vir jou aandag, ek hoop jy het daarvan gehou Probeer nuwe nutsgoed vir die bou en outomatisering van ontplooiing in Kubernetes

Bron: will.com

Voeg 'n opmerking