Versiyalangan hujjatlar sayti misolidan foydalanib, werf bilan Docker tasvirlarini dinamik yig'ish va joylashtirish

Biz allaqachon GitOps vositamiz haqida bir necha bor gaplashganmiz. werf, va bu safar biz loyihaning o'zi hujjatlari bilan saytni yig'ish bo'yicha tajribamizni baham ko'rmoqchimiz - werf.io (uning ruscha versiyasi en.werf.io). Bu oddiy statik sayt, lekin uning yig'ilishi qiziqarli, chunki u dinamik sonli artefaktlar yordamida qurilgan.

Versiyalangan hujjatlar sayti misolidan foydalanib, werf bilan Docker tasvirlarini dinamik yig'ish va joylashtirish

Sayt strukturasining nuanslariga o'ting: barcha versiyalar uchun umumiy menyu yaratish, relizlar haqidagi ma'lumotlarga ega sahifalar va boshqalar. - qilmaymiz. Buning o'rniga, keling, dinamik yig'ishning muammolari va xususiyatlariga va ozgina CI/CD jarayonlariga to'xtalib o'tamiz.

Kirish: sayt qanday ishlaydi

Birinchidan, werf hujjatlari uning kodi bilan birga saqlanadi. Bu, odatda, ushbu maqola doirasidan tashqarida bo'lgan muayyan rivojlanish talablarini qo'yadi, lekin hech bo'lmaganda shuni aytish mumkin:

  • Yangi werf funktsiyalari hujjatlarni yangilamasdan chiqarilmasligi kerak va aksincha, hujjatlardagi har qanday o'zgarishlar werfning yangi versiyasini chiqarishni nazarda tutadi;
  • Loyiha juda jadal rivojlanmoqda: yangi versiyalar kuniga bir necha marta chiqarilishi mumkin;
  • Hujjatlarning yangi versiyasi bilan saytni joylashtirish uchun qo'lda bajariladigan har qanday operatsiyalar hech bo'lmaganda zerikarli;
  • Loyiha semantik yondashuvni qabul qiladi versiyalashtirish, 5 ta barqarorlik kanali bilan. Chiqarish jarayoni barqarorlikni oshirish tartibida kanallar bo'ylab versiyalarning ketma-ket o'tishini o'z ichiga oladi: alfa-dan tosh-qattiqgacha;
  • Saytda rus tilidagi versiya mavjud bo'lib, u asosiy (ya'ni, ingliz tilidagi) versiyaga parallel ravishda "yashaydi va rivojlanadi" (ya'ni, uning mazmuni yangilanadi).

Bularning barchasini "ichki oshxona" ni foydalanuvchidan yashirish uchun, unga "shunchaki ishlaydigan" narsani taklif qildik alohida werf o'rnatish va yangilash vositasi Ismi? multiwerf. Siz shunchaki foydalanishga tayyor bo'lgan reliz raqamini va barqarorlik kanalini ko'rsatishingiz kerak, multiwerf kanalda yangi versiya mavjudligini tekshiradi va kerak bo'lganda uni yuklab oladi.

Veb-saytdagi versiya tanlash menyusida har bir kanalda werfning so'nggi versiyalari mavjud. Odatiy bo'lib, manzil bo'yicha werf.io/documentation so'nggi versiya uchun eng barqaror kanalning versiyasi ochiladi - u qidiruv tizimlari tomonidan ham indekslanadi. Kanal uchun hujjatlar alohida manzillarda mavjud (masalan, werf.io/v1.0-beta/documentation beta-versiya 1.0 uchun).

Umuman olganda, saytda quyidagi versiyalar mavjud:

  1. ildiz (sukut bo'yicha ochiladi),
  2. har bir nashrning har bir faol yangilash kanali uchun (masalan, werf.io/v1.0-beta).

Saytning ma'lum bir versiyasini yaratish uchun, umuman olganda, uni yordamida kompilyatsiya qilish kifoya Jekyllkatalogda ishga tushirish orqali /docs werf omboriga mos keladigan buyruq (jekyll build), kerakli versiyaning Git tegiga o'tgandan so'ng.

Faqat shuni qo'shish qoladi:

  • yig'ish uchun yordamchi dasturning o'zi (werf) ishlatiladi;
  • CI/CD jarayonlari GitLab CI asosida qurilgan;
  • va bularning barchasi, albatta, Kubernetesda ishlaydi.

vazifalar

Keling, barcha tavsiflangan xususiyatlarni hisobga olgan holda vazifalarni tuzamiz:

  1. Har qanday yangilash kanalida werf versiyasini o'zgartirgandan so'ng saytdagi hujjatlar avtomatik ravishda yangilanishi kerak.
  2. Rivojlanish uchun siz ba'zan qila olishingiz kerak saytning oldindan ko'rish versiyalarini ko'rish.

Har qanday kanaldagi versiyani mos keladigan Git teglaridan o'zgartirgandan so'ng saytni qayta kompilyatsiya qilish kerak, ammo tasvirni yaratish jarayonida biz quyidagi xususiyatlarga ega bo'lamiz:

  • Kanallardagi versiyalar ro'yxati o'zgarganligi sababli, faqat versiya o'zgargan kanallar uchun hujjatlar qayta tiklanishi kerak. Axir, hamma narsani qayta tiklash juda yoqimli emas.
  • Relizlar uchun kanallar to'plami o'zgarishi mumkin. Vaqt o'tishi bilan, masalan, kanallarda erta kirish 1.1 versiyasiga qaraganda barqarorroq versiya bo'lmasligi mumkin, ammo vaqt o'tishi bilan ular paydo bo'ladi - bu holda yig'ilishni qo'lda o'zgartirish kerak emasmi?

Bu chiqadi yig'ish tashqi ma'lumotlarni o'zgartirishga bog'liq.

Реализация

Yondashuvni tanlash

Shu bilan bir qatorda, har bir talab qilingan versiyani Kubernetesda alohida pod sifatida ishga tushirishingiz mumkin. Ushbu parametr klasterdagi ko'proq ob'ektlarni nazarda tutadi, ular barqaror werf relizlar sonining ko'payishi bilan o'sib boradi. Va bu, o'z navbatida, yanada murakkab texnik xizmat ko'rsatishni nazarda tutadi: har bir versiyada o'z HTTP serveri va kichik yuk bilan. Albatta, bu ham katta resurs xarajatlarini talab qiladi.

Biz ham xuddi shunday yo'ldan bordik barcha kerakli versiyalarni bitta rasmda yig'ish. Saytning barcha versiyalarining tuzilgan statikasi NGINX bilan konteynerda joylashgan va tegishli joylashtirishga trafik NGINX Ingress orqali keladi. Oddiy tuzilma - fuqaroligi bo'lmagan dastur - Kubernetesning o'zi yordamida Deployment (yuklanishga qarab) osonlik bilan o'lchash imkonini beradi.

Aniqroq qilib aytadigan bo'lsak, biz ikkita rasmni yig'amiz: biri ishlab chiqarish sxemasi uchun, ikkinchisi - ishlab chiqarish sxemasi uchun qo'shimcha. Qo'shimcha tasvir faqat asosiysi bilan birga ishlab chiqaruvchi sxemada qo'llaniladi (ishga tushiriladi) va ko'rib chiqish topshirig'idan olingan sayt versiyasini o'z ichiga oladi va ular orasidagi marshrutlash Ingress resurslari yordamida amalga oshiriladi.

werf vs git klon va artefaktlar

Yuqorida aytib o'tilganidek, hujjatlarning ma'lum bir versiyasi uchun sayt statikasini yaratish uchun siz tegishli ombor yorlig'iga o'tish orqali qurishingiz kerak. Buni har safar qurganingizda omborni klonlash, roʻyxatdan tegishli teglarni tanlash orqali ham qilishingiz mumkin. Biroq, bu juda ko'p resurs talab qiladigan operatsiya va bundan tashqari, ahamiyatsiz bo'lmagan ko'rsatmalar yozishni talab qiladi ... Yana bir jiddiy kamchilik shundaki, bu yondashuv bilan yig'ish paytida biror narsani keshlashning imkoni yo'q.

Bu erda werf yordam dasturining o'zi bizning yordamimizga keladi va amalga oshiradi aqlli keshlash va foydalanishga imkon beradi tashqi omborlar. Repozitariydan kod qo'shish uchun werf dan foydalanish qurilishni sezilarli darajada tezlashtiradi, chunki werf asosan omborni bir marta klonlaydi va keyin bajaradi faqatgina fetch zarur bo'lsa. Bundan tashqari, ombordan ma'lumotlarni qo'shganda, biz faqat kerakli kataloglarni tanlashimiz mumkin (bizning holimizda bu katalog docs), bu qo'shilgan ma'lumotlar miqdorini sezilarli darajada kamaytiradi.

Jekyll statik ma'lumotlarni kompilyatsiya qilish uchun mo'ljallangan vosita bo'lgani uchun va yakuniy rasmda kerak emas, shuning uchun uni kompilyatsiya qilish mantiqan to'g'ri keladi. werf artefakti, va yakuniy rasmga o'ting faqat kompilyatsiya natijasini import qiling.

Biz werf.yaml yozamiz

Shunday qilib, biz har bir versiyani alohida werf artefaktida to'plashga qaror qildik. Biroq biz yig'ish paytida bu artefaktlarning qanchasi bo'lishini bilmaymiz, shuning uchun biz qattiq konfiguratsiyani yoza olmaymiz (to'g'risini aytganda, biz hali ham qila olamiz, lekin u butunlay samarali bo'lmaydi).

werf foydalanish imkonini beradi Shablonlarga o'ting konfiguratsiya faylida (werf.yaml) va bu imkon beradi konfiguratsiyani tezda yarating tashqi ma'lumotlarga qarab (sizga nima kerak!). Bizning holatlarimizda tashqi ma'lumotlar versiyalar va relizlar haqidagi ma'lumotlar bo'lib, ular asosida biz kerakli miqdordagi artefaktlarni yig'amiz va natijada ikkita rasmni olamiz: werf-doc и werf-dev turli davrlarda ishlash uchun.

Tashqi ma'lumotlar muhit o'zgaruvchilari orqali uzatiladi. Mana ularning tarkibi:

  • RELEASES - formatdagi qiymatlarning bo'sh joydan ajratilgan ro'yxati ko'rinishidagi nashrlar ro'yxati va mos keladigan werf versiyasiga ega qator <НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>. Misol: 1.0%v1.0.4-beta.20
  • CHANNELS - formatdagi qiymatlar ro'yxati bo'sh joydan ajratilgan ko'rinishidagi kanallar ro'yxati va mos keladigan werf versiyasiga ega qator <КАНАЛ>%<НОМЕР_ВЕРСИИ>. Misol: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION — werf reliz versiyasi sukut bo'yicha saytda ko'rsatiladi (hujjatlarni har doim ham eng yuqori reliz raqami bo'yicha ko'rsatish shart emas). Misol: v1.0.4-beta.20
  • REVIEW_SHA — sinov davri uchun versiyani yaratishingiz kerak bo'lgan ko'rib chiqish majburiyatining xeshi.

Ushbu o'zgaruvchilar GitLab CI quvur liniyasida to'ldiriladi va quyida qanday aniq yozilgan.

Avvalo, qulaylik uchun biz aniqlaymiz werf.yaml Shablon o'zgaruvchilariga o'ting, ularga muhit o'zgaruvchilaridan qiymatlarni tayinlang:

{{ $_ := set . "WerfVersions" (cat (env "CHANNELS") (env "RELEASES") | splitList " ") }}
{{ $Root := . }}
{{ $_ := set . "WerfRootVersion" (env "ROOT_VERSION") }}
{{ $_ := set . "WerfReviewCommit" (env "REVIEW_SHA") }}

Saytning statik versiyasini kompilyatsiya qilish uchun artefakt tavsifi, odatda, bizga kerak bo'lgan barcha holatlar uchun bir xil bo'ladi (jumladan, ildiz versiyasini yaratish, shuningdek, ishlab chiqish davri uchun versiya). Shuning uchun funksiya yordamida uni alohida blokga o'tkazamiz define - keyinchalik qayta foydalanish uchun include. Biz quyidagi argumentlarni shablonga o'tkazamiz:

  • Version — yaratilgan versiya (teg nomi);
  • Channel — artefakt yaratilgan yangilash kanalining nomi;
  • Commit — agar artefakt ko'rib chiqish uchun yaratilgan bo'lsa, xeshni amalga oshirish;
  • kontekst.

Artefakt shablon tavsifi

{{- define "doc_artifact" -}}
{{- $Root := index . "Root" -}}
artifact: doc-{{ .Channel }}
from: jekyll/builder:3
mount:
- from: build_dir
  to: /usr/local/bundle
ansible:
  install:
  - shell: |
      export PATH=/usr/jekyll/bin/:$PATH
  - name: "Install Dependencies"
    shell: bundle install
    args:
      executable: /bin/bash
      chdir: /app/docs
  beforeSetup:
{{- if .Commit }}
  - shell: echo "Review SHA - {{ .Commit }}."
{{- end }}
{{- if eq .Channel "root" }}
  - name: "releases.yml HASH: {{ $Root.Files.Get "releases.yml" | sha256sum }}"
    copy:
      content: |
{{ $Root.Files.Get "releases.yml" | indent 8 }}
      dest:  /app/docs/_data/releases.yml
{{- else }}
  - file:
      path: /app/docs/_data/releases.yml
      state: touch
{{- end }}
  - file:
      path: "{{`{{ item }}`}}"
      state: directory
      mode: 0777
    with_items:
    - /app/main_site/
    - /app/ru_site/
  - file:
      dest: /app/docs/pages_ru/cli
      state: link
      src: /app/docs/pages/cli
  - shell: |
      echo -e "werfVersion: {{ .Version }}nwerfChannel: {{ .Channel }}" > /tmp/_config_additional.yml
      export PATH=/usr/jekyll/bin/:$PATH
{{- if and (ne .Version "review") (ne .Channel "root") }}
{{- $_ := set . "BaseURL" ( printf "v%s" .Channel ) }}
{{- else if ne .Channel "root" }}
{{- $_ := set . "BaseURL" .Channel }}
{{- end }}
      jekyll build -s /app/docs  -d /app/_main_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/tmp/_config_additional.yml
      jekyll build -s /app/docs  -d /app/_ru_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/app/docs/_config_ru.yml,/tmp/_config_additional.yml
    args:
      executable: /bin/bash
      chdir: /app/docs
git:
- url: https://github.com/flant/werf.git
  to: /app/
  owner: jekyll
  group: jekyll
{{- if .Commit }}
  commit: {{ .Commit }}
{{- else }}
  tag: {{ .Version }}
{{- end }}
  stageDependencies:
    install: ['docs/Gemfile','docs/Gemfile.lock']
    beforeSetup: '**/*'
  includePaths: 'docs'
  excludePaths: '**/*.sh'
{{- end }}

Artefakt nomi noyob bo'lishi kerak. Bunga, masalan, kanal nomini (o'zgaruvchining qiymatini) qo'shish orqali erishishimiz mumkin .Channel) artefakt nomiga qo‘shimcha sifatida: artifact: doc-{{ .Channel }}. Ammo artefaktlardan import qilishda siz bir xil nomlarga murojaat qilishingiz kerakligini tushunishingiz kerak.

Artefaktni tasvirlashda quyidagi werf xususiyatidan foydalaniladi: o'rnatish. Xizmat katalogini ko'rsatuvchi o'rnatish build_dir Jekyll keshini quvur liniyasi o'rtasida saqlashga imkon beradi, bu esa qayta yig'ishni sezilarli darajada tezlashtiradi.

Siz fayldan foydalanishni ham sezgan bo'lishingiz mumkin releases.yml YAML fayli boʻlib, undan reliz maʼlumotlari soʻralgan github.com (quvurni amalga oshirishda olingan artefakt). Bu saytni tuzishda kerak, ammo maqola kontekstida bu biz uchun qiziq, chunki u uning holatiga bog'liq. faqat bitta artefaktni qayta yig'ish — saytning ildiz versiyasining artefakti (boshqa artefaktlarda bu kerak emas).

Bu shartli bayonot yordamida amalga oshiriladi if Shablonlar va dizaynlarga o'ting {{ $Root.Files.Get "releases.yml" | sha256sum }} bosqichda bosqichlar. U quyidagicha ishlaydi: ildiz versiyasi uchun artefakt yaratishda (o'zgaruvchi .Channel mavjud root) fayl xeshi releases.yml butun bosqichning imzosiga ta'sir qiladi, chunki u Ansible vazifasi nomining bir qismidir (parametr name). Shunday qilib, o'zgartirilganda mazmuni fayl releases.yml tegishli artefakt qayta yig'iladi.

Iltimos, tashqi ombor bilan ishlashga ham e'tibor bering. dan artefakt tasvirida werf ombori, faqat katalog qo'shiladi /docs, va o'tgan parametrlarga qarab, kerakli teg yoki ko'rib chiqish majburiyatining ma'lumotlari darhol qo'shiladi.

Kanallar va relizlarning uzatilgan versiyalari artefaktining tavsifini yaratish uchun artefakt shablonidan foydalanish uchun biz o'zgaruvchi bo'yicha tsiklni tashkil qilamiz. .WerfVersions в werf.yaml:

{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ dict "Version" $VersionsDict._1 "Channel" $VersionsDict._0 "Root" $Root | include "doc_artifact" }}
---
{{ end -}}

Chunki pastadir bir nechta artefaktlarni yaratadi (biz shunday deb umid qilamiz), ular orasidagi ajratuvchini - ketma-ketlikni hisobga olish kerak --- (Konfiguratsiya fayli sintaksisi haqida ko'proq ma'lumot olish uchun qarang hujjatlar). Yuqorida aytib o'tilganidek, shablonni tsiklda chaqirishda biz versiya parametrlarini, URL manzilini va ildiz kontekstini o'tkazamiz.

Xuddi shunday, lekin halqasiz, biz artefakt shablonini "maxsus holatlar" deb ataymiz: ildiz versiyasi uchun, shuningdek ko'rib chiqish versiyasi uchun:

{{ dict "Version" .WerfRootVersion "Channel" "root" "Root" $Root  | include "doc_artifact" }}
---
{{- if .WerfReviewCommit }}
{{ dict "Version" "review" "Channel" "review" "Commit" .WerfReviewCommit "Root" $Root  | include "doc_artifact" }}
{{- end }}

Esda tutingki, ko'rib chiqish uchun artefakt faqat o'zgaruvchi o'rnatilgan bo'lsa yaratiladi .WerfReviewCommit.

Artefaktlar tayyor - import qilishni boshlash vaqti keldi!

Kubernetes-da ishlash uchun mo'ljallangan yakuniy rasm oddiy NGINX bo'lib, server konfiguratsiya fayli qo'shilgan. nginx.conf va artefaktlardan statik. Saytning ildiz versiyasining artefaktiga qo'shimcha ravishda, biz o'zgaruvchidagi pastadirni takrorlashimiz kerak .WerfVersions kanal artefaktlarini import qilish va versiyalarni chiqarish + biz ilgari qabul qilgan artefakt nomlash qoidasiga amal qiling. Har bir artefakt saytning ikki tildagi versiyalarini saqlaganligi sababli, biz ularni konfiguratsiya tomonidan taqdim etilgan joylarga import qilamiz.

Yakuniy tasvirning tavsifi werf-doc

image: werf-doc
from: nginx:stable-alpine
ansible:
  setup:
  - name: "Setup /etc/nginx/nginx.conf"
    copy:
      content: |
{{ .Files.Get ".werf/nginx.conf" | indent 8 }}
      dest: /etc/nginx/nginx.conf
  - file:
      path: "{{`{{ item }}`}}"
      state: directory
      mode: 0777
    with_items:
    - /app/main_site/assets
    - /app/ru_site/assets
import:
- artifact: doc-root
  add: /app/_main_site
  to: /app/main_site
  before: setup
- artifact: doc-root
  add: /app/_ru_site
  to: /app/ru_site
  before: setup
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
  add: /app/_main_site
  to: /app/main_site/v{{ $Channel }}
  before: setup
{{ end -}}
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
  add: /app/_ru_site
  to: /app/ru_site/v{{ $Channel }}
  before: setup
{{ end -}}

Asosiysi bilan birgalikda ishlab chiqaruvchi pallasida ishga tushirilgan qo'shimcha rasm saytning faqat ikkita versiyasini o'z ichiga oladi: ko'rib chiqishdan olingan versiya va saytning ildiz versiyasi (umumiy aktivlar mavjud va agar esingizda bo'lsa , ma'lumotlarni chiqarish). Shunday qilib, qo'shimcha rasm asosiy rasmdan faqat import bo'limida (va, albatta, nomda) farq qiladi:

image: werf-dev
...
import:
- artifact: doc-root
  add: /app/_main_site
  to: /app/main_site
  before: setup
- artifact: doc-root
  add: /app/_ru_site
  to: /app/ru_site
  before: setup
{{- if .WerfReviewCommit  }}
- artifact: doc-review
  add: /app/_main_site
  to: /app/main_site/review
  before: setup
- artifact: doc-review
  add: /app/_ru_site
  to: /app/ru_site/review
  before: setup
{{- end }}

Yuqorida ta'kidlab o'tilganidek, tekshirish majburiyati uchun artefakt faqat o'rnatilgan muhit o'zgaruvchisi ishga tushirilganda yaratiladi. REVIEW_SHA. Agar muhit o'zgaruvchisi bo'lmasa, werf-dev tasvirini umuman yaratmaslik mumkin edi REVIEW_SHA, lekin maqsadida siyosat bo'yicha tozalash Werf-dagi Docker tasvirlari werf-dev tasviri uchun ishlagan, biz quvur liniyasi tuzilishini soddalashtirish uchun uni faqat artefaktning ildiz versiyasi (baribir u allaqachon qurilgan) bilan qurish uchun qoldiramiz.

Assambleya tayyor! Keling, CI/CD va muhim nuanslarga o'tamiz.

GitLab CI-dagi quvur liniyasi va dinamik qurish xususiyatlari

Qurilishni ishga tushirishda biz ishlatiladigan muhit o'zgaruvchilarini o'rnatishimiz kerak werf.yaml. Bu GitHub kancasidan quvur liniyasini chaqirganda o'rnatadigan REVIEW_SHA o'zgaruvchisiga taalluqli emas.

Biz Bash skriptida kerakli tashqi ma'lumotlarni yaratamiz generate_artifacts, bu ikkita GitLab quvur liniyasi artefaktini yaratadi:

  • fayl releases.yml chiqarish ma'lumotlari bilan,
  • fayl common_envs.sh, eksport qilinadigan muhit o'zgaruvchilari mavjud.

Fayl tarkibi generate_artifacts bizda topasiz misollar bilan omborlar. Ma'lumotni o'zi qabul qilish maqolaning mavzusi emas, balki fayldir common_envs.sh biz uchun muhim, chunki werf ishi bunga bog'liq. Uning mazmuniga misol:

export RELEASES='1.0%v1.0.6-4'
export CHANNELS='1.0-alpha%v1.0.7-1 1.0-beta%v1.0.7-1 1.0-ea%v1.0.6-4 1.0-stable%v1.0.6-4 1.0-rock-solid%v1.0.6-4'
export ROOT_VERSION='v1.0.6-4'

Siz bunday skriptning chiqishidan foydalanishingiz mumkin, masalan, Bash funktsiyasidan foydalanib source.

Endi qiziqarli qism keladi. Ilovani yaratish ham, joylashtirish ham to'g'ri ishlashi uchun buni ta'minlash kerak werf.yaml edi xuddi shu kamida bitta quvur ichida. Agar bu shart bajarilmasa, werf yig'ish va, masalan, joylashtirish paytida hisoblaydigan bosqichlarning imzolari boshqacha bo'ladi. Bu joylashtirish xatosiga olib keladi, chunki... joylashtirish uchun zarur bo'lgan rasm yo'qoladi.

Boshqacha qilib aytadigan bo'lsak, agar sayt tasvirini yig'ish paytida relizlar va versiyalar haqidagi ma'lumotlar bir xil bo'lsa va joylashtirish vaqtida yangi versiya chiqarilsa va muhit o'zgaruvchilari turli qiymatlarga ega bo'lsa, u holda joylashtirish xato bilan muvaffaqiyatsiz bo'ladi: Axir, yangi versiyaning artefakti hali qurilmagan.

Agar avlod werf.yaml tashqi ma'lumotlarga bog'liq (masalan, bizning holatimizda bo'lgani kabi, joriy versiyalar ro'yxati), keyin bunday ma'lumotlarning tarkibi va qiymatlari quvur liniyasida qayd etilishi kerak. Agar tashqi parametrlar tez-tez o'zgarsa, bu ayniqsa muhimdir.

Biz bo `lamiz tashqi ma'lumotlarni qabul qilish va yozib olish GitLab-dagi quvur liniyasining birinchi bosqichida (Oldindan qurilgan) va ularni yanada shaklda uzating GitLab CI artefakti. Bu sizga bir xil konfiguratsiya bilan quvur liniyasi ishlarini (qurilish, joylashtirish, tozalash) ishga tushirish va qayta boshlash imkonini beradi. werf.yaml.

Sahna mazmuni Oldindan qurilgan fayl .gitlab-ci.yml:

Prebuild:
  stage: prebuild
  script:
    - bash ./generate_artifacts 1> common_envs.sh
    - cat ./common_envs.sh
  artifacts:
    paths:
      - releases.yml
      - common_envs.sh
    expire_in: 2 week

Artefaktdagi tashqi ma'lumotlarni qo'lga kiritgandan so'ng, siz standart GitLab CI quvur liniyasi bosqichlari yordamida qurishingiz va joylashtirishingiz mumkin: Qurilish va joylashtirish. Biz quvur liniyasini werf GitHub omboridagi ilgaklar yordamida ishga tushiramiz (ya'ni, GitHub omborida o'zgarishlar bo'lganda). Ular uchun ma'lumotlarni bo'limdagi GitLab loyihasi xususiyatlarida topish mumkin CI/CD sozlamalari -> Quvur liniyasi ishga tushirgichlari, va keyin GitHub da mos keladigan Webhook yarating (Sozlamalar -> Webhooks).

Qurilish bosqichi quyidagicha ko'rinadi:

Build:
  stage: build
  script:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - werf build-and-publish --stages-storage :local
  except:
    refs:
      - schedules
  dependencies:
    - Prebuild

GitLab sahnadan qurish bosqichiga ikkita artefakt qo'shadi Oldindan qurilgan, shuning uchun biz konstruksiyadan foydalangan holda tayyorlangan kirish ma'lumotlari bilan o'zgaruvchilarni eksport qilamiz source common_envs.sh. Quvurni jadvalga muvofiq ishga tushirishdan tashqari barcha holatlarda qurilish bosqichini boshlaymiz. Jadvalga ko'ra, biz tozalash uchun quvur liniyasini ishga tushiramiz - bu holda montajni amalga oshirishning hojati yo'q.

Joylashtirish bosqichida biz ikkita vazifani ta'riflaymiz - YAML shablonidan foydalangan holda ishlab chiqarish va ishlab chiqarish sxemalariga joylashtirish uchun alohida:

.base_deploy: &base_deploy
  stage: deploy
  script:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - werf deploy --stages-storage :local
  dependencies:
    - Prebuild
  except:
    refs:
      - schedules

Deploy to Production:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: prod
  environment:
    name: production
    url: werf.io
  only:
    refs:
      - master
  except:
    variables:
      - $REVIEW_SHA
    refs:
      - schedules

Deploy to Test:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: dev
  environment:
    name: test
    url: werf.test.flant.com
  except:
    refs:
      - schedules
  only:
    variables:
      - $REVIEW_SHA

Vazifalar faqat werf joylashtirishni amalga oshirishi kerak bo'lgan klaster kontekstini ko'rsatishda tubdan farq qiladi (WERF_KUBE_CONTEXT) va aylanish muhiti o'zgaruvchilarini o'rnatish (environment.name и environment.url), ular keyinchalik Helm diagramma shablonlarida ishlatiladi. Biz shablonlarning mazmunini bermaymiz, chunki... u erda mavzu uchun qiziq narsa yo'q, lekin siz ularni topishingiz mumkin maqola uchun omborlar.

oxirgi teginish

Werf versiyalari tez-tez chiqarilganligi sababli, tez-tez yangi tasvirlar yaratiladi va Docker Registry doimiy ravishda o'sib boradi. Shuning uchun, siyosatlar asosida avtomatik tasvirni tozalashni sozlash juda muhimdir. Buni qilish juda oson.

Amalga oshirish uchun sizga kerak bo'ladi:

  • Tozalash bosqichini qo'shing .gitlab-ci.yml;
  • Tozalash vazifasining davriy bajarilishini qo'shing;
  • Yozish uchun ruxsat belgisi bilan muhit o'zgaruvchisini o'rnating.

Tozalash bosqichi qo'shilmoqda .gitlab-ci.yml:

Cleanup:
  stage: cleanup
  script:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
    - werf cleanup --stages-storage :local
  only:
    refs:
      - schedules

Biz bularning deyarli barchasini biroz yuqoriroq ko'rdik - faqat uni tozalash uchun avval Docker registriga Docker registridagi tasvirlarni o'chirish huquqiga ega bo'lgan token bilan kirishingiz kerak (avtomatik ravishda chiqarilgan GitLab CI topshiriq tokeni bunday emas. bunday huquqlarga ega). Token GitLab da oldindan yaratilishi va uning qiymati muhit oʻzgaruvchisida koʻrsatilishi kerak WERF_IMAGES_CLEANUP_PASSWORD loyiha (CI/CD sozlamalari -> O'zgaruvchilar).

Kerakli jadval bilan tozalash vazifasini qo'shish ichida amalga oshiriladi CI/CD ->
Jadvallar
.

Hammasi shunday: Docker registridagi loyiha endi foydalanilmagan tasvirlardan doimiy ravishda o'smaydi.

Amaliy qismning oxirida sizga eslatib o'tamanki, maqoladan to'liq ro'yxatlar mavjud borib:

natija

  1. Biz mantiqiy montaj tuzilmasini oldik: har bir versiyada bitta artefakt.
  2. Assambleya universaldir va werf-ning yangi versiyalari chiqarilganda qo'lda o'zgartirishlarni talab qilmaydi: veb-saytdagi hujjatlar avtomatik ravishda yangilanadi.
  3. Turli xil konturlar uchun ikkita rasm yig'iladi.
  4. Tez ishlaydi, chunki Keshlash imkon qadar ko'proq ishlatiladi - werfning yangi versiyasi chiqarilganda yoki ko'rib chiqish uchun GitHub kancasi chaqirilganda, faqat o'zgartirilgan versiyaga ega mos artefakt qayta tiklanadi.
  5. Foydalanilmayotgan rasmlarni o'chirish haqida o'ylashning hojati yo'q: werf qoidalariga muvofiq tozalash Docker registrini tartibda saqlaydi.

topilmalar

  • Werf-dan foydalanish yig'ilishning o'zini keshlash va tashqi omborlar bilan ishlashda keshlash tufayli tez ishlashiga imkon beradi.
  • Tashqi Git omborlari bilan ishlash har safar butun omborni klonlash yoki murakkab optimallashtirish mantig'i bilan g'ildirakni qayta ixtiro qilish zaruratini yo'q qiladi. werf keshdan foydalanadi va klonlashni faqat bir marta amalga oshiradi va keyin foydalanadi fetch va faqat kerak bo'lganda.
  • Qurilish konfiguratsiya faylida Go shablonlaridan foydalanish imkoniyati werf.yaml natijasi tashqi ma'lumotlarga bog'liq bo'lgan yig'ilishni tasvirlash imkonini beradi.
  • Mount in werf-dan foydalanish artefaktlarni to'plashni sezilarli darajada tezlashtiradi - barcha quvurlar uchun umumiy bo'lgan kesh tufayli.
  • werf tozalashni sozlashni osonlashtiradi, bu dinamik ravishda qurishda ayniqsa muhimdir.

PS

Shuningdek, bizning blogimizda o'qing:

Manba: www.habr.com

a Izoh qo'shish