Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Salam! Son zamanlarda həm Docker şəkillərini yaratmaq, həm də Kubernetes-də yerləşdirmək üçün çoxlu sərin avtomatlaşdırma alətləri buraxılmışdır. Bu baxımdan mən Gitlab ilə oynamaq, onun imkanlarını necə öyrənmək və təbii ki, boru kəməri qurmaq qərarına gəldim.

Bu saytdan ilhamlanıb kubernetes.io-dən yaranır mənbə kodları avtomatik olaraq və göndərilən hər bir çəkmə sorğusu üçün robot avtomatik olaraq dəyişikliklərinizlə saytın önizləmə versiyasını yaradır və baxış üçün keçid təqdim edir.

Bənzər bir prosesi sıfırdan qurmağa çalışdım, lakin tamamilə Gitlab CI və Kubernetes-də tətbiqləri yerləşdirmək üçün istifadə etdiyim pulsuz alətlər üzərində quruldum. Bu gün nəhayət sizə onlar haqqında daha çox məlumat verəcəyəm.

Məqalədə aşağıdakı kimi vasitələrə toxunulacaq:
Hugo, qbec, kaniko, git-crypt и GitLab CI dinamik mühitlərin yaradılması ilə.

Məzmun

  1. Hüqo ilə tanış olmaq
  2. Dockerfile hazırlanır
  3. Kaniko ilə tanış olmaq
  4. Qbec-ə giriş
  5. Gitlab-runner Kubernetes-icraçı ilə sınaqdan keçirilir
  6. Qbec ilə Helm qrafiklərini yerləşdirin
  7. Git-crypt-ə giriş
  8. Alətlər qutusu şəkli yaradın
  9. İlk boru kəmərimiz və şəkillərin etiketlərlə yığılması
  10. Avtomatlaşdırma tətbiq edin
  11. Master itələyərkən artefaktlar və montaj
  12. Dinamik mühitlər
  13. Proqramları nəzərdən keçirin

1. Hüqonu tanımaq

Layihəmizə bir nümunə olaraq, Hugo üzərində qurulmuş bir sənəd nəşri saytı yaratmağa çalışacağıq. Hugo statik məzmun generatorudur.

Statik generatorlarla tanış olmayanlar üçün onlar haqqında bir az daha ətraflı məlumat verəcəyəm. İstifadəçinin tələb etdiyi zaman səhifələr yaradan verilənlər bazası və bir növ php olan adi sayt mühərriklərindən fərqli olaraq, statik generatorlar bir az fərqli şəkildə yerləşdirilir. Onlar sizə mənbə kodunu, adətən Markdown işarələmə və tema şablonlarında bir sıra faylları götürməyə, sonra onları tamamilə hazır sayta tərtib etməyə imkan verir.

Yəni, çıxışda siz sadəcə olaraq istənilən ucuz hostinqə yükləyə və işləyən sayt əldə edə biləcəyiniz bir kataloq strukturu və yaradılan html faylları dəsti əldə edəcəksiniz.

Siz Hugo-nu yerli olaraq quraşdırıb sınaqdan keçirə bilərsiniz:

Yeni sayt işə salınır:

hugo new site docs.example.org

Və eyni zamanda git deposu:

cd docs.example.org
git init

İndiyə qədər saytımız təmizdir və orada nəyinsə görünməsi üçün əvvəlcə mövzunu birləşdirməliyik, mövzu sadəcə olaraq saytımızın yaradıldığı şablonlar və müəyyən edilmiş qaydalar toplusudur.

Mövzu olaraq istifadə edəcəyik Öyrənmək, mənim fikrimcə, sənədləri olan bir sayt üçün ən uyğun olanıdır.

Mən xüsusi diqqət yetirmək istərdim ki, bizim layihəmizin repozitoriyasında mövzu fayllarını saxlamağa ehtiyac yoxdur, bunun əvəzinə biz sadəcə onu istifadə edərək birləşdirə bilərik. git alt modulu:

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

