Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Здраво! Неодамна, беа објавени многу кул алатки за автоматизација и за градење на слики на Docker и за распоредување на Kubernetes. Во овој поглед, решив да си поиграм со GitLab, темелно да ги проучувам неговите способности и, се разбира, да го поставам гасоводот.

Ова дело е инспирирано од веб-страницата kubernetes.io, кој е генериран од изворни кодови автоматски и за секое испратено барање за базен, роботот автоматски генерира верзија за преглед на страницата со вашите промени и обезбедува врска за прегледување.

Се обидов да изградам сличен процес од нула, но целосно изграден на Gitlab CI и бесплатни алатки што сум навикнат да ги користам за распоредување апликации на Kubernetes. Денес конечно ќе ви кажам повеќе за нив.

Написот ќе разговара за алатки како што се:
Хуго, qbec, канико, git-crypt и GitLab CI со создавање на динамични средини.

содржина

  1. Запознајте го Хуго
  2. Подготовка на Dockerfile
  3. Запознавање со Канико
  4. Запознавање со qbec
  5. Пробување на Gitlab-runner со Kubernetes-executor
  6. Распоредување на табели на Helm со qbec
  7. Воведување на git-crypt
  8. Креирање слика на кутијата со алатки
  9. Нашиот прв цевковод и склопување на слики по ознаки
  10. Автоматизација на распоредување
  11. Артефакти и склопување при туркање за совладување
  12. Динамични средини
  13. Прегледајте ги апликациите

1. Запознавање на Хуго

Како пример за нашиот проект, ќе се обидеме да создадеме страница за објавување документација изградена на Hugo. Hugo е генератор на статична содржина.

За оние кои не се запознаени со статичките генератори, ќе ви кажам малку повеќе за нив. За разлика од конвенционалните мотори на веб-локации со база на податоци и некои PHP, кои, кога ги бара корисникот, генерираат страници во лет, статичните генератори се дизајнирани малку поинаку. Тие ви дозволуваат да земете извори, обично збир на датотеки во шаблони за обележување и теми на Markdown, а потоа да ги компајлирате во целосно завршена веб-локација.

Тоа е, како резултат на тоа, ќе добиете структура на директориуми и збир на генерирани HTML-датотеки, кои едноставно можете да ги поставите на кој било евтин хостинг и да добиете работна веб-страница.

Можете да го инсталирате Hugo локално и да го испробате:

Иницијализирање на нова страница:

hugo new site docs.example.org

И во исто време складиштето за git:

cd docs.example.org
git init

Досега, нашата страница е недопрена и за да се појави нешто на неа, прво треба да поврземе тема; темата е само збир на шаблони и одредени правила со кои се генерира нашата страница.

За темата што ќе ја користиме Научете, што, според мое мислење, е совршено прилагодено за локација за документација.

Би сакал да обрнам посебно внимание на фактот дека не треба да ги зачувуваме датотеките со теми во складиштето на нашиот проект; наместо тоа, можеме едноставно да го поврземе користејќи подмодул git:

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

Така, нашето складиште ќе содржи само датотеки директно поврзани со нашиот проект, а поврзаната тема ќе остане како врска до одредено складиште и заложба во него, односно секогаш може да се повлече од оригиналниот извор и да не се плаши од некомпатибилни промени.

Ајде да ја поправиме конфигурацијата config.toml:

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

Веќе во оваа фаза можете да трчате:

hugo server

И на адресата http://localhost:1313/ проверете ја нашата новосоздадена веб-страница, сите промени направени во директориумот автоматски ја ажурираат отворената страница во прелистувачот, многу погодно!

Ајде да се обидеме да создадеме насловна страница во содржина/_индекс.мд:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Слика од екранот на новосоздадената страница

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

За да генерирате локација, само стартувајте:

hugo

Содржина на директориумот публика/ и ќе биде вашата веб-страница.
Да, патем, веднаш да го додадеме .гитинор:

echo /public > .gitignore

Не заборавајте да ги извршите нашите промени:

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

2. Подготовка на Dockerfile

Време е да ја дефинираме структурата на нашето складиште. Јас обично користам нешто како:

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

  • dockerfiles/ — содржи директориуми со Dockerfiles и се што е потребно за градење на нашите Docker слики.
  • распоредување/ — содржи директориуми за распоредување на нашите апликации на Kubernetes

Така, ќе го создадеме нашиот прв Dockerfile по патеката dockerfiles/веб-страница/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" ]

