Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Ahoj! V poslední době bylo vydáno mnoho skvělých automatizačních nástrojů jak pro vytváření obrazů Docker, tak pro nasazení do Kubernetes. V tomto ohledu jsem se rozhodl pohrát si s Gitlabem, jak nastudovat jeho možnosti a samozřejmě nastavit pipeline.

Inspirací pro tuto práci byly stránky kubernetes.io, který je generován z zdrojové kódy automaticky a pro každou odeslanou žádost o stažení robot automaticky vygeneruje náhledovou verzi webu s vašimi změnami a poskytne odkaz pro zobrazení.

Pokusil jsem se vytvořit podobný proces od nuly, ale zcela postavený na Gitlab CI a bezplatných nástrojích, které jsem používal k nasazení aplikací do Kubernetes. Dnes vám o nich konečně řeknu více.

Článek se bude zabývat nástroji, jako jsou:
Hugo, qbec, kaniko, git-crypt и GitLab CI s vytvářením dynamických prostředí.

Obsah

  1. Seznámení s Hugem
  2. Příprava souboru Dockerfile
  3. Seznámení s kaniko
  4. Úvod do qbec
  5. Vyzkoušejte Gitlab-runner s Kubernetes-executorem
  6. Nasaďte grafy Helm pomocí qbec
  7. Úvod do git-crypt
  8. Vytvořte obrázek sady nástrojů
  9. Naše první potrubí a sestavování obrázků pomocí značek
  10. Nasadit automatizaci
  11. Artefakty a sestavení při tlačení na master
  12. Dynamická prostředí
  13. Recenze aplikací

1. Seznámení s Hugem

Jako příklad našeho projektu se pokusíme vytvořit web pro publikování dokumentace postavený na Hugo. Hugo je generátor statického obsahu.

Pro ty, kteří nejsou obeznámeni se statickými generátory, vám o nich řeknu něco více. Na rozdíl od běžných enginů stránek s databází a nějakým tím php, které na žádost uživatele generují stránky za běhu, jsou statické generátory uspořádány trochu jinak. Umožňují vám vzít zdrojový kód, obvykle sadu souborů v Markdown markup a šablonách témat, a poté je zkompilovat do kompletně hotového webu.

To znamená, že na výstupu získáte adresářovou strukturu a sadu vygenerovaných html souborů, které jednoduše nahrajete na jakýkoli levný hosting a získáte funkční stránky.

Hugo si můžete nainstalovat lokálně a vyzkoušet:

Inicializace nového webu:

hugo new site docs.example.org

A zároveň úložiště git:

cd docs.example.org
git init

Zatím je náš web panenský a aby se na něm něco objevilo, potřebujeme nejprve propojit téma, téma je jen sada šablon a nastavených pravidel, podle kterých se naše stránky generují.

Jako téma použijeme Učit se, který se podle mého názoru na stránky s dokumentací hodí nejlépe.

Chtěl bych věnovat zvláštní pozornost skutečnosti, že nemusíme ukládat soubory motivu do úložiště našeho projektu, místo toho je můžeme jednoduše připojit pomocí submodul git:

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

V našem úložišti tak budou pouze soubory přímo související s naším projektem a připojené téma zůstane jako odkaz na konkrétní úložiště a v něm commit, to znamená, že jej lze vždy stáhnout z původního zdroje a nebát se neslučitelných změn.

Pojďme opravit konfiguraci config.toml:

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

Již v této fázi můžete spustit:

hugo server

A na adrese http://localhost:1313/ zkontrolujte naše nově vytvořené stránky, všechny změny provedené v adresáři automaticky aktualizují otevřenou stránku v prohlížeči, velmi pohodlné!

Zkusme vytvořit titulní stránku v content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Snímek obrazovky nově vytvořené stránky

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Chcete-li vygenerovat web, stačí spustit:

hugo

Obsah adresáře veřejnost/ a bude to vaše stránka.
Ano, mimochodem, pojďme to okamžitě uvést .gignignore:

echo /public > .gitignore

Nezapomeňte potvrdit naše změny:

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

2. Příprava souboru Dockerfile

Je čas definovat strukturu našeho úložiště. Obvykle používám něco jako:

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

  • dockerfiles/ - obsahují adresáře s Dockerfiles a vše potřebné k vytvoření našich docker obrazů.
  • nasadit/ - obsahuje adresáře pro nasazení našich aplikací v Kubernetes