Beləliklə, anbarımızda yalnız birbaşa layihəmizlə əlaqəli fayllar olacaq və əlaqəli mövzu müəyyən bir depoya keçid və oradakı öhdəlik kimi qalacaq, yəni həmişə orijinal mənbədən çıxarıla bilər və qorxmur. uyğun olmayan dəyişikliklər.

Gəlin konfiqurasiyanı düzəldək config.toml:

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

Artıq bu mərhələdə siz qaça bilərsiniz:

hugo server

Və ünvanda http://localhost:1313/ yeni yaradılmış saytımızı yoxlayın, kataloqda edilən bütün dəyişikliklər brauzerdə açıq səhifəni avtomatik olaraq yeniləyir, çox rahatdır!

Gəlin bir başlıq səhifəsi yaratmağa çalışaq content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

Yeni yaradılmış səhifənin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Sayt yaratmaq üçün sadəcə işləyin:

hugo

Kataloq məzmunu ictimai/ və saytınız olacaq.
Bəli, yeri gəlmişkən, onu dərhal daxil edək .gitignore:

echo /public > .gitignore

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

2. Dockerfile-nin hazırlanması

Anbarımızın strukturunu müəyyənləşdirməyin vaxtı gəldi. Adətən mən belə bir şey istifadə edirəm:

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

  • dockerfiles/ - Dockerfiles ilə qovluqları və docker şəkillərimizi yaratmaq üçün lazım olan hər şeyi ehtiva edir.
  • yerləşdirmək/ - tətbiqlərimizi Kubernetes-də yerləşdirmək üçün qovluqları ehtiva edir

Beləliklə, yol boyu ilk Dockerfaylımızı yaradacağıq 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" ]

Gördüyünüz kimi, Dockerfile ikidən ibarətdir DAN, bu ehtimal deyilir çoxmərhələli tikinti və sizə lazımsız hər şeyi son docker görüntüsündən çıxarmağa imkan verir.
Beləliklə, son şəkil yalnız ehtiva edəcəkdir qaranlıqhttpd (yüngül HTTP server) və ictimai/ - statik olaraq yaradılan saytımızın məzmunu.

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

3. Kaniko ilə tanış olmaq

Docker şəkillərinin qurucusu olaraq istifadə etmək qərarına gəldim kaniko, çünki işləmək üçün docker demonu tələb olunmur və montaj özü istənilən maşında həyata keçirilə bilər və keşi birbaşa reyestrdə saxlaya bilər və bununla da tam hüquqlu davamlı saxlama ehtiyacından qurtulur.

Təsviri yaratmaq üçün sadəcə konteyneri işlədin kaniko icraçısı və cari qurma kontekstini ona ötürsəniz, bunu yerli olaraq, docker vasitəsilə edə bilərsiniz:

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

Harada? registry.gitlab.com/kvaps/docs.example.org/website - docker təsvirinizin adı, qurulduqdan sonra o, avtomatik olaraq docker reyestrində işə salınacaq.

Parametr --gizli yer docker reyestrində təbəqələri keşləməyə imkan verir, verilən nümunə üçün onlar saxlanılacaq registry.gitlab.com/kvaps/docs.example.org/website/cache, lakin parametr ilə başqa bir yol təyin edə bilərsiniz --cache-repo.

Docker-registrinin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

4. Qbec-ə giriş

Qbec tətbiq manifestlərinizi deklarativ şəkildə təsvir etməyə və onları Kubernetes-də yerləşdirməyə imkan verən yerləşdirmə vasitəsidir. Jsonnet-in əsas sintaksis kimi istifadəsi çoxsaylı mühitlər üçün fərqləri təsvir etməyi çox asanlaşdırır və həmçinin kod təkrarını demək olar ki, tamamilə aradan qaldırır.

Bu, xüsusilə tətbiqi müxtəlif parametrləri olan bir neçə klasterə yerləşdirməli olduğunuz və onları Git-də deklarativ şəkildə təsvir etmək istədiyiniz hallarda doğru ola bilər.

Qbec həmçinin sizə lazımi parametrləri ötürməklə Helm diaqramlarını göstərməyə və daha sonra onlara müxtəlif mutasiyalar tətbiq etmək imkanı daxil olmaqla, müntəzəm manifestlərlə eyni şəkildə işləməyə imkan verir və bu da öz növbəsində ChartMuseum-dan istifadə ehtiyacını aradan qaldırır. Yəni siz diaqramları aid olduqları git-dən birbaşa saxlaya və göstərə bilərsiniz.