Како што можете да видите, Dockerfile содржи два ОД, оваа функција се нарекува повеќестепена изградба и ви овозможува да исклучите сè што е непотребно од конечната слика на Docker.
Така, конечната слика ќе содржи само темноhttpd (лесен HTTP сервер) и публика/ — содржината на нашата статички генерирана веб-локација.

Не заборавајте да ги извршите нашите промени:

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

3. Запознавање со канико

Како градител на слики докер, решив да користам канико, бидејќи за неговото работење не е потребен докер демон, а самата градба може да се изврши на која било машина и кешот може да се складира директно во регистарот, со што се елиминира потребата да се има полноправно постојано складирање.

За да ја изградите сликата, само стартувајте го контејнерот со канико извршител и префрлете му го тековниот контекст на изградбата; ова може да се направи и локално, преку докер:

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

Каде registry.gitlab.com/kvaps/docs.example.org/website — името на вашата докер-слика; по изградбата, таа автоматски ќе биде лансирана во регистарот на докер.

Параметар -- кеш ви овозможува да ги кеширате слоевите во регистарот на докер; за дадениот пример, тие ќе бидат зачувани во registry.gitlab.com/kvaps/docs.example.org/website/cache, но можете да наведете друга патека користејќи го параметарот -- кеш-репо.

Слика од екранот на докер-регистарот

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

4. Запознавање со qbec

Кјубек е алатка за распоредување која ви овозможува декларативно да ги опишете вашите манифестации на апликацијата и да ги распоредите на Kubernetes. Користењето на Jsonnet како главна синтакса ви овозможува значително да го поедноставите описот на разликите во повеќе средини, а исто така речиси целосно го елиминира повторувањето на кодот.

Ова може да биде особено точно во случаи кога треба да распоредите апликација во неколку кластери со различни параметри и сакате декларативно да ги опишете во Git.

Qbec, исто така, ви овозможува да ги прикажувате табелите на Helm со предавање на потребните параметри и потоа да управувате со нив на ист начин како и редовните манифестации, вклучително и да можете да примените разни мутации на нив, а тоа, пак, ви овозможува да се ослободите од потребата за користете ChartMuseum. Односно, можете да складирате и прикажувате графикони директно од git, каде што припаѓаат.

Како што реков претходно, ќе ги складираме сите распоредувања во директориум распоредување/:

mkdir deploy
cd deploy

Ајде да ја иницијализираме нашата прва апликација:

qbec init website
cd website

Сега структурата на нашата апликација изгледа вака:

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

да ја погледнеме датотеката qbec.yaml:

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

Овде првенствено не интересира спец.средини, qbec веќе создаде стандардна околина за нас и ја зеде адресата на серверот, како и просторот за имиња од нашата актуелна kubeconfig.
Сега кога се распоредува на стандардно околина, qbec секогаш ќе се распоредува само во наведениот кластер Kubernetes и во наведениот именски простор, односно, повеќе не мора да се префрлате помеѓу контексти и простори за имиња за да извршите распоредување.
Доколку е потребно, секогаш можете да ги ажурирате поставките во оваа датотека.

Сите ваши средини се опишани во qbec.yaml, и во датотеката парами.libsonnet, каде што пишува каде да се добијат параметрите за нив.

Следно, гледаме два директориуми:

  • компоненти/ - сите манифестации за нашата апликација ќе бидат зачувани овде; тие може да се опишат и во jsonnet и во обичните yaml датотеки
  • средини/ — овде ќе ги опишеме сите променливи (параметри) за нашите средини.

Стандардно имаме две датотеки:

  • средини/база.libsonnet - ќе содржи заеднички параметри за сите средини
  • околини/стандардно.libsonnet — содржи параметри префрлени за животната средина стандардно

да отвориме средини/база.libsonnet и додадете параметри за нашата прва компонента таму:

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

Ајде да ја создадеме и нашата прва компонента компоненти/веб-страница.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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

Во оваа датотека опишавме три Кубернетес ентитети одеднаш, тоа се: распоредување, Сервис и Целосно. Ако сакавме, можевме да ги ставиме во различни компоненти, но во оваа фаза една ќе ни биде доволна.

синтакса jsonnet е многу сличен на обичниот json, во принцип, обичниот json е веќе валиден jsonnet, така што на почетокот можеби ќе ви биде полесно да користите онлајн услуги како yaml2json да го конвертирате вашиот вообичаен yaml во json или, ако вашите компоненти не содржат никакви променливи, тогаш тие може да се опишат во форма на обичен yaml.