Po cestě tedy vytvoříme náš první Dockerfile 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" ]

Jak vidíte, Dockerfile obsahuje dva Z, tato možnost se nazývá vícestupňová stavba a umožňuje vám z výsledného obrazu dockeru vyloučit vše nepotřebné.
Výsledný obrázek tedy bude obsahovat pouze darkhttpd (odlehčený HTTP server) a veřejnost/ - obsah našeho staticky generovaného webu.

Nezapomeňte potvrdit naše změny:

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

3. Seznámení s kaniko

Jako tvůrce obrázků dockerů jsem se rozhodl použít kaniko, protože ke své práci nepotřebuje docker démona a samotné sestavení lze provést na jakémkoli počítači a uložit mezipaměť přímo do registru, čímž se zbavíte potřeby mít plnohodnotné trvalé úložiště.

Chcete-li vytvořit obrázek, stačí spustit kontejner pomocí kaniko exekutor a předat mu aktuální kontext sestavení, můžete to udělat lokálně pomocí dockeru:

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

Kde registry.gitlab.com/kvaps/docs.example.org/webové stránky - název vašeho obrazu dockeru, po sestavení se automaticky spustí v registru dockeru.

Parametr --mezipaměti umožňuje ukládat vrstvy do mezipaměti v registru dockeru, pro daný příklad budou uloženy registry.gitlab.com/kvaps/docs.example.org/website/cache, ale pomocí parametru můžete zadat jinou cestu --cache-repo.

Snímek obrazovky docker-registru

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

4. Úvod do qbec

Qbec je nástroj pro nasazení, který vám umožňuje deklarativně popsat manifesty vaší aplikace a nasadit je do Kubernetes. Použití Jsonnet jako hlavní syntaxe velmi usnadňuje popis rozdílů pro více prostředí a téměř zcela eliminuje opakování kódu.

To může platit zejména v případech, kdy potřebujete nasadit aplikaci do několika clusterů s různými parametry a chcete je deklarativně popsat v Gitu.

Qbec také umožňuje vykreslovat Helmovy diagramy tak, že jim předáte potřebné parametry a následně s nimi budete pracovat stejným způsobem jako s běžnými manifesty, včetně možnosti na ně aplikovat různé mutace, a to zase eliminuje nutnost používat ChartMuseum. To znamená, že můžete ukládat a vykreslovat grafy přímo z git, kam patří.

Jak jsem již řekl, všechna nasazení uložíme do adresáře nasadit/:

mkdir deploy
cd deploy

Pojďme inicializovat naši první aplikaci:

qbec init website
cd website

Nyní struktura naší aplikace vypadá takto:

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

podívejte se do souboru qbec.yaml:

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

Zde nás zajímá především spec.prostředí, qbec již pro nás vytvořil výchozí prostředí a převzal adresu serveru a jmenný prostor z našeho aktuálního kubeconfig.
Nyní při nasazení do standardní prostředí, qbec se vždy nasadí pouze do zadaného clusteru Kubernetes a do zadaného jmenného prostoru, to znamená, že při nasazení již nemusíte přepínat mezi kontexty a jmennými prostory.
V případě potřeby můžete vždy aktualizovat nastavení v tomto souboru.

Všechna vaše prostředí jsou popsána v qbec.yamla v souboru params.libsonnet, který říká, kde pro ně musíte vzít parametry.

Dále vidíme dva adresáře:

  • komponenty / - zde budou uloženy všechny manifesty pro naši aplikaci, lze je popsat jak v jsonnetu, tak v běžných yaml souborech
  • prostředí/ - zde popíšeme všechny proměnné (parametry) pro naše prostředí.

Ve výchozím nastavení máme dva soubory:

  • environments/base.libsonnet - bude obsahovat společné parametry pro všechna prostředí
  • environments/default.libsonnet - obsahuje parametry předefinované pro prostředí standardní

otevřeme environments/base.libsonnet a tam přidejte parametry pro naši první 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',
    },
  },
}

Vytvořme také naši první komponentu komponenty/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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

V tomto souboru jsme popsali tři entity Kubernetes najednou, jsou to: Rozvinutí, Servis и Ingress. Na přání je můžeme přesunout do různých komponent, ale v této fázi nám stačí jeden.

syntax jsonnet velmi podobný běžnému json, v principu je běžný json již platným jsonnetem, takže zpočátku pro vás může být jednodušší používat online služby, jako je yaml2json převést váš obvyklý yaml na json, nebo pokud vaše komponenty neobsahují žádné proměnné, pak je lze popsat ve formě běžného yaml.