Daha əvvəl dediyim kimi, biz bütün yerləşdirmələri kataloqda saxlayacağıq yerləşdirmək/:

mkdir deploy
cd deploy

Gəlin ilk tətbiqimizi işə salaq:

qbec init website
cd website

İndi tətbiqimizin strukturu belə görünür:

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

fayla baxın qbec.yaml:

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

Burada ilk növbədə bizi maraqlandırır spec.mühitlər, qbec artıq bizim üçün standart mühit yaratdı və server ünvanını və ad sahəsini hazırkı kubeconfig-dən götürdü.
İndi yerləşdirərkən default mühitdə, qbec həmişə yalnız müəyyən edilmiş Kubernetes klasterinə və müəyyən edilmiş ad sahəsinə yerləşdirəcək, yəni yerləşdirmək üçün artıq kontekstlər və ad məkanları arasında keçid etməli deyilsiniz.
Lazım gələrsə, bu fayldakı parametrləri həmişə yeniləyə bilərsiniz.

Bütün mühitləriniz təsvir edilmişdir qbec.yaml, və faylda params.libsonnet, onlar üçün parametrləri haradan götürməyiniz lazım olduğunu söyləyir.

Sonra iki qovluğu görürük:

  • komponentlər / - tətbiqimiz üçün bütün manifestlər burada saxlanılacaq, onları həm jsonnetdə, həm də adi yaml fayllarında təsvir etmək olar
  • mühitlər/ - burada mühitlərimiz üçün bütün dəyişənləri (parametrləri) təsvir edəcəyik.

Varsayılan olaraq iki faylımız var:

  • mühitlər/base.libsonnet - bütün mühitlər üçün ümumi parametrləri ehtiva edəcək
  • mühitlər/default.libsonnet - ətraf mühit üçün yenidən təyin edilmiş parametrləri ehtiva edir default

açaq mühitlər/base.libsonnet və oraya ilk komponentimiz üçün parametrlər əlavə edin:

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

Gəlin ilk komponentimizi də yaradaq komponentlər/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,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

Bu faylda bir anda üç Kubernetes obyektini təsvir etdik, bunlar: Deployment, xidmət и Girme. İstəsəniz, onları müxtəlif komponentlərə köçürə bilərdik, lakin bu mərhələdə bizim üçün biri kifayətdir.

sintaksis jsonnet adi json-a çox bənzəyir, prinsipcə, adi json artıq etibarlı jsonnetdir, ona görə də əvvəlcə kimi onlayn xidmətlərdən istifadə etmək sizin üçün daha asan ola bilər. yaml2json adi yamlınızı json-a çevirmək üçün və ya komponentlərinizdə heç bir dəyişən yoxdursa, onları adi yaml şəklində təsvir etmək olar.

İlə işləyərkən jsonnet Mən sizə redaktorunuz üçün plagin quraşdırmağı məsləhət görürəm

Məsələn, vim üçün bir plagin var vim-jsonnet, bu, sintaksisin vurğulanmasını yandırır və avtomatik icra edir jsonnet fmt hər saxlamada (jsonnet-in quraşdırılmasını tələb edir).

Hər şey hazırdır, indi yerləşdirməyə başlaya bilərik:

Nə əldə etdiyimizi görmək üçün qaçaq:

qbec show default

Çıxışda siz standart klasterə tətbiq olunacaq göstərilən yaml manifestlərini görəcəksiniz.

Əla, indi müraciət edin:

qbec apply default

Çıxışda siz həmişə klasterinizdə nə ediləcəyini görəcəksiniz, qbec yazaraq dəyişiklikləri qəbul etməyinizi xahiş edəcək. y niyyətlərinizi təsdiq edə bilərsiniz.

Bitdi, indi tətbiqimiz yerləşdirildi!

Dəyişikliklər edilərsə, hər zaman işlədə bilərsiniz:

qbec diff default