Кога работите со jsonnet Силно препорачувам да инсталирате приклучок за вашиот уредник

На пример, постои приклучок за vim vim-jsonnet, кој го вклучува означувањето на синтаксата и автоматски се извршува jsonnet fmt секој пат кога зачувувате (потребно е инсталирано jsonnet).

Сè е подготвено, сега можеме да започнеме со распоредување:

За да видиме што добивме, да трчаме:

qbec show default

На излезот, ќе видите рендерирани yaml манифестации кои ќе се применат на стандардниот кластер.

Одлично, сега аплицирајте:

qbec apply default

На излезот секогаш ќе видите што ќе се прави во вашиот кластер, qbec ќе ве замоли да се согласите со промените со пишување y ќе можете да ги потврдите вашите намери.

Нашата апликација е подготвена и распоредена!

Ако правите промени, секогаш можете да направите:

qbec diff default

за да видите како овие промени ќе влијаат на тековното распоредување

Не заборавајте да ги извршите нашите промени:

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

5. Пробување на Gitlab-runner со Kubernetes-executor

До неодамна користев само обична gitlab-тркач на претходно подготвена машина (LXC контејнер) со школка или докер-извршител. Првично, имавме неколку такви тркачи глобално дефинирани во нашата gitlab. Тие собраа докер слики за сите проекти.

Но, како што покажа практиката, оваа опција не е најидеална, и во однос на практичноста и безбедноста. Многу е подобро и идеолошки покоректно да се распоредат посебни тркачи за секој проект, па дури и за секоја средина.

За среќа, тоа воопшто не е проблем, бидејќи сега ќе се распоредиме gitlab-тркач директно како дел од нашиот проект токму во Кубернетес.

Gitlab обезбедува готова шема на кормило за распоредување на gitlab-runner на Kubernetes. Значи, сè што треба да направите е да дознаете токен за регистрација за нашиот проект во Поставки -> CI / CD -> Тркачи и префрли го на кормилото:

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

Каде што:

  • https://gitlab.com — адресата на вашиот Gitlab сервер.
  • yga8y-jdCusVDn_t4Wxc — токен за регистрација за вашиот проект.
  • rbac.создаде=точно — му дава на тркачот потребната количина на привилегии за да може да создава подлоги за извршување на нашите задачи користејќи kubernetes-executor.

Ако сè е направено правилно, треба да видите регистриран тркач во делот Тркачите, во поставките на вашиот проект.

Слика од екранот на додадениот тркач

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Дали е толку едноставно? - Да, толку е едноставно! Нема повеќе проблеми со рачно регистрирање на тркачите, отсега па натаму тркачите ќе се креираат и уништуваат автоматски.

6. Распоредете ги табелите на Helm со QBEC

Бидејќи решивме да размислиме gitlab-тркач дел од нашиот проект, време е да го опишеме во нашето складиште на Git.

Можеме да го опишеме како посебна компонента , но во иднина планираме да распоредиме различни копии многу често, за разлика од gitlab-тркач, кој ќе биде распореден само еднаш по кластер на Kubernetes. Значи, ајде да иницијализираме посебна апликација за тоа:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Овој пат нема рачно да ги опишуваме ентитетите на Кубернетес, туку ќе земеме готова шема на Хелм. Една од предностите на qbec е можноста за прикажување на табелите на Helm директно од складиштето на Git.

Ајде да го поврземе користејќи го подмодулот git:

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

Сега директориумот продавач/gitlab-runner Имаме складиште со графикон за gitlab-runner.

На сличен начин, можете да поврзете други складишта, на пример, целото складиште со официјални графикони https://github.com/helm/charts

Ајде да ја опишеме компонентата компоненти/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,
  }
)

Првиот аргумент за прошируваХелмШаблон го поминуваме патот до табелата, тогаш парами.вредности, кои ги земаме од параметрите на околината, а потоа доаѓа објектот со

  • име Шаблон - име на издавање
  • именски простор — именскиот простор префрлен на кормилото
  • оваа Датотека — потребен параметар што ја поминува патеката до тековната датотека
  • гласно - ја покажува командата шаблон за кормило со сите аргументи при рендерирање на графиконот

Сега да ги опишеме параметрите за нашата компонента во средини/база.libsonnet:

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

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

Обрни внимание runnerRegistrationToken земаме од надворешна датотека тајни/база.libsonnet, ајде да го создадеме:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Ајде да провериме дали сè работи:

qbec show default

ако сè е во ред, тогаш можеме да го избришеме нашето претходно распоредено издание преку Helm:

helm uninstall gitlab-runner

и распореди го на ист начин, но преку qbec:

qbec apply default

7. Вовед во git-crypt

Git-crypt е алатка која ви овозможува да поставите транспарентно шифрирање за вашето складиште.

Во моментов, нашата структура на директориуми за gitlab-runner изгледа вака:

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

Но, складирањето тајни во Git не е безбедно, нели? Затоа треба да ги шифрираме правилно.

Обично, за доброто на една променлива, ова не секогаш има смисла. Можете да ги пренесете тајните на qbec и преку променливите на околината на вашиот CI систем.
Но, вреди да се напомене дека има и посложени проекти кои можат да содржат многу повеќе тајни; пренесувањето на сите нив преку променливите на животната средина ќе биде исклучително тешко.

Покрај тоа, во овој случај не би можел да ви кажам за таква прекрасна алатка како git-crypt.

git-crypt Погодно е и по тоа што ви овозможува да ја зачувате целата историја на тајни, како и да споредувате, спојувате и решавате конфликти на ист начин како што сме навикнати да правиме во случајот со Git.

Првото нешто по инсталацијата git-crypt треба да генерираме клучеви за нашето складиште:

git crypt init

Ако имате PGP клуч, тогаш можете веднаш да се додадете себеси како соработник за овој проект:

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

На овој начин секогаш можете да го дешифрирате ова складиште користејќи го вашиот приватен клуч.

Ако немате PGP клуч и не го очекувате, тогаш можете да одите на друг начин и да го извезете клучот на проектот:

git crypt export-key /path/to/keyfile

Така, секој што има извезено клучна датотека ќе може да го дешифрира вашето складиште.

Време е да ја поставиме нашата прва тајна.
Да ве потсетам дека сè уште сме во именикот распореди/gitlab-runner/, каде што имаме директориум тајни/, ајде да ги криптираме сите датотеки во него, за ова ќе создадеме датотека тајни/.гитатрибути со следнава содржина:

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

Како што може да се види од содржината, сите датотеки се маскирани * ќе се вози низ git-crypt, освен повеќето .гитатрибути

Можеме да го провериме ова со трчање:

git crypt status -e

Излезот ќе биде список на сите датотеки во складиштето за кои е овозможено шифрирање

Тоа е сè, сега можеме безбедно да ги извршиме нашите промени:

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

За да блокирате складиште, само стартувајте:

git crypt lock

и веднаш сите шифрирани датотеки ќе се претворат во бинарно нешто, ќе биде невозможно да се прочитаат.
За да го дешифрирате складиштето, извршете:

git crypt unlock

8. Направете слика од кутијата со алатки

Сликата на кутијата со алатки е слика со сите алатки што ќе ги користиме за да го распоредиме нашиот проект. Ќе се користи од страна на Gitlab тркачот за извршување на типични задачи за распоредување.

Сè е едноставно овде, ајде да создадеме ново dockerfiles/Toolbox/Dockerfile со следнава содржина:

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

Како што можете да видите, на оваа слика ги инсталираме сите алатки што ги користевме за распоредување на нашата апликација. Не ни треба овде освен ако кубектел, но можеби ќе сакате да си играте со него за време на фазата на поставување на гасоводот.

Исто така, за да можеме да комуницираме со Kubernetes и да се распоредиме на него, треба да конфигурираме улога за pods генерирани од gitlab-runner.

За да го направите ова, ајде да одиме во директориумот со gitlab-runner:

cd deploy/gitlab-runner

и додадете нова компонента компоненти/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,
      },
    ],
  },
]

Ќе ги опишеме и новите параметри во средини/база.libsonnet, кој сега изгледа вака:

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

Обрни внимание $.components.rbac.name се однесува на името за компонента рбац

Ајде да провериме што се смени:

qbec diff default

и примени ги нашите промени во Kubernetes:

qbec apply default

Исто така, не заборавајте да ги извршите нашите промени во 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. Нашиот прв цевковод и склопување на слики по ознаки

Во основата на проектот ќе создадеме .gitlab-ci.yml со следнава содржина:

.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

Ве молиме имајте предвид дека користиме GIT_SUBMODULE_STRATEGY: нормално за оние работни места каде што треба експлицитно да ги иницијализирате подмодулите пред извршувањето.

Не заборавајте да ги извршите нашите промени:

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