Při práci s jsonnet Důrazně vám doporučuji nainstalovat plugin pro váš editor

Existuje například plugin pro vim vim-jsonnet, který zapne zvýraznění syntaxe a automaticky se spustí jsonnet fmt při každém uložení (vyžaduje instalaci jsonnet).

Vše je připraveno, nyní můžeme začít s nasazením:

Abychom viděli, co máme, běžme:

qbec show default

Na výstupu uvidíte vykreslené yaml manifesty, které budou aplikovány na výchozí cluster.

Skvělé, nyní aplikujte:

qbec apply default

Na výstupu vždy uvidíte, co se ve vašem clusteru udělá, qbec vás požádá o přijetí změn zadáním y můžete potvrdit své záměry.

Hotovo, naše aplikace je nasazena!

Pokud jsou provedeny změny, můžete vždy spustit:

qbec diff default

abyste viděli, jak tyto změny ovlivní aktuální nasazení

Nezapomeňte potvrdit naše změny:

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

5. Vyzkoušejte Gitlab-runner s Kubernetes-executorem

Donedávna jsem používal pouze běžné gitlab-runner na předem připraveném stroji (kontejner LXC) s shell-nebo docker-exekutorem. Zpočátku jsme měli několik těchto běžců globálně definovaných v našem gitlabu. Vytvořili docker obrazy pro všechny projekty.

Jak ale ukázala praxe, tato možnost není nejideálnější, a to jak z hlediska praktičnosti, tak z hlediska bezpečnosti. Mnohem lepší a ideologicky správné je mít pro každý projekt a dokonce i pro každé prostředí nasazené samostatné běžce.

Naštěstí to není vůbec problém, protože teď budeme nasazovat gitlab-runner přímo v rámci našeho projektu přímo v Kubernetes.

Gitlab poskytuje hotový graf kormidla pro nasazení gitlab-runner do Kubernetes. Takže vše, co potřebujete vědět, je registrační token pro náš projekt v Nastavení -> CI / CD -> Runners a předat to kormidlu:

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

Kde:

  • https://gitlab.com je adresa vašeho serveru Gitlab.
  • yga8y-jdCusVDn_t4Wxc - registrační token pro váš projekt.
  • rbac.create=true - dává běžci potřebný počet oprávnění, aby mohl vytvářet pody pro provádění našich úkolů pomocí kubernetes-executor.

Pokud je vše provedeno správně, měli byste v sekci vidět přihlášeného běžce Běžci, v nastavení vašeho projektu.

Snímek obrazovky přidaného běžce

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Je to tak jednoduché? - ano, je to tak jednoduché! Už žádné potíže s ruční registrací běžců, od nynějška se budou běžci vytvářet a ničit automaticky.

6. Nasaďte grafy Helm pomocí QBEC

Protože jsme se rozhodli zvážit gitlab-runner součástí našeho projektu, je čas ji popsat v našem úložišti Git.

Mohli bychom to popsat jako samostatnou komponentu webových stránkách , ale v budoucnu plánujeme nasazení různých kopií webových stránkách velmi často, na rozdíl od gitlab-runner, který bude nasazen pouze jednou na cluster Kubernetes. Pojďme pro to tedy inicializovat samostatnou aplikaci:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Tentokrát nebudeme entity Kubernetes popisovat ručně, ale vezmeme si hotový Helmův graf. Jednou z výhod qbec je schopnost vykreslovat Helmovy grafy přímo z úložiště Git.

Pojďme to povolit pomocí submodulu git:

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

Nyní adresář vendor/gitlab-runner obsahuje náš repozitář s grafem pro gitlab-runner.

Podobným způsobem lze propojit i další úložiště, například celé úložiště s oficiálními grafy https://github.com/helm/charts

Pojďme si součást popsat komponenty/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,
  }
)

První argument k expandHelmTemplate pak předáme cestu k grafu parametry.hodnoty, který přebíráme z parametrů prostředí, pak přichází objekt se kterým

  • název šablony - název vydání
  • jmenný prostor - jmenný prostor předán kormidlu
  • tento soubor - povinný parametr, který předává cestu k aktuálnímu souboru
  • podrobný - ukazuje příkaz šablona kormidla se všemi argumenty při vykreslování grafu

Nyní si popišme parametry pro naši komponentu v 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,
      },
    },
  },
}

