Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Zdravo! Nedavno su objavljeni mnogi zgodni alati za automatizaciju za izradu Docker slika i za implementaciju u Kubernetes. S tim u vezi, odlučio sam se poigrati s GitLabom, temeljito proučiti njegove mogućnosti i, naravno, postaviti pipeline.

Ovaj je rad inspiriran web stranicom kubernetes.io, koji se generira iz izvorni kodovi automatski, a za svaki poslani zahtjev za skupom, robot automatski generira pretpreglednu verziju web-mjesta s vašim promjenama i daje poveznicu za gledanje.

Pokušao sam izgraditi sličan proces od nule, ali u potpunosti izgrađen na Gitlab CI i besplatnim alatima koje sam navikao koristiti za implementaciju aplikacija u Kubernetes. Danas ću vam konačno reći nešto više o njima.

U članku će se raspravljati o alatima kao što su:
Hugo, qbec, kaniko, git-kripta и GitLab CI uz stvaranje dinamičnih okruženja.

Sadržaj

  1. Upoznaj Huga
  2. Priprema datoteke Docker
  3. Upoznavanje s kanikom
  4. Upoznavanje s qbecom
  5. Isprobavanje Gitlab-runnera s Kubernetes-executorom
  6. Postavljanje Helmovih karata s qbecom
  7. Predstavljamo git-crypt
  8. Stvaranje slike kutije s alatima
  9. Naš prvi cjevovod i sklapanje slika po oznakama
  10. Automatizacija implementacije
  11. Artefakti i montaža prilikom guranja u master
  12. Dinamična okruženja
  13. Pregledajte aplikacije

1. Upoznavanje Huga

Kao primjer našeg projekta, pokušat ćemo stvoriti stranicu za objavljivanje dokumentacije izgrađenu na Hugu. Hugo je generator statičnog sadržaja.

Za one koji nisu upoznati sa statičkim generatorima, reći ću vam nešto više o njima. Za razliku od konvencionalnih web motora s bazom podataka i nešto PHP-a, koji na zahtjev korisnika generiraju stranice u hodu, statički generatori su dizajnirani malo drugačije. Omogućuju vam da uzmete izvore, obično skup datoteka u Markdown oznakama i predlošcima tema, zatim ih kompajlirate u potpuno dovršeno web mjesto.

To jest, kao rezultat toga, dobit ćete strukturu direktorija i skup generiranih HTML datoteka, koje možete jednostavno prenijeti na bilo koji jeftini hosting i dobiti radnu web stranicu.

Možete instalirati Hugo lokalno i isprobati ga:

Inicijalizacija nove stranice:

hugo new site docs.example.org

I u isto vrijeme git repozitorij:

cd docs.example.org
git init

Za sada je naša stranica netaknuta i da bi se nešto pojavilo na njoj prvo moramo povezati temu, tema je samo skup šablona i specificiranih pravila po kojima se naša stranica generira.

Za temu koju ćemo koristiti Naučiti, koji je, po mom mišljenju, savršeno prikladan za mjesto s dokumentacijom.

Želio bih obratiti posebnu pozornost na činjenicu da ne moramo spremati datoteke tema u naš repozitorij projekta; umjesto toga, možemo ga jednostavno povezati pomoću git podmodul:

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

Tako će naš repozitorij sadržavati samo datoteke koje su izravno povezane s našim projektom, a povezana tema će ostati kao poveznica na određeno repozitorij i commit u njemu, odnosno uvijek se može povući iz izvornog izvora i ne bojati se nekompatibilne promjene.

Ispravimo konfiguraciju config.toml:

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

Već u ovoj fazi možete pokrenuti:

hugo server

I na adresi http://localhost:1313/ provjerite našu novostvorenu web stranicu, sve promjene u imeniku automatski ažuriraju otvorenu stranicu u pregledniku, vrlo povoljno!

Pokušajmo napraviti naslovnu stranicu u sadržaj/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Snimka zaslona novostvorene stranice

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Za generiranje stranice samo pokrenite:

hugo