Мислам дека можеме безбедно да го наречеме ова верзија v0.0.1 и додадете ја ознаката:

git tag v0.0.1

Ќе додаваме ознаки секогаш кога ќе треба да објавиме нова верзија. Ознаките во сликите на Docker ќе бидат поврзани со ознаките Git. Секое притискање со нова ознака ќе го иницијализира создавањето на слики со оваа ознака.

Ајде да го направиме тоа git push --тагови, и да го погледнеме нашиот прв гасовод:

Слика од екранот на првиот гасовод

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Вреди да се привлече вашето внимание на фактот дека склопувањето по ознаки е погодно за градење на докер слики, но не е погодно за распоредување апликација на Кубернет. Бидејќи новите ознаки може да се доделат на старите обврзници, во овој случај, иницијализирањето на гасоводот за нив ќе доведе до распоредување на старата верзија.

За да се реши овој проблем, обично изградбата на докер слики е врзана за ознаки, а распоредувањето на апликацијата во гранка господар, во која верзии на собраните слики се хардкодирани. Ова е местото каде што можете да го иницијализирате враќањето со едноставно враќање господар-гранки.

10. Автоматизација на распоредувањето

За да може Gitlab-runner да ги дешифрира нашите тајни, ќе треба да го извеземе клучот за складиште и да го додадеме во нашите променливи на околината CI:

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

Ќе ја зачуваме добиената линија во Gitlab; за да го направиме ова, да одиме до нашите поставки за проектот:
Поставки -> CI / CD -> Променливи

И ајде да создадеме нова променлива:

тип
Клучни
Вредност
заштитени
маскирани
Опсегот

File
GITCRYPT_KEY
<your string>
true (за време на обуката можете false)
true
All environments

Слика од екранот на додадената променлива

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Сега да ја ажурираме нашата .gitlab-ci.yml додавајќи на тоа:

.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

Овде овозможивме неколку нови опции за qbec:

  • -- root some/app — ви овозможува да го одредите директориумот на одредена апликација
  • --force:k8s-context __incluster__ - ова е магична променлива која вели дека распоредувањето ќе се случи во истиот кластер во кој работи gtilab-runner. Ова е неопходно затоа што во спротивно, qbec ќе се обиде да најде соодветен сервер за Kubernetes во вашиот kubeconfig
  • -- почекај — го принудува qbec да почека додека ресурсите што ги создава не влезат во подготвена состојба и дури потоа да излезе со успешен излезен код.
  • — да - едноставно ја оневозможува интерактивната школка Дали си сигурен? кога се распоредени.

Не заборавајте да ги извршите нашите промени:

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

И потоа git push ќе видиме како се распоредени нашите апликации:

Слика од екранот на вториот гасовод

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

11. Артефакти и склопување при туркање за совладување

Вообичаено, чекорите опишани погоре се доволни за да се изгради и испорача речиси секоја микроуслуга, но не сакаме да додаваме ознака секогаш кога ќе треба да ја ажурираме страницата. Затоа, ќе земеме подинамичен пат и ќе поставиме распоредување на дигестот во главната гранка.

Идејата е едноставна: сега сликата на нашата ќе се обновува секој пат кога ќе се втурнете во господар, а потоа автоматски се распореди на Кубернетес.

Ајде да ги ажурираме овие две работни места во нашата .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"

Ве молиме имајте предвид дека додадовме нишка господар к реф за работни места build_website и сега користиме $CI_COMMIT_REF_NAME наместо $CI_COMMIT_TAG, односно, ние сме одврзани од ознаките во Git и сега ќе туркаме слика со името на гранката на commit што го иницијализираше гасоводот. Вреди да се напомене дека ова ќе работи и со ознаки, што ќе ни овозможи да зачуваме снимки од страница со одредена верзија во докер-регистарот.

Кога името на докер-ознаката за нова верзија на страницата може да биде непроменето, сепак треба да ги опишеме промените на Kubernetes, инаку едноставно нема да ја прераспореди апликацијата од новата слика, бидејќи нема да забележи никакви промени во манифест за распоредување.

Опција —vm:ext-str дигест=”$DIGEST” за qbec - ви овозможува да пренесете надворешна променлива на jsonnet. Сакаме да се прераспореди во кластерот со секое издание на нашата апликација. Веќе не можеме да го користиме името на ознаката, кое сега може да биде непроменливо, бидејќи треба да бидеме врзани за одредена верзија на сликата и да го активираме распоредувањето кога ќе се промени.