bu dəyişikliklərin cari yerləşdirməyə necə təsir edəcəyini görmək

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

5. Gitlab-runner-i Kubernetes-icraçı ilə sınayın

Son vaxtlara qədər mən yalnız müntəzəm istifadə etmişəm gitlab-runner qabıq və ya docker-icraçı ilə əvvəlcədən hazırlanmış maşında (LXC konteyneri). Əvvəlcə gitlabımızda qlobal olaraq müəyyən edilmiş bu qaçışçıların bir neçəsi var idi. Bütün layihələr üçün docker şəkilləri yaratdılar.

Ancaq təcrübənin göstərdiyi kimi, bu seçim həm praktiklik, həm də təhlükəsizlik baxımından ən ideal deyil. Hər bir layihə və hətta hər bir mühit üçün ayrı-ayrı qaçışçıların təyin edilməsi daha yaxşı və ideoloji cəhətdən düzgündür.

Xoşbəxtlikdən, bu heç də problem deyil, çünki indi yerləşdirəcəyik gitlab-runner birbaşa Kubernetesdəki layihəmizin bir hissəsi kimi.

Gitlab, gitlab-runner-i Kubernetes-ə yerləşdirmək üçün hazır sükan cədvəlini təqdim edir. Beləliklə, bilməli olduğunuz şey budur qeyd işarəsi layihəmiz üçün Parametrlər -> CI / CD -> Qaçışlar və sükan arxasına keçin:

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

Harada:

  • https://gitlab.com Gitlab serverinizin ünvanıdır.
  • yga8y-jdCusVDn_t4Wxc - layihəniz üçün qeydiyyat nişanı.
  • rbac.create=true - qaçışçıya kubernetes-icraçıdan istifadə edərək tapşırıqlarımızı yerinə yetirmək üçün podlar yarada bilmək üçün lazımi sayda imtiyazlar verir.

Hər şey düzgün aparılırsa, bölmədə qeydiyyatdan keçmiş idmançını görməlisiniz Runners, layihə parametrlərinizdə.

Əlavə edilmiş qaçışçının ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Bu qədər sadədir? - bəli, bu qədər sadədir! Qaçışçıların əl ilə qeydiyyata alınması ilə bağlı artıq əngəl yoxdur, bundan sonra qaçışçılar avtomatik olaraq yaradılacaq və məhv ediləcək.

6. QBEC ilə Helm qrafiklərini yerləşdirin

Biz düşünməyə qərar verdiyimizdən gitlab-runner layihəmizin bir hissəsidir, onu Git depomuzda təsvir etməyin vaxtı gəldi.

Biz onu ayrı bir komponent kimi təsvir edə bilərik veb, lakin gələcəkdə fərqli nüsxələri yerləşdirməyi planlaşdırırıq veb çox tez-tez, fərqli olaraq gitlab-runner, hər Kubernetes klasterinə yalnız bir dəfə yerləşdiriləcək. Beləliklə, bunun üçün ayrıca bir tətbiq işə salaq:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

Bu dəfə biz Kubernetes obyektlərini əl ilə təsvir etməyəcəyik, lakin hazır Helm diaqramını götürəcəyik. Qbec-in üstünlüklərindən biri də Helm diaqramlarını birbaşa Git deposundan göstərmək imkanıdır.

git submodulundan istifadə edərək onu aktiv edək:

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

İndi kataloq satıcı/gitlab-runner gitlab-runner üçün diaqramı olan depomuzu ehtiva edir.

Digər depolar oxşar şəkildə birləşdirilə bilər, məsələn, rəsmi diaqramlarla bütün depo https://github.com/helm/charts

Komponenti təsvir edək komponentlər/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,
  }
)

İlk arqument HelmŞablonunu genişləndirin sonra diaqrama gedən yolu keçirik parametrlər.dəyərlər, mühit parametrlərindən aldığımız, daha sonra obyekt ilə gəlir

  • ad Şablon - buraxılış adı
  • ad sahəsi - ad sahəsi sükan arxasına keçdi
  • bu Fayl - cari faylın yolunu keçən tələb olunan parametr
  • geniş - əmri göstərir sükan şablonu qrafiki göstərərkən bütün arqumentlərlə