Sadržaj imenika javnost/ i bit će vaša web stranica.
Da, usput, odmah ga dodajmo .gitignor:

echo /public > .gitignore

Ne zaboravite unijeti naše promjene:

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

2. Priprema Dockerfile

Vrijeme je da definiramo strukturu našeg repozitorija. Obično koristim nešto poput:

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

  • dockerfiles/ — sadrže direktorije s Docker datotekama i svime što je potrebno za izgradnju naših Docker slika.
  • rasporediti/ — sadrži direktorije za postavljanje naših aplikacija na Kubernetes

Stoga ćemo stvoriti našu prvu Docker datoteku na putu dockerfiles/web stranica/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" ]

Kao što vidite, Dockerfile sadrži dva IZ, ova značajka se zove višestupanjska izgradnja i omogućuje vam da isključite sve nepotrebno iz konačne Docker slike.
Stoga će konačna slika sadržavati samo tamnohttpd (lagani HTTP poslužitelj) i javnost/ — sadržaj naše statički generirane web stranice.

Ne zaboravite unijeti naše promjene:

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

3. Upoznavanje s kanikom

Kao graditelj docker slika, odlučio sam koristiti kaniko, budući da za njegov rad nije potreban docker demon, a sama se izgradnja može izvesti na bilo kojem računalu, a predmemorija se može pohraniti izravno u registar, čime se eliminira potreba za punopravnom trajnom pohranom.

Za izradu slike samo pokrenite spremnik s kaniko izvršitelj i proslijedite mu trenutni kontekst izgradnje; to se također može učiniti lokalno, putem dockera:

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

gdje registry.gitlab.com/kvaps/docs.example.org/website — naziv vaše docker slike; nakon izgradnje, automatski će se pokrenuti u docker registar.

Parametar --predmemorija omogućuje vam spremanje slojeva u predmemoriju u docker registru; za navedeni primjer, oni će biti spremljeni u registry.gitlab.com/kvaps/docs.example.org/website/cache, ali možete navesti drugu putanju pomoću parametra --cache-repo.

Snimka zaslona docker-registra

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

4. Upoznavanje s qbecom

Qbec je alat za implementaciju koji vam omogućuje deklarativno opisivanje manifesta vaše aplikacije i njihovu implementaciju u Kubernetes. Korištenje Jsonneta kao glavne sintakse omogućuje vam da uvelike pojednostavite opis razlika u više okruženja, a također gotovo u potpunosti eliminira ponavljanje koda.

To može biti osobito istinito u slučajevima kada trebate implementirati aplikaciju u nekoliko klastera s različitim parametrima i želite ih deklarativno opisati u Gitu.

Qbec vam također omogućuje renderiranje Helmovih dijagrama prosljeđivanjem potrebnih parametara, a zatim njima upravljate na isti način kao i običnim manifestima, uključujući mogućnost primjene raznih mutacija na njih, a to vam zauzvrat omogućuje da se riješite potrebe da koristite ChartMuseum. Odnosno, možete pohraniti i prikazati grafikone izravno iz gita, gdje im je i mjesto.

Kao što sam ranije rekao, sve ćemo implementacije pohraniti u direktorij rasporediti/:

mkdir deploy
cd deploy

Inicijalizirajmo našu prvu aplikaciju:

qbec init website
cd website

Sada struktura naše aplikacije izgleda ovako:

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

pogledajmo datoteku qbec.yaml:

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

Ovdje nas prvenstveno zanima spec.okoline, qbec je već stvorio zadano okruženje za nas i uzeo adresu poslužitelja, kao i prostor imena iz našeg trenutnog kubeconfiga.
Sada prilikom postavljanja na zadani okruženju, qbec će se uvijek implementirati samo u navedeni Kubernetes klaster i u navedeni prostor imena, to jest, više ne morate prelaziti između konteksta i prostora imena kako biste izvršili implementaciju.
Ako je potrebno, uvijek možete ažurirati postavke u ovoj datoteci.

Sva vaša okruženja opisana su u qbec.yaml, i u datoteci parametri.libsonnet, gdje piše gdje se mogu nabaviti parametri za njih.