Poznámka runnerRegistrationToken načteme z externího souboru secrets/base.libsonnet, pojďme to vytvořit:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Zkontrolujeme, zda vše funguje:

qbec show default

pokud je vše v pořádku, můžeme odstranit naše dříve nasazené prostřednictvím vydání Helm:

helm uninstall gitlab-runner

a nasadit jej, ale prostřednictvím qbec:

qbec apply default

7. Úvod do git-crypt

git-crypt je nástroj, který vám umožní nastavit transparentní šifrování pro vaše úložiště.

V tuto chvíli vypadá naše adresářová struktura pro gitlab-runner takto:

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

Ale ukládání tajemství v Gitu není bezpečné, že? Musíme je tedy správně zašifrovat.

Obvykle to kvůli jedné proměnné ne vždy dává smysl. Můžete přenést tajemství na qbec a prostřednictvím proměnných prostředí vašeho systému CI.
Ale stojí za zmínku, že existují i ​​složitější projekty, které mohou obsahovat mnohem více tajemství, bude extrémně obtížné je všechny protáhnout proměnnými prostředí.

Navíc v tomto případě bych vám nemohl říct o tak úžasném nástroji, jako je git-crypt.

git-crypt Je také výhodná v tom, že umožňuje ukládat celou historii tajemství a také porovnávat, spojovat a řešit konflikty stejným způsobem, jako jsme to dělali v případě Gitu.

První věc po instalaci git-crypt potřebujeme vygenerovat klíče pro naše úložiště:

git crypt init

Pokud máte klíč PGP, můžete se okamžitě přidat jako spolupracovník pro tento projekt:

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

Tímto způsobem můžete vždy dešifrovat toto úložiště pomocí vašeho soukromého klíče.

Pokud nemáte klíč PGP a neočekává se, že jej budete mít, můžete jít jiným způsobem a exportovat klíč projektu:

git crypt export-key /path/to/keyfile

Tedy každý, kdo vlastní export klíčový soubor bude moci dešifrovat vaše úložiště.

Je čas nastavit naše první tajemství.
Připomínám, že jsme stále v adresáři deploy/gitlab-runner/kde máme adresář tajemství/, zašifrujeme všechny soubory v něm, k tomu vytvoříme soubor tajemství/.gitattributes s obsahem jako je tento:

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

Jak je vidět z obsahu, všechny soubory podle masky * proběhne git-crypt, s výjimkou .gitattributes

Můžeme to zkontrolovat spuštěním:

git crypt status -e

Na výstupu získáme seznam všech souborů v úložišti, pro které je šifrování povoleno

To je vše, nyní můžeme bezpečně provést změny:

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

K zablokování úložiště stačí provést:

git crypt lock

a všechny zašifrované soubory se okamžitě změní na binární něco, nebude možné je přečíst.
Chcete-li dešifrovat úložiště, spusťte:

git crypt unlock

8. Vytvořte obrázek sady nástrojů

Obrázek sady nástrojů je obrázek se všemi nástroji, které použijeme k nasazení našeho projektu. Bude ho používat gitlab runner k provádění typických úloh nasazení.

Vše je zde jednoduché, tvoříme nové dockerfiles/toolbox/Dockerfile s obsahem jako je tento:

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

Jak můžete vidět, na tomto obrázku nainstalujeme všechny nástroje, které jsme použili k nasazení naší aplikace. Nepotřebujeme tady, ledaže kubectl, ale možná si s tím budete chtít pohrát při nastavování potrubí.

Abychom mohli komunikovat s Kubernetes a nasazovat se do něj, musíme také nastavit roli pro pody generované gitlab-runner.

Chcete-li to provést, přejděte do adresáře s gitlab-runner'om:

cd deploy/gitlab-runner

a přidat novou součást komponenty/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,
      },
    ],
  },
]

Také popisujeme nové parametry v environments/base.libsonnet, který nyní vypadá takto:

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

Poznámka $.components.rbac.name odkazuje na název pro komponent rbac

Podívejme se, co se změnilo:

qbec diff default

a aplikujte naše změny na Kubernetes:

qbec apply default

Také nezapomeňte odeslat naše změny do 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še první potrubí a sestavování obrázků pomocí značek

V kořenu projektu vytvoříme .gitlab-ci.yml s obsahem jako je tento:

.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