Овде ќе ни помогне способноста на Канико да зачува дигестирана слика во датотека (опција --дигест-датотека)
Потоа ќе ја пренесеме оваа датотека и ќе ја прочитаме во моментот на распоредување.

Ајде да ги ажурираме параметрите за нашите deploy/website/environments/base.libsonnet кој сега ќе изгледа вака:

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

Готово, сега било какво обврзување господар ја иницијализира изградбата на докер сликата за , а потоа распоредете го на Кубернетес.

Не заборавајте да ги извршите нашите промени:

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

Ќе провериме подоцна git push треба да видиме вакво нешто:

Слика од екранот на гасоводот за господар

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Во принцип, не треба да го прераспоредуваме gitlab-runner со секое притискање, освен ако, се разбира, ништо не се променило во неговата конфигурација, ајде да го поправиме во .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/**/*

промени ќе ви овозможи да ги следите промените во распореди/gitlab-runner/ и ќе ја активира нашата работа само доколку ги има

Не заборавајте да ги извршите нашите промени:

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

git push, тоа е подобро:

Слика од екранот на ажурираниот гасовод

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

12. Динамични средини

Време е да го диверзифицираме нашиот гасовод со динамични средини.

Прво, да ја ажурираме работата build_website во нашата .gitlab-ci.yml, отстранувајќи го блокот од него само, што ќе го принуди Gitlab да го активира на кое било обврзување на која било гранка:

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/

Потоа ажурирајте ја работата deploy_website, додадете блок таму животната средина:

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"

Ова ќе му овозможи на Gitlab да ја поврзе работата со prod околина и прикажете ја точната врска до неа.

Сега да додадеме уште две работни места:

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

Тие ќе бидат лансирани по притискање до која било гранка освен мастер и ќе ја распоредат верзијата за преглед на страницата.

Гледаме нова опција за qbec: --апликација-ознака — ви овозможува да ги означите распоредените верзии на апликацијата и да работите само во рамките на оваа ознака; кога креирате и уништувате ресурси во Kubernetes, qbec ќе работи само со нив.
На овој начин не можеме да создадеме посебна средина за секој преглед, туку едноставно повторно да ја користиме истата.

Овде ние исто така користиме qbec примени преглед, наместо qbec примени стандардно - ова е токму моментот кога ќе се обидеме да ги опишеме разликите за нашите средини (преглед и стандардно):

Додај преглед средина во deploy/website/qbec.yaml

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

Потоа ќе го објавиме 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

И запишете ги сопствените параметри за него во 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',
    },
  },
}

Ајде да го разгледаме подетално и jobu стоп_преглед, ќе се активира кога гранката е избришана и за да gitlab не се обидува да ја наплати се користи GIT_STRATEGY: нема, подоцна клонираме господар-огранок и брише преглед преку него.
Малку е збунувачки, но сè уште не сум нашол поубав начин.
Алтернативна опција би била да се распореди секоја рецензија во именскиот простор на хотелот, кој секогаш може целосно да се уништи.

Не заборавајте да ги извршите нашите промени:

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

git push, git checkout -b тест, тест за потекло на git push, проверете:

Слика од екранот на создадените средини во Gitlab

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Сè работи? - одлично, избришете ја нашата тест гранка: господар на исходот од гит, git push origin :тест, проверуваме дали задачите за бришење на околината функционирале без грешки.

Овде би сакал веднаш да појаснам дека секој развивач во проект може да создаде гранки, тој исто така може да се промени .gitlab-ci.yml датотека и пристап до тајните променливи.
Затоа, строго се препорачува да се дозволи нивна употреба само за заштитени гранки, на пример во господар, или креирајте посебен сет на променливи за секоја средина.

13. Прегледајте ги апликациите

Прегледајте ги апликациите Ова е функција на GitLab која ви овозможува да додадете копче за секоја датотека во складиштето за брзо да ја видите во распоредена околина.

За да се појават овие копчиња, треба да креирате датотека .gitlab/route-map.yml и опишете ги сите трансформации на патеката во него; во нашиот случај тоа ќе биде многу едноставно:

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

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

Не заборавајте да ги извршите нашите промени:

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

git pushи проверете:

Слика од екранот на копчето Преглед на апликацијата

Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Работата е завршена!

Извори на проектот:

Ви благодарам за вниманието, се надевам дека ви се допадна Испробување нови алатки за градење и автоматизирање на распоредувањето во Кубернетес

Извор: www.habr.com

Додадете коментар