İndi komponentimiz üçün parametrləri təsvir edək mühitlər/base.libsonnet:

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

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

Xahiş edirik runnerRegistrationToken xarici fayldan əldə edirik secrets/base.libsonnet, gəlin onu yaradaq:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

Hər şeyin işlədiyini yoxlayaq:

qbec show default

hər şey qaydasındadırsa, o zaman Helm buraxılışı ilə əvvəllər yerləşdirdiyimizi silə bilərik:

helm uninstall gitlab-runner

və yerləşdirin, lakin qbec vasitəsilə:

qbec apply default

7. Git-crypt-ə giriş

git-crypt deponuz üçün şəffaf şifrələmə qurmağa imkan verən bir vasitədir.

Hazırda gitlab-runner üçün kataloq strukturumuz belə görünür:

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

Ancaq Git-də sirləri saxlamaq təhlükəsiz deyil, elə deyilmi? Beləliklə, biz onları düzgün şəkildə şifrələməliyik.

Adətən bir dəyişən üçün bu həmişə məna kəsb etmir. Siz sirləri köçürə bilərsiniz qbec və CI sisteminizin mühit dəyişənləri vasitəsilə.
Ancaq qeyd etmək lazımdır ki, daha çox sirləri ehtiva edə bilən daha mürəkkəb layihələr də var, onların hamısını mühit dəyişənləri vasitəsilə ötürmək olduqca çətin olacaq.

Bundan əlavə, bu vəziyyətdə sizə belə gözəl bir vasitə haqqında danışa bilməyəcəkdim git-crypt.

git-crypt Həm də rahatdır ki, o, sirlərin bütün tarixini saxlamağa, həmçinin Git vəziyyətində etdiyimiz kimi münaqişələri müqayisə etməyə, birləşdirməyə və həll etməyə imkan verir.

Quraşdırıldıqdan sonra ilk şey git-crypt depomuz üçün açarlar yaratmalıyıq:

git crypt init

PGP açarınız varsa, dərhal özünüzü bu layihə üçün əməkdaş kimi əlavə edə bilərsiniz:

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

Bu yolla siz həmişə şəxsi açarınızdan istifadə edərək bu deponun şifrəsini aça bilərsiniz.

Əgər PGP açarınız yoxdursa və gözlənilmirsə, o zaman başqa yolla gedə və layihə açarını ixrac edə bilərsiniz:

git crypt export-key /path/to/keyfile

Beləliklə, ixracat sahibi olan hər kəs açar faylı repozitorunuzun şifrəsini aça biləcək.

İlk sirrimizi qurmağın vaxtı gəldi.
Nəzərinizə çatdırım ki, biz hələ də kataloqdayıq deploy/gitlab-runner/bir kataloqumuz var sirr/, içindəki bütün faylları şifrələyək, bunun üçün fayl yaradacağıq sirləri/.gitatributları bu kimi məzmunla:

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

Məzmundan göründüyü kimi, bütün fayllar maska ​​ilə * keçəcək git-crypt, istisna olmaqla .gitatributları

Bunu işləməklə yoxlaya bilərik:

git crypt status -e

Çıxışda, şifrələmənin aktiv olduğu depodakı bütün faylların siyahısını alırıq

Budur, indi dəyişikliklərimizi təhlükəsiz şəkildə həyata keçirə bilərik:

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

Anbarı bloklamaq üçün yerinə yetirmək kifayətdir:

git crypt lock

və dərhal bütün şifrələnmiş fayllar ikili bir şeyə çevriləcək, onları oxumaq mümkün olmayacaq.
Anbarın şifrəsini açmaq üçün çalıştırın:

git crypt unlock

8. Alətlər qutusu şəkli yaradın

Alətlər qutusu şəkli, layihəmizi tətbiq etmək üçün istifadə edəcəyimiz bütün alətləri ehtiva edən bir şəkildir. O, tipik yerləşdirmə tapşırıqlarını yerinə yetirmək üçün gitlab runner tərəfindən istifadə olunacaq.