Upozorňujeme, že používáme GIT_SUBMODULE_STRATEGY: normální pro ty úlohy, kde musíte před provedením explicitně inicializovat submoduly.

Nezapomeňte potvrdit naše změny:

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

Myslím, že to můžete klidně nazvat verzí v0.0.1 a přidat značku:

git tag v0.0.1

Značky zavěsíme vždy, když budeme potřebovat vydat novou verzi. Značky v obrázcích Dockeru budou mapovány na značky Git. Každé odeslání s novou značkou inicializuje sestavení obrázku s touto značkou.

Pojďme na to git push --tagsa podívejte se na náš první kanál:

Snímek obrazovky prvního potrubí

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Stojí za zmínku, že sestavení založená na značkách jsou dobrá pro vytváření obrazů dockerů, ale ne pro nasazení aplikace do Kubernetes. Vzhledem k tomu, že nové značky mohou být také přiřazeny ke starým commitům, v tomto případě inicializace kanálu pro ně povede k nasazení staré verze.

K vyřešení tohoto problému je sestavení obrázků dockeru obvykle vázáno na značky a nasazení aplikace do pobočky mistr, ve kterém jsou pevně zakódovány verze shromážděných obrázků. Právě v tomto případě můžete inicializovat rollback jednoduchým návratem mistr- větve.

10. Nasaďte automatizaci

Aby Gitlab-runner dešifroval naše tajemství, musíme exportovat klíč úložiště a přidat jej do našich proměnných prostředí CI:

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

výsledný řetězec uložíme do Gitlabu, proto přejdeme do nastavení našeho projektu:
Nastavení —> CI / CD —> Proměnné

A vytvořte novou proměnnou:

Styl
Klíč
Hodnota
Chráněný
Maskované
Rozsah

File
GITCRYPT_KEY
<your string>
true (v době tréninku můžete false)
true
All environments

Snímek obrazovky přidané proměnné

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Nyní aktualizujme naše .gitlab-ci.yml přidávám k tomu:

.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

Zde jsme povolili některé nové možnosti pro qbec:

  • --root some/app - umožňuje definovat adresář konkrétní aplikace
  • --force:k8s-context __incluster__ - toto je magická proměnná, která říká, že k nasazení dojde ve stejném clusteru, ve kterém běží gtilab-runner. To je nutné, jinak se qbec pokusí najít vhodný server Kubernetes ve vašem kubeconfig
  • -Počkejte - nutí qbec čekat, dokud prostředky, které vytváří, nepřejdou do stavu Připraveno a teprve poté se dokončí s úspěšným výstupním kódem.
  • -Ano - pouze deaktivuje interaktivní shell Jsi si jistá? při nasazení.

Nezapomeňte potvrdit naše změny:

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

A poté git push uvidíme, jak byly naše aplikace nasazeny:

Snímek obrazovky druhého potrubí

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

11. Artefakty a montáž při tlačení na master

Obvykle výše uvedené kroky stačí k vytvoření a poskytování téměř jakékoli mikroslužby, ale nechceme přidávat značku pokaždé, když potřebujeme web aktualizovat. Proto půjdeme dynamičtěji a nastavíme nasazení digestu v hlavní větvi.

Myšlenka je jednoduchá: nyní obraz našeho webových stránkách bude přestavěn pokaždé, když zatlačíte na mistra poté automaticky nasadit do Kubernetes.

Pojďme aktualizovat tyto dvě úlohy v 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"

Upozorňujeme, že jsme přidali pobočku mistr к refs za práci build_web a nyní používáme $CI_COMMIT_REF_NAME místo $CI_COMMIT_TAG, to znamená, že se zbavíme značek v Gitu a nyní vložíme obrázek s názvem větve commitu, která inicializovala váš kanál. Stojí za zmínku, že to bude fungovat také se značkami, což nám umožní ukládat snímky webu s konkrétní verzí v docker-registru.

Když může být název docker tagu pro novou verzi webu nezměněn, stále musíme popsat změny pro Kubernetes, jinak jednoduše znovu nenasadí aplikaci z nového obrázku, protože nezaznamená žádné změny v manifest nasazení.

Možnost --vm:ext-str digest="$DIGEST" for qbec - umožňuje předat externí proměnnou do jsonnet. Chceme, aby naše aplikace byla znovu nasazena v clusteru s každým vydáním. Již nemůžeme používat název značky, který nyní může být nezměněn, protože potřebujeme odkaz na konkrétní verzi obrázku a spustit nasazení, když se změní.