Zatim vidimo dva direktorija:

  • komponente / — svi manifesti za našu aplikaciju bit će pohranjeni ovdje; mogu se opisati i u jsonnet i u običnim yaml datotekama
  • okruženja/ — ovdje ćemo opisati sve varijable (parametre) za naše okruženje.

Standardno imamo dvije datoteke:

  • okruženja/baza.libsonnet - sadržavat će zajedničke parametre za sva okruženja
  • okruženja/zadano.libsonnet — sadrži parametre nadjačane za okolinu zadani

otvorimo okruženja/baza.libsonnet i tamo dodajte parametre za našu prvu komponentu:

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

Kreirajmo i našu prvu komponentu komponente/web stranica.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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

U ovoj datoteci smo opisali tri Kubernetes entiteta odjednom, a to su: razvoj, Servis и Ulaz. Da želimo, mogli bismo ih staviti u različite komponente, ali u ovoj fazi jedna će nam biti dovoljna.

sintaksa jsonnet je vrlo sličan običnom jsonu, u načelu, obični json je već važeći jsonnet, tako da će vam u početku možda biti lakše koristiti mrežne usluge kao što su yaml2json da pretvorite svoj uobičajeni yaml u json ili, ako vaše komponente ne sadrže nikakve varijable, mogu se opisati u obliku običnog yamla.

Prilikom rada s jsonnet Toplo preporučujem da instalirate dodatak za svoj uređivač

Na primjer, postoji dodatak za vim vim-jsonnet, koji uključuje označavanje sintakse i automatski se izvršava jsonnet fmt svaki put kada spremite (zahtijeva instaliran jsonnet).

Sve je spremno, sada možemo početi s implementacijom:

Da vidimo što imamo, pokrenimo:

qbec show default

Na izlazu ćete vidjeti prikazane yaml manifeste koji će se primijeniti na zadani klaster.

Super, sada se prijavi:

qbec apply default

Na izlazu ćete uvijek vidjeti što će se raditi u vašem klasteru, qbec će vas pitati da pristanete na promjene upisivanjem y moći ćete potvrditi svoje namjere.

Naša aplikacija je spremna i implementirana!

Ako napravite promjene, uvijek možete učiniti sljedeće:

qbec diff default

da vidite kako će ove promjene utjecati na trenutnu implementaciju

Ne zaboravite unijeti naše promjene:

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

5. Isprobavanje Gitlab-runnera s Kubernetes-executorom

Do nedavno sam koristila samo obične gitlab-trkač na unaprijed pripremljenom stroju (LXC kontejner) sa shellom ili docker-executorom. U početku smo imali nekoliko takvih trkača globalno definiranih u našem gitlabu. Prikupili su docker slike za sve projekte.

No, kako je praksa pokazala, ova opcija nije najidealnija, kako u smislu praktičnosti tako i sigurnosti. Mnogo je bolje i ideološki ispravnije imati zasebne trkače raspoređene za svaki projekt, ili čak za svako okruženje.

Srećom, to uopće nije problem, jer sada ćemo se rasporediti gitlab-trkač izravno u sklopu našeg projekta upravo u Kubernetesu.

Gitlab pruža gotovu shemu kormila za implementaciju gitlab-runner-a u Kubernetes. Dakle, sve što trebate učiniti je saznati registracijski token za naš projekt u Postavke -> CI / CD -> Trkači i dodaj ga kormilu:

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

Gdje:

  • https://gitlab.com — adresa vašeg Gitlab poslužitelja.
  • yga8y-jdCusVDn_t4Wxc — registracijski token za vaš projekt.
  • rbac.create=true — pruža runner-u potrebnu količinu privilegija da može stvoriti mahune za obavljanje naših zadataka pomoću kubernetes-executora.

Ako je sve učinjeno ispravno, trebali biste vidjeti registriranog trkača u odjeljku Trkači, u postavkama vašeg projekta.