Burada hər şey sadədir, biz yenisini yaradırıq dockerfiles/toolbox/Dockerfile bu kimi məzmunla:

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

Gördüyünüz kimi, bu şəkildə tətbiqimizi yerləşdirmək üçün istifadə etdiyimiz bütün yardım proqramlarını quraşdırırıq. Bura ehtiyacımız yoxdursa kubectl, lakin siz boru kəmərini qurarkən onunla oynamaq istəyə bilərsiniz.

Həmçinin, Kubernetes ilə əlaqə saxlamaq və ona yerləşdirmək üçün biz gitlab-runner tərəfindən yaradılan podlar üçün rol təyin etməliyik.

Bunu etmək üçün gitlab-runner'om ilə qovluğa keçin:

cd deploy/gitlab-runner

və yeni komponent əlavə edin komponentlər/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,
      },
    ],
  },
]

Yeni parametrləri də təsvir edirik mühitlər/base.libsonnet, indi bu kimi görünür:

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

Xahiş edirik $.components.rbac.name istinad edir ad komponent üçün rbac

Nəyin dəyişdiyini yoxlayaq:

qbec diff default

və dəyişikliklərimizi Kubernetes-ə tətbiq edin:

qbec apply default

Həmçinin, git-də dəyişikliklərimizi etməyi unutmayın:

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. İlk boru kəmərimiz və şəkillərin etiketlərlə yığılması

Layihənin kökündə biz yaradacağıq .gitlab-ci.yml bu kimi məzmunla:

.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

İstifadə etdiyimizi nəzərə alın GIT_SUBMODULE_STRATEGY: normal icra etməzdən əvvəl alt modulları açıq şəkildə başlatmağınız lazım olan işlər üçün.

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

Düşünürəm ki, siz bunu təhlükəsiz bir versiya adlandıra bilərsiniz v0.0.1 və etiket əlavə edin:

git tag v0.0.1

Yeni versiyanı buraxmaq lazım olanda teqləri asacağıq. Docker şəkillərindəki teqlər Git teqlərinə uyğunlaşdırılacaq. Yeni teq ilə hər təkan həmin teqlə şəkil quruluşunu işə salacaq.

Gəl edək git push --teqləri, və ilk boru kəmərimizə baxın:

İlk boru kəmərinin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Qeyd etmək lazımdır ki, etiketə əsaslanan quruluşlar docker şəkilləri yaratmaq üçün yaxşıdır, lakin Kubernetes-də tətbiq yerləşdirmək üçün deyil. Yeni teqlər köhnə öhdəliklərə də təyin oluna bildiyindən, bu halda boru kəmərinin onlar üçün işə salınması köhnə versiyanın tətbiqinə gətirib çıxaracaq.

Bu problemi həll etmək üçün docker şəkillərinin qurulması adətən etiketlərə bağlanır və tətbiqin filiala yerləşdirilməsi ustad, burada toplanmış şəkillərin versiyaları sərt kodlaşdırılır. Məhz bu halda siz sadə geri qaytarma ilə geri qaytarmağı işə sala bilərsiniz ustad- filiallar.

10. Avtomatlaşdırmanı yerləşdirin

Gitlab-runner-in sirlərimizi deşifrə etməsi üçün biz repozitor açarını ixrac etməli və onu CI mühit dəyişənlərimizə əlavə etməliyik:

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

yaranan sətri Gitlab-da saxlayacağıq, bunun üçün layihəmizin parametrlərinə keçəcəyik:
Parametrlər -> CI / CD -> Dəyişənlər

Və yeni dəyişən yaradın:

növü
Aparıcı
Dəyər
Qorunan
Maskalı
Vüsət

File
GITCRYPT_KEY
<your string>
true (təlim zamanı edə bilərsiniz false)
true
All environments

Əlavə edilmiş dəyişənin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

İndi özümüzü yeniləyək .gitlab-ci.yml ona əlavə edərək:

.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

Burada qbec üçün bəzi yeni seçimləri aktiv etdik:

  • --kök bəzi/app - konkret proqramın kataloqunu müəyyən etməyə imkan verir
  • --force:k8s-kontekst __incluster__ - bu, yerləşdirmənin gtilab-runner-in işlədiyi eyni klasterdə baş verəcəyini söyləyən sehrli bir dəyişəndir. Bu lazımdır, əks halda qbec kubeconfig-də uyğun Kubernetes serveri tapmağa çalışacaq.
  • -Gözləmək - qbec-i yaratdığı resurslar Hazır vəziyyətinə keçənə qədər gözləməyə və yalnız bundan sonra uğurlu çıxış kodu ilə tamamlamağa məcbur edir.
  • -bəli - sadəcə interaktiv qabığı söndürür Sən əminsən? yerləşdirmə zamanı.

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

Və sonra git basmaq tətbiqlərimizin necə yerləşdirildiyini görəcəyik:

İkinci boru kəmərinin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

11. Master itələyərkən artefaktlar və montaj

Adətən, yuxarıda göstərilən addımlar demək olar ki, hər hansı bir mikroservisin qurulması və çatdırılması üçün kifayətdir, lakin biz saytı yeniləmək üçün hər dəfə etiket əlavə etmək istəmirik. Buna görə də, biz daha dinamik şəkildə gedəcəyik və master filialında həzm yerləşdirməsini quracağıq.

İdeya sadədir: indi bizim obrazımız veb hər dəfə basdığınız zaman yenidən qurulacaq ustad, sonra avtomatik olaraq Kubernetes-ə yerləşdirin.

Gəlin bizim bu iki işi yeniləyək .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"

Nəzərə alın ki, biz filial əlavə etmişik ustad к istinadlar iş üçün build_website və indi istifadə edirik $CI_COMMIT_REF_NAME əvəzinə $CI_COMMIT_TAG, yəni Git-də teqlərdən qurtuluruq və indi boru kəmərinizi işə salan commit filialının adı ilə şəkli itələyirik. Qeyd etmək lazımdır ki, bu, teqlərlə də işləyəcək ki, bu da bizə saytın snapshotlarını docker-registrində xüsusi versiya ilə saxlamağa imkan verəcək.

Saytın yeni versiyası üçün docker teqinin adı dəyişdirilə bildikdə, biz hələ də Kubernetes üçün dəyişiklikləri təsvir etməliyik, əks halda o, sadəcə olaraq tətbiqi yeni şəkildən dəyişdirməyəcək, çünki o, heç bir dəyişiklik görməyəcək. yerləşdirmə manifestosu.

Seçim --vm:ext-str digest="$DIGEST" qbec üçün - jsonnet-ə xarici dəyişəni ötürməyə imkan verir. Tətbiqimizin hər buraxılışda klasterdə yenidən yerləşdirilməsini istəyirik. Artıq dəyişdirilə bilən teq adından istifadə edə bilmərik, çünki şəklin xüsusi versiyası ilə əlaqə saxlamalı və dəyişdikdə yerləşdirməni işə salmalıyıq.

Burada Kanikonun təsvirin həzmini faylda saxlamaq qabiliyyəti bizə kömək edəcək (seçim --digest-fayl)
Sonra bu faylı köçürəcəyik və yerləşdirmə zamanı oxuyacağıq.

Bizim üçün parametrləri yeniləyək deploy/website/environments/base.libsonnet indi bu kimi görünəcək:

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

Bitdi, indi hər hansı bir öhdəlik götürün ustad üçün docker təsvirinin qurulmasını işə salır veb, sonra onu Kubernetes-də yerləşdirin.

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

Sonra yoxlayın git basmaq belə bir şey görməliyik:

Master üçün boru kəmərinin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Prinsipcə, hər təkanla gitlab-runner-i yenidən yerləşdirməyə ehtiyacımız yoxdur, əgər əlbəttə ki, konfiqurasiyasında heç nə dəyişməyibsə, gəlin bunu düzəltməyə çalışaq. .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/**/*

dəyişikliklər dəyişiklikləri izləyəcək deploy/gitlab-runner/ və yalnız varsa işimizi tetikleyeceğiz

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

git basmaq, bu daha yaxşıdır:

Yenilənmiş boru kəmərinin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

12. Dinamik mühitlər

Boru kəmərimizi dinamik mühitlərlə şaxələndirməyin vaxtıdır.

Əvvəlcə işi yeniləyək build_website bizim .gitlab-ci.yml, bloku ondan çıxarın yalnız, bu Gitlab-ı hər hansı bir filiala hər hansı bir öhdəlik götürməyə məcbur edəcək:

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/

Sonra işi yeniləyin deploy_website, orada bir blok əlavə edin ətraf mühit:

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"

Bu, Gitlab-a işi əlaqələndirməyə imkan verəcəkdir prod mühiti və ona düzgün keçidi göstərin.

İndi daha iki iş əlavə edək:

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

Onlar master istisna olmaqla istənilən filiala təkanla işə salınacaq və saytın önizləmə versiyasını yerləşdirəcək.

Qbec üçün yeni seçim görürük: --app-teg - bu, tətbiqin yerləşdirilmiş versiyalarını işarələməyə və yalnız bu teq daxilində işləməyə imkan verir; Kubernetes-də resursları yaradıb məhv edərkən qbec yalnız onların üzərində işləyəcək.
Beləliklə, biz hər bir baxış üçün ayrıca mühit yarada bilmərik, sadəcə olaraq eyni mühiti təkrar istifadə edirik.

Burada da istifadə edirik qbec müraciət nəzərdən keçirin, əvəzinə qbec default tətbiq edir - bu, mühitlərimiz üçün fərqləri təsvir etməyə çalışacağımız andır (nəzərdən keçirmə və defolt):

əlavə edək nəzərdən mühitdə deploy/website/qbec.yaml

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

Sonra biz bunu elan edirik 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

Və bunun üçün xüsusi parametrlər yazın 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',
    },
  },
}

Gəlin işə daha yaxından nəzər salaq dayandırın, filial çıxarıldıqda işə salınacaq və gitlab onu yoxlamağa çalışmaması üçün istifadə olunur GIT_STRATEGY: heç biri, sonra klonlayırıq ustad-filial və onun vasitəsilə baxışı silin.
Bir az çaşqınlıq var, amma hələ daha gözəl bir yol tapmamışam.
Alternativ seçim, hər bir rəyi həmişə tamamilə sökülə bilən bir otel ad sahəsinə yerləşdirmək olardı.

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

git basmaq, git checkout -b testi, git push mənşə testi, yoxlayın:

Gitlab-da yaradılmış mühitlərin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Hər şey işləyir? - əla, test şöbəmizi silin: git ödəmə ustası, git push mənşəyi: test, mühiti silmək üçün işlərin səhvsiz işlədiyini yoxlayırıq.

Burada dərhal aydınlaşdırmaq istəyirəm ki, layihədə hər hansı bir tərtibatçı filial yarada bilər, o da dəyişə bilər .gitlab-ci.yml fayl və gizli dəyişənlərə giriş.
Buna görə də, onların yalnız qorunan filiallar üçün istifadəsinə icazə vermək tövsiyə olunur, məsələn ustad, və ya hər bir mühit üçün ayrıca dəyişənlər dəsti yaradın.

13 Proqramları nəzərdən keçirin

Proqramları nəzərdən keçirin bu, yerləşdirilən mühitdə onu tez bir zamanda görmək üçün depodakı hər bir fayl üçün düymə əlavə etməyə imkan verən gitlab xüsusiyyətidir.

Bu düymələrin görünməsi üçün bir fayl yaratmalısınız .gitlab/route-map.yml və orada yolların bütün çevrilmələrini təsvir edin, bizim vəziyyətimizdə çox sadə olacaq:

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

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

Dəyişikliklərimizi həyata keçirməyi unutmayın:

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

git basmaq, və yoxlayın:

Tətbiqi Baxış Düyməsinin ekran görüntüsü

Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

İş tamamlandı!

Layihə mənbələri:

Diqqətiniz üçün təşəkkür edirəm, ümid edirəm bəyəndiniz Kubernetes-də yerləşdirmənin qurulması və avtomatlaşdırılması üçün yeni alətlər sınaqdan keçirilir

Mənbə: www.habr.com

Добавить комментарий