Zde nám pomůže možnost Kaniko uložit výtah obrázku do souboru (volba --digest-file)
Poté tento soubor přeneseme a přečteme v době nasazení.

Pojďme aktualizovat parametry pro naše deploy/website/environments/base.libsonnet který nyní bude vypadat takto:

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

Hotovo, nyní se zapojte mistr inicializuje sestavení obrazu dockeru pro webových stránkách a poté jej nasaďte do Kubernetes.

Nezapomeňte potvrdit naše změny:

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

Zkontrolujte to po git push měli bychom vidět něco takového:

Snímek obrazovky potrubí pro master

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

V zásadě nemusíme znovu nasazovat gitlab-runner s každým stisknutím, pokud se samozřejmě nic nezměnilo v jeho konfiguraci, opravme to v .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/**/*

změny bude sledovat změny v deploy/gitlab-runner/ a spustí naši práci, pouze pokud nějaké budou

Nezapomeňte potvrdit naše změny:

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

git push, to je lepší:

Snímek obrazovky aktualizovaného potrubí

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

12. Dynamická prostředí

Je čas diverzifikovat naše potrubí o dynamická prostředí.

Nejprve aktualizujme úlohu build_web v naší .gitlab-ci.yml, vyjměte z něj blok 👔, což donutí Gitlab, aby jej spustil při každém odevzdání do jakékoli větve:

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/

Poté aktualizujte úlohu deploy_website, přidejte tam blok životní prostředí:

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 Gitlabu umožní přidružit úlohu prod prostředí a zobrazit na něj správný odkaz.

Nyní přidáme další dvě úlohy:

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

Budou spuštěny push do všech větví kromě master a nasadí náhledovou verzi webu.

Vidíme novou možnost pro qbec: --app-tag - umožňuje označovat nasazené verze aplikace a pracovat pouze v rámci této značky, při vytváření a ničení zdrojů v Kubernetes bude qbec fungovat pouze s nimi.
Nemůžeme tedy pro každou recenzi vytvořit samostatné prostředí, ale jednoduše znovu použít to samé.

Zde také používáme qbec aplikovat recenzi, namísto qbec použít výchozí - to je přesně ten okamžik, kdy se pokusíme popsat rozdíly pro naše prostředí (recenze a výchozí):

Přidat recenze prostředí v deploy/website/qbec.yaml

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

Pak to deklarujeme 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

A napište pro něj vlastní parametry 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',
    },
  },
}

Podívejme se také blíže na práci stop_review, spustí se, když je větev odstraněna a používá se tak, aby se na ní gitlab nepokoušel zaplatit GIT_STRATEGY: žádná, později klonujeme mistr-rozvětvete a odstraňte recenzi přes něj.
Trochu matoucí, ale krásnější způsob jsem zatím nenašel.
Alternativní možností by bylo nasazení každé recenze do jmenného prostoru hotelu, který lze vždy celý zbourat.

Nezapomeňte potvrdit naše změny:

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

git push, git checkout -b test, git push test původu, šek:

Snímek obrazovky vytvořených prostředí v Gitlabu

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Všechno funguje? - skvělé, smažte naši testovací větev: git checkout master, git push origin :test, zkontrolujeme, že úlohy pro smazání prostředí fungovaly bez chyb.

Zde chci hned upřesnit, že každý vývojář v projektu může vytvářet větve, může se také měnit .gitlab-ci.yml soubor a přístup k tajným proměnným.
Proto se důrazně doporučuje povolit jejich použití pouze pro chráněné větve, například v mistrnebo vytvořte samostatnou sadu proměnných pro každé prostředí.

13 Kontrola aplikací

Recenze aplikací toto je funkce gitlabu, která vám umožňuje přidat tlačítko pro každý soubor v úložišti, abyste jej mohli rychle zobrazit v nasazeném prostředí.

Aby se tato tlačítka zobrazila, musíte vytvořit soubor .gitlab/route-map.yml a popište v něm všechny transformace cest, v našem případě to bude velmi jednoduché:

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

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

Nezapomeňte potvrdit naše změny:

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

git pusha zkontrolujte:

Snímek obrazovky tlačítka Review App

Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Práce je hotová!

Zdroje projektu:

Děkuji za pozornost, doufám, že se vám to líbilo Vyzkoušejte nové nástroje pro vytváření a automatizaci nasazení v Kubernetes

Zdroj: www.habr.com

Přidat komentář