Snimka zaslona dodanog pokretača

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Je li tako jednostavno? - da, tako je jednostavno! Nema više gnjavaže s ručnim registriranjem trkača, od sada će se trkači stvarati i uništavati automatski.

6. Postavite Helm karte s QBEC-om

Budući da smo odlučili razmotriti gitlab-trkač dio našeg projekta, vrijeme je da ga opišemo u našem Git repozitoriju.

Mogli bismo ga opisati kao zasebnu komponentu web stranicu, ali u budućnosti planiramo postaviti različite kopije web stranicu vrlo često, za razliku od gitlab-trkač, koji će biti implementiran samo jednom po Kubernetes klasteru. Inicijalizirajmo zasebnu aplikaciju za to:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Ovaj put nećemo ručno opisivati ​​Kubernetes entitete, već ćemo uzeti gotov Helmov grafikon. Jedna od prednosti qbec-a je mogućnost renderiranja Helm grafikona izravno iz Git repozitorija.

Povežimo ga pomoću git submodula:

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

Sada imenik dobavljač/gitlab-runner Imamo repozitorij s grafikonom za gitlab-runner.

Na sličan način možete povezati i druge repozitorije, na primjer, cijeli repozitorij sa službenim grafikonima https://github.com/helm/charts

Opišimo komponentu 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,
  }
)

Prvi argument za expandHelmTemplate onda prolazimo put do grafikona parametri.vrijednosti, koje uzimamo iz parametara okoline, zatim dolazi objekt s

  • nameTemplate — naziv izdanja
  • imenski prostor — imenski prostor prenesen u helm
  • thisFile — obavezni parametar koji prosljeđuje stazu do trenutne datoteke
  • glagolan - pokazuje naredbu predložak kormila sa svim argumentima prilikom renderiranja grafikona

Sada opišimo parametre za našu komponentu okruženja/baza.libsonnet:

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

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

Imajte na umu runnerRegistrationToken preuzimamo iz vanjske datoteke tajne/baza.libsonnet, stvorimo ga:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Provjerimo radi li sve:

qbec show default

ako je sve u redu, tada možemo izbrisati svoje prethodno postavljeno izdanje putem Helma:

helm uninstall gitlab-runner

i implementirajte ga na isti način, ali kroz qbec:

qbec apply default

7. Predstavljamo git-crypt

Git-kripta je alat koji vam omogućuje postavljanje transparentne enkripcije za vaše spremište.

Trenutačno, naša struktura direktorija za gitlab-runner izgleda ovako:

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

Ali pohranjivanje tajni u Gitu nije sigurno, zar ne? Dakle, moramo ih ispravno šifrirati.

Obično, radi jedne varijable, to nema uvijek smisla. Možete prenijeti tajne na qbec i kroz varijable okruženja vašeg CI sustava.
Ali vrijedi napomenuti da postoje i složeniji projekti koji mogu sadržavati mnogo više tajni; prijenos svih kroz varijable okruženja bit će izuzetno težak.

Štoviše, u ovom slučaju ne bih vam mogao govoriti o tako divnom alatu kao što je git-kripta.

git-kripta Također je zgodan jer vam omogućuje spremanje cijele povijesti tajni, kao i usporedbu, spajanje i rješavanje sukoba na isti način kao što smo navikli raditi u slučaju Gita.

Prva stvar nakon instalacije git-kripta moramo generirati ključeve za naše spremište:

git crypt init

Ako imate PGP ključ, možete se odmah dodati kao suradnik za ovaj projekt:

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

Na taj način uvijek možete dešifrirati ovo spremište koristeći svoj privatni ključ.

Ako nemate PGP ključ i ne očekujete ga, možete ići drugim putem i izvesti projektni ključ:

git crypt export-key /path/to/keyfile

Dakle, svatko tko ima izvezeno ključnu datoteku će moći dešifrirati vaše spremište.

Vrijeme je da postavimo našu prvu tajnu.
Da vas podsjetim da smo još uvijek u imeniku implementacija/gitlab-runner/, gdje imamo imenik tajne/, šifrirajmo sve datoteke u njemu, za to ćemo stvoriti datoteku tajne/.gitattributes sa sljedećim sadržajem:

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

Kao što se može vidjeti iz sadržaja, sve datoteke su maskirane * će se voziti kroz git-kripta, osim većine .gitattributes

To možemo provjeriti pokretanjem:

git crypt status -e

Izlaz će biti popis svih datoteka u repozitoriju za koje je omogućena enkripcija

To je sve, sada možemo sigurno primiti naše promjene:

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

Da biste blokirali spremište, samo pokrenite:

git crypt lock

i odmah će se sve šifrirane datoteke pretvoriti u nešto binarno, bit će ih nemoguće pročitati.
Za dešifriranje repozitorija, pokrenite:

git crypt unlock

8. Napravite sliku kutije s alatima

Slika toolboxa je slika sa svim alatima koje ćemo koristiti za implementaciju našeg projekta. Koristit će ga Gitlab pokretač za izvođenje tipičnih zadataka implementacije.

Ovdje je sve jednostavno, stvorimo novi dockerfiles/toolbox/Dockerfile sa sljedećim sadržajem:

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

Kao što vidite, na ovoj slici instaliramo sve pomoćne programe koje smo koristili za implementaciju naše aplikacije. Ne treba nam ovdje osim ako kubectl, ali možda biste se htjeli poigrati s njim tijekom faze postavljanja cjevovoda.

Također, kako bismo mogli komunicirati s Kubernetesom i implementirati ga, moramo konfigurirati ulogu za podove koje generira gitlab-runner.

Da bismo to učinili, idemo u direktorij s gitlab-runner:

cd deploy/gitlab-runner

i dodajte novu komponentu 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,
      },
    ],
  },
]

Također ćemo opisati nove parametre u okruženja/baza.libsonnet, koji sada izgleda ovako:

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

Imajte na umu $.components.rbac.name odnosi se na ime za komponentu rbac

Provjerimo što se promijenilo:

qbec diff default

i primijenite naše promjene na Kubernetes:

qbec apply default

Također, ne zaboravite unijeti naše promjene u git:

cd ../..
git add dockerfiles/toolbox
git commit -m "Add Dockerfile for toolbox"
git add deploy/gitlab-runner
git commit -m "Configure gitlab-runner to use toolbox"

9. Naš prvi cjevovod i sklapanje slika po oznakama

U korijenu projekta koji ćemo stvoriti .gitlab-ci.yml sa sljedećim sadržajem:

.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

Imajte na umu da koristimo GIT_SUBMODULE_STRATEGY: normalno za one poslove gdje trebate eksplicitno inicijalizirati podmodule prije izvršenja.

Ne zaboravite unijeti naše promjene:

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

Mislim da ovo sa sigurnošću možemo nazvati verzijom v0.0.1 i dodajte oznaku:

git tag v0.0.1

Dodat ćemo oznake kad god trebamo izdati novu verziju. Oznake u Docker slikama bit će povezane s Git oznakama. Svaki pritisak s novom oznakom će pokrenuti izgradnju slika s ovom oznakom.

Učinimo to git push --tagovi, i pogledajmo naš prvi cjevovod:

Snimka zaslona prvog cjevovoda

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Vrijedno je skrenuti vašu pozornost na činjenicu da je sklapanje pomoću oznaka prikladno za izradu docker slika, ali nije prikladno za implementaciju aplikacije u Kubernetes. Budući da se nove oznake mogu dodijeliti starim obvezama, u ovom slučaju će inicijalizacija cjevovoda za njih dovesti do implementacije stare verzije.

Da bi se riješio ovaj problem, obično je izrada docker slika vezana uz oznake, a implementacija aplikacije u granu majstor, u kojem su verzije prikupljenih slika tvrdo kodirane. Ovo je mjesto gdje možete pokrenuti vraćanje na staro stanje jednostavnim vraćanjem majstor- grane.

10. Automatizacija implementacije

Kako bi Gitlab-runner dešifrirao naše tajne, morat ćemo izvesti ključ spremišta i dodati ga našim varijablama CI okruženja:

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

Rezultirajući redak ćemo spremiti u Gitlab; da bismo to učinili, idemo na postavke našeg projekta:
Postavke -> CI / CD -> Varijable

I stvorimo novu varijablu:

Tip
Ključ
Još malo brojeva
zaštićen
maskiran
Djelokrug

File
GITCRYPT_KEY
<your string>
true (tijekom obuke možete false)
true
All environments

Snimka zaslona dodane varijable

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Sada ažurirajmo naše .gitlab-ci.yml dodajući tome:

.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

Ovdje smo omogućili nekoliko novih opcija za qbec:

  • --root neke/aplikacije — omogućuje određivanje direktorija određene aplikacije
  • --force:k8s-kontekst __incluster__ - ovo je čarobna varijabla koja kaže da će se implementacija dogoditi u istom klasteru u kojem se izvodi gtilab-runner. Ovo je neophodno jer će inače qbec pokušati pronaći odgovarajući Kubernetes poslužitelj u vašem kubeconfigu
  • --čekati — prisiljava qbec da čeka dok resursi koje kreira prijeđu u stanje Spremno i tek tada izađe s uspješnim izlaznim kodom.
  • -Da - jednostavno onemogućuje interaktivnu ljusku Jesi li siguran? kada je raspoređen.

Ne zaboravite unijeti naše promjene:

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

I poslije git guranje vidjet ćemo kako su naše aplikacije raspoređene:

Snimka zaslona drugog cjevovoda

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

11. Artefakti i sklapanje pri guranju na master

Obično su gore opisani koraci dovoljni za izgradnju i isporuku gotovo svake mikrousluge, ali ne želimo dodavati oznaku svaki put kada trebamo ažurirati web mjesto. Stoga ćemo krenuti dinamičnijim putem i postaviti sažetak implementacije u glavnoj grani.

Ideja je jednostavna: sada slika našeg web stranicu ponovno će se izgraditi svaki put kad uđete majstor, a zatim automatski implementirati u Kubernetes.

Ažurirajmo ova dva posla u našem .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"

Imajte na umu da smo dodali nit majstor к ref za radna mjesta izgraditi_web stranicu i sada koristimo $CI_COMMIT_REF_NAME umjesto $CI_COMMIT_TAG, to jest, odvezani smo od oznaka u Gitu i sada ćemo gurnuti sliku s nazivom grane urezivanja koja je inicijalizirala cjevovod. Vrijedno je napomenuti da će ovo također raditi s oznakama, što će nam omogućiti spremanje snimaka stranice s određenom verzijom u docker-registru.

Kada naziv docker oznake za novu verziju web-mjesta može biti nepromijenjen, još uvijek moramo opisati promjene u Kubernetesu, inače jednostavno neće ponovno postaviti aplikaciju s nove slike, jer neće primijetiti nikakve promjene u manifest implementacije.

Opcija —vm:ext-str digest=”$DIGEST” za qbec - omogućuje vam prosljeđivanje vanjske varijable u jsonnet. Želimo da se ponovno rasporedi u klaster sa svakim izdanjem naše aplikacije. Više ne možemo koristiti naziv oznake, koji sada može biti nepromjenjiv, budući da moramo biti vezani za određenu verziju slike i pokrenuti implementaciju kada se promijeni.

Ovdje će nam pomoći Kanikova sposobnost spremanja sažete slike u datoteku (opcija --sažeta-datoteka)
Zatim ćemo prenijeti ovu datoteku i pročitati je u vrijeme postavljanja.

Ažurirajmo parametre za naš implementacija/web stranica/okruženja/base.libsonnet koji će sada izgledati ovako:

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

Gotovo, sada možete izvršiti bilo kakvu predaju majstor inicijalizira izgradnju docker slike za web stranicu, a zatim ga implementirajte u Kubernetes.

Ne zaboravite unijeti naše promjene:

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

Provjerit ćemo kasnije git guranje trebali bismo vidjeti nešto poput ovoga:

Snimka zaslona cjevovoda za master

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

U principu, ne trebamo ponovno postavljati gitlab-runner sa svakim pritiskom, osim ako se, naravno, ništa nije promijenilo u njegovoj konfiguraciji, popravimo to u .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/**/*

promjene omogućit će vam praćenje promjena u implementacija/gitlab-runner/ i pokrenut će naš posao samo ako ih bude

Ne zaboravite unijeti naše promjene:

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

git guranje, tako je bolje:

Snimka zaslona ažuriranog cjevovoda

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

12. Dinamička okruženja

Vrijeme je da diverzificiramo našu ponudu dinamičnim okruženjima.

Prvo, ažurirajmo posao izgraditi_web stranicu u našem .gitlab-ci.yml, uklanjajući blok iz njega samo, što će natjerati Gitlab da ga pokrene pri svakom predanju bilo koje grane:

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/

Zatim ažurirajte posao deploy_website, dodajte blok tamo okolina:

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"

To će omogućiti Gitlabu da poveže posao sa štap okruženje i prikazati ispravnu vezu na njega.

Dodajmo sada još dva posla:

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

Pokrenut će se nakon guranja u bilo koju granu osim glavne i pokrenut će pretpreglednu verziju web-mjesta.

Vidimo novu opciju za qbec: --oznaka-aplikacije — omogućuje vam označavanje implementiranih verzija aplikacije i rad samo unutar te oznake; prilikom stvaranja i uništavanja resursa u Kubernetesu, qbec će raditi samo s njima.
Na taj način ne možemo stvoriti zasebno okruženje za svaki pregled, već jednostavno ponovno upotrijebiti isto.

Ovdje također koristimo qbec primijeniti pregledumjesto qbec primijeni zadano - ovo je upravo trenutak kada ćemo pokušati opisati razlike za naše sredine (review i default):

Dodati recenzija okruženje u implementacija/web stranica/qbec.yaml

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

Tada ćemo to prijaviti implementacija/web stranica/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

I zapišite prilagođene parametre za to implementacija/web stranica/okruženja/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',
    },
  },
}

Pogledajmo također pobliže jobu stop_review, pokrenut će se kada se ogranak izbriše i koristi se kako gitlab ne bi pokušao provjeriti GIT_STRATEGIJA: ništa, kasnije kloniramo majstor-odvojite granu i izbrišite pregled kroz nju.
Malo je zbunjujuće, ali još nisam našao ljepši način.
Alternativna opcija bila bi implementacija svake recenzije u prostor imena hotela, koji se uvijek može u potpunosti uništiti.

Ne zaboravite unijeti naše promjene:

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

git guranje, git checkout -b test, git push izvorni test, ček:

Snimka zaslona kreiranih okruženja u Gitlabu

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Sve radi? - odlično, izbrišite našu testnu granu: git checkout majstor, git push origin :test, provjeravamo jesu li poslovi za brisanje okruženja radili bez grešaka.

Ovdje bih želio odmah pojasniti da bilo koji programer u projektu može stvarati grane, može i mijenjati .gitlab-ci.yml datoteka i pristup tajnim varijablama.
Stoga se strogo preporuča dopustiti njihovu upotrebu samo za zaštićene grane, na primjer u majstor, ili stvoriti zaseban skup varijabli za svako okruženje.

13. Pregledajte aplikacije

Pregledajte aplikacije Ovo je GitLab značajka koja vam omogućuje dodavanje gumba za svaku datoteku u repozitoriju kako biste je brzo pregledali u postavljenom okruženju.

Kako bi se ovi gumbi pojavili, morate stvoriti datoteku .gitlab/route-map.yml i opisati sve transformacije putanje u njemu; u našem slučaju to će biti vrlo jednostavno:

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

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

Ne zaboravite unijeti naše promjene:

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

git guranje, i provjerite:

Snimka zaslona gumba Pregled aplikacije

Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Posao je gotov!

Izvori projekta:

Hvala na pažnji, nadam se da vam se svidjelo Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu

Izvor: www.habr.com

Dodajte komentar