Нұсқаланған құжаттама сайтының мысалын пайдалана отырып, werf көмегімен Docker кескіндерін динамикалық құрастыру және орналастыру

Біз GitOps құралы туралы бірнеше рет айтқанбыз. верф, және бұл жолы біз жобаның құжаттамасымен сайтты құрастыру тәжірибемізбен бөліскіміз келеді - werf.io (оның орысша нұсқасы en.werf.io). Бұл кәдімгі статикалық сайт, бірақ оны құрастыру артефактілердің динамикалық санын пайдаланып салынғанымен қызықты.

Нұсқаланған құжаттама сайтының мысалын пайдалана отырып, werf көмегімен Docker кескіндерін динамикалық құрастыру және орналастыру

Сайт құрылымының нюанстарына өтіңіз: барлық нұсқалар үшін жалпы мәзірді, шығарылымдар туралы ақпараты бар беттерді және т.б. - болмаймыз. Оның орнына, динамикалық құрастырудың мәселелері мен ерекшеліктеріне және аздап CI/CD процестеріне тоқталайық.

Кіріспе: сайт қалай жұмыс істейді

Бастау үшін werf құжаттамасы оның кодымен бірге сақталады. Бұл әдетте осы мақаланың шеңберінен тыс белгілі бір әзірлеу талаптарын қояды, бірақ кем дегенде мынаны айтуға болады:

  • Жаңа werf функциялары құжаттаманы жаңартпай шығарылмауы керек және, керісінше, құжаттамадағы кез келген өзгерістер werf жаңа нұсқасын шығаруды білдіреді;
  • Жобаның жеткілікті қарқынды дамуы бар: жаңа нұсқаларды күніне бірнеше рет шығаруға болады;
  • Құжаттаманың жаңа нұсқасы бар сайтты орналастыру бойынша кез келген қолмен жасалатын операциялар кем дегенде жалықтырады;
  • Жоба семантикалық тәсілді қабылдайды нұсқалау, 5 тұрақтылық арналары бар. Шығару процесі тұрақтылықты жоғарылату тәртібімен арналар арқылы нұсқалардың дәйекті өтуін қамтиды: альфадан тасқа дейін;
  • Сайтта негізгі (яғни, ағылшын тіліндегі) нұсқамен қатар «өмір сүретін және дамитын» (яғни мазмұны жаңартылатын) орыс тіліндегі нұсқасы бар.

Осы «ішкі асүйді» пайдаланушыдан жасыру үшін, оған «жұмыс істейтін» нәрсені ұсына отырып, біз жасадық бөлек werf орнату және жаңарту құралы Мүмкін multiwerf. Сіз жай ғана пайдалануға дайын шығарылым нөмірін және тұрақтылық арнасын көрсетсеңіз болғаны, multiwerf арнада жаңа нұсқаның бар-жоғын тексеріп, қажет болса жүктеп алады.

Веб-сайттағы нұсқаларды таңдау мәзірінде werf бағдарламасының соңғы нұсқалары әр арнада қолжетімді. Әдепкі бойынша, мекенжай бойынша werf.io/documentation соңғы шығарылымға арналған ең тұрақты арнаның нұсқасы ашылады - оны іздеу жүйелері де индекстейді. Арнаның құжаттамасы бөлек мекенжайларда қолжетімді (мысалы, werf.io/v1.0-beta/documentation бета нұсқасы 1.0 үшін).

Барлығы сайтта келесі нұсқалар бар:

  1. түбір (әдепкі бойынша ашылады),
  2. әрбір шығарылымның әрбір белсенді жаңарту арнасы үшін (мысалы, werf.io/v1.0-бета).

Сайттың белгілі бір нұсқасын жасау үшін, жалпы алғанда, оны пайдалану арқылы құрастыру жеткілікті Джеккаталогта іске қосу арқылы /docs werf репозиторийіне сәйкес пәрмен (jekyll build), қажетті нұсқаның Git тегіне ауысқаннан кейін.

Мұны қосу ғана қалады:

  • утилитаның өзі (werf) құрастыру үшін пайдаланылады;
  • CI/CD процестері GitLab CI негізінде құрастырылған;
  • және мұның бәрі, әрине, Кубернетесте жұмыс істейді.

міндеттері

Енді барлық сипатталған ерекшеліктерді ескере отырып тапсырмаларды тұжырымдаймыз:

  1. Кез келген жаңарту арнасында werf нұсқасын өзгерткеннен кейін сайттағы құжаттама автоматты түрде жаңартылуы керек.
  2. Даму үшін сіз кейде қабілетті болуыңыз керек сайттың алдын ала қарау нұсқаларын көру.

Кез келген арнадағы нұсқаны сәйкес Git тегтерінен өзгерткеннен кейін сайтты қайта құрастыру керек, бірақ кескінді құру барысында біз келесі мүмкіндіктерді аламыз:

  • Арналардағы нұсқалар тізімі өзгергендіктен, нұсқасы өзгерген арналар үшін құжаттаманы қайта құру ғана қажет. Өйткені, бәрін қайта құру өте жақсы емес.
  • Шығарылым арналарының жинағы өзгеруі мүмкін. Уақыт өте келе, мысалы, арналарда ерте қолжетімділік 1.1 шығарылымына қарағанда тұрақты нұсқа болмауы мүмкін, бірақ уақыт өте келе олар пайда болады - бұл жағдайда жинақты қолмен өзгерту керек емес пе?

Көрсетіледі құрастыру сыртқы деректерді өзгертуге байланысты.

Реализация

Тәсілді таңдау

Сондай-ақ, әрбір талап етілетін нұсқаны Kubernetes жүйесінде бөлек бөлім ретінде іске қосуға болады. Бұл опция кластердегі нысандардың көбірек санын білдіреді, олар тұрақты верф шығарылымдарының санының өсуімен бірге өседі. Және бұл, өз кезегінде, күрделірек техникалық қызмет көрсетуді білдіреді: әрбір нұсқада өзінің HTTP сервері және шағын жүктемесі бар. Әрине, бұл да үлкен ресурс шығындарын талап етеді.

Біз бірдей жолды ұстандық барлық қажетті нұсқаларды бір суретте жинау. Сайттың барлық нұсқаларының құрастырылған статикасы NGINX бар контейнерде орналасқан және сәйкес Орналастыруға трафик NGINX Ingress арқылы келеді. Қарапайым құрылым - азаматтығы жоқ қолданба - Kubernetes көмегімен Орналастыруды (жүктемеге байланысты) оңай масштабтауға мүмкіндік береді.

Дәлірек айтсақ, біз екі суретті жинап жатырмыз: біреуі өндіріс тізбегі үшін, екіншісі - әзірлеу тізбегі үшін қосымша. Қосымша кескін негізгімен бірге әзірлеу тізбегінде ғана пайдаланылады (іске қосылады) және шолу тапсырмасынан сайттың нұсқасын қамтиды және олардың арасындағы бағыттау Ingress ресурстары арқылы жүзеге асырылады.

werf vs git клон және артефактілер

Жоғарыда айтылғандай, құжаттаманың нақты нұсқасы үшін сайт статикасын жасау үшін сізге сәйкес репозиторий тегіне ауысу арқылы құрастыру қажет. Мұны әр құрастырған кезде репозиторийді клондау, тізімнен сәйкес тегтерді таңдау арқылы жасауға болады. Дегенмен, бұл айтарлықтай ресурсты қажет ететін операция және оның үстіне тривиальды емес нұсқауларды жазуды талап етеді... Тағы бір маңызды кемшілік - бұл тәсілмен құрастыру кезінде бір нәрсені кэштеуге мүмкіндік жоқ.

Мұнда werf утилитасының өзі бізге көмекке келеді, іске асырады смарт кэштеу және пайдалануға мүмкіндік береді сыртқы репозиторийлер. Репозиторийден код қосу үшін werf пайдалану құрастыруды айтарлықтай жылдамдатады, өйткені werf репозиторийді бір рет клондайды, содан кейін орындайды тек fetch қажет болған жағдайда. Сонымен қатар, репозиторийден деректерді қосқанда, біз тек қажетті каталогтарды таңдай аламыз (біздің жағдайда бұл каталог docs), бұл қосылған деректер көлемін айтарлықтай азайтады.

Jekyll статикалық деректерді құрастыруға арналған және соңғы кескінде қажет емес құрал болғандықтан, оны құрастыру қисынды болар еді. верф артефакті, және соңғы кескінге тек компиляция нәтижесін импорттау.

Біз werf.yaml деп жазамыз

Сондықтан біз әр нұсқаны бөлек верф артефактісінде құрастырамыз деп шештік. Дегенмен біз құрастыру кезінде осы артефактілердің қаншасы болатынын білмейміз, сондықтан біз бекітілген құрастыру конфигурациясын жаза алмаймыз (қатаң айтқанда, біз әлі де жасай аламыз, бірақ ол толығымен тиімді болмайды).

werf пайдалануға мүмкіндік береді Үлгілерге өтіңіз конфигурация файлында (werf.yaml) және бұл мүмкін етеді конфигурацияны жылдам жасаңыз сыртқы деректерге байланысты (сізге не қажет!). Біздің жағдайда сыртқы деректер - бұл нұсқалар мен шығарылымдар туралы ақпарат, оның негізінде біз артефактілердің қажетті санын жинаймыз және нәтижесінде екі сурет аламыз: werf-doc и werf-dev әртүрлі тізбектерде жұмыс істеу.

Сыртқы деректер орта айнымалылары арқылы беріледі. Міне, олардың құрамы:

  • RELEASES — форматта бос орынмен бөлінген мәндер тізімі түріндегі шығарылымдар тізімі және werf сәйкес ағымдағы нұсқасы бар жол <НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>. Мысал: 1.0%v1.0.4-beta.20
  • CHANNELS — арналар тізімі және werf сәйкес ағымдағы нұсқасы бар жол, форматтағы мәндердің бос орынмен бөлінген тізімі түріндегі <КАНАЛ>%<НОМЕР_ВЕРСИИ>. Мысал: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION — сайтта әдепкі бойынша көрсетілетін werf шығарылым нұсқасы (құжаттарды ең жоғары шығарылым нөмірі бойынша көрсету әрқашан қажет емес). Мысалы: v1.0.4-beta.20
  • REVIEW_SHA — сынақ циклінің нұсқасын құру қажет шолу міндеттемесінің хэші.

Бұл айнымалы мәндер GitLab CI құбырында толтырылады және төменде қалай дәл жазылған.

Ең алдымен, ыңғайлы болу үшін біз оны анықтаймыз werf.yaml Айнымалы үлгілерге өтіңіз, оларға орта айнымалыларынан мәндер тағайындаңыз:

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

Сайттың статикалық нұсқасын құрастыруға арналған артефакттың сипаттамасы әдетте бізге қажет барлық жағдайлар үшін бірдей (соның ішінде түбірлік нұсқаны, сондай-ақ әзірлеу тізбегінің нұсқасын жасау). Сондықтан функцияны пайдаланып, оны бөлек блокқа жылжытамыз define - кейіннен қайта пайдалану үшін include. Үлгіге келесі аргументтерді береміз:

  • Version — құрылған нұсқасы (тег аты);
  • Channel — артефакт жасалатын жаңарту арнасының атауы;
  • Commit — егер артефакт қарап шығу үшін жасалған болса, хэшті орындау;
  • контекст.

Артефакт үлгісінің сипаттамасы

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

Артефакт атауы бірегей болуы керек. Біз бұған, мысалы, арна атауын (айнымалының мәнін) қосу арқылы қол жеткізе аламыз .Channel) артефакт атына жұрнақ ретінде: artifact: doc-{{ .Channel }}. Бірақ сіз артефактілерден импорттау кезінде бірдей атауларға сілтеме жасауыңыз керек екенін түсінуіңіз керек.

Артефактты сипаттау кезінде келесі верф мүмкіндігі пайдаланылады: монтаждау. Қызметтік каталогты көрсететін монтаждау build_dir Jekyll кэшін құбырлар арасында сақтауға мүмкіндік береді, ол қайта құрастыруды айтарлықтай жылдамдатады.

Сіз сондай-ақ файлды пайдалануды байқаған боларсыз releases.yml шығарылым деректері сұралған YAML файлы Github.com (құбырды орындау кезінде алынған артефакт). Бұл сайтты құрастыру кезінде қажет, бірақ мақаланың контекстінде бұл бізге қызықты, өйткені ол оның күйіне байланысты. тек бір артефактты қайта жинау — сайттың түбірлік нұсқасының артефакті (ол басқа артефактілерде қажет емес).

Бұл шартты оператордың көмегімен жүзеге асырылады if Үлгілер мен дизайндарға өтіңіз {{ $Root.Files.Get "releases.yml" | sha256sum }} кезеңде кезеңдер. Ол келесідей жұмыс істейді: түбір нұсқасы үшін артефакт құру кезінде (айнымалы .Channel бар root) файл хэш releases.yml бүкіл кезеңнің қолтаңбасына әсер етеді, өйткені ол Ansible тапсырмасының атауының бөлігі болып табылады (параметр name). Осылайша, өзгерту кезінде мазмұны файл releases.yml сәйкес артефакт қайта жиналады.

Сондай-ақ сыртқы репозиториймен жұмыс істеуге назар аударыңыз. Артефакт бейнесінде werf репозиторийі, тек каталог қосылады /docs, және берілген параметрлерге байланысты қажетті тегтің немесе шолу тапсырмасының деректері дереу қосылады.

Артефакт үлгісін арналар мен шығарылымдардың тасымалданған нұсқаларының артефакті сипаттамасын жасау үшін пайдалану үшін біз айнымалы бойынша цикл ұйымдастырамыз .WerfVersions в werf.yaml:

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

Өйткені цикл бірнеше артефактілерді жасайды (біз солай деп үміттенеміз), олардың арасындағы бөлгішті ескеру қажет - реттілік --- (Конфигурация файлының синтаксисі туралы қосымша ақпаратты қараңыз құжаттама). Бұрын анықталғандай, үлгіні циклде шақырған кезде біз нұсқа параметрлерін, URL мекенжайын және түбірлік контекстті береміз.

Сол сияқты, бірақ циклсыз, біз артефакт үлгісін «ерекше жағдайлар» деп атаймыз: түбірлік нұсқа үшін, сондай-ақ шолу нұсқасы үшін:

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

Тексеру тапсырмасына арналған артефакт айнымалы мән орнатылған жағдайда ғана құрылатынын ескеріңіз .WerfReviewCommit.

Артефактілер дайын - импорттауды бастау уақыты келді!

Kubernetes жүйесінде жұмыс істеуге арналған соңғы кескін сервер конфигурация файлы қосылған кәдімгі NGINX болып табылады. nginx.conf және артефактілерден статикалық. Сайттың түбірлік нұсқасының артефактісіне қосымша, біз айнымалыдағы циклды қайталауымыз керек .WerfVersions арна артефактілерін импорттау және нұсқаларды шығару + біз бұрын қабылдаған артефакті атау ережесін орындаңыз. Әрбір артефакт сайттың екі тілге арналған нұсқаларын сақтайтындықтан, біз оларды конфигурациямен қамтамасыз етілген орындарға импорттаймыз.

Соңғы кескіннің сипаттамасы 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 -}}

Негізгі суретпен бірге әзірлеу тізбегінде іске қосылған қосымша кескінде сайттың тек екі нұсқасы бар: шолу тапсырмасынан алынған нұсқасы және сайттың түбірлік нұсқасы (жалпы активтер бар және есіңізде болса , шығарылым деректері). Осылайша, қосымша кескін негізгіден тек импорт бөлімінде (және, әрине, атауында) ерекшеленеді:

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

Жоғарыда атап өтілгендей, тексеру тапсырмасына арналған артефакт орнатылған орта айнымалысы іске қосылғанда ғана жасалады. REVIEW_SHA. Айнымалы орта болмаса, werf-dev кескінін мүлде жасамау мүмкін еді REVIEW_SHA, бірақ үшін саясат бойынша тазалау Werf ішіндегі Docker кескіндері werf-dev кескіні үшін жұмыс істеді, біз оны тек түбірлік нұсқасы артефактімен (ол бәрібір салынған) құрастыруды қалдырамыз, құбыр құрылымын жеңілдету үшін.

Жиналыс дайын! CI/CD және маңызды нюанстарға көшейік.

GitLab CI жүйесіндегі құбыр желісі және динамикалық құрастыру мүмкіндіктері

Құрылымды іске қосқан кезде біз пайдаланылатын ортаның айнымалы мәндерін орнатуымыз керек werf.yaml. Бұл GitHub ілгегінен конвейерге қоңырау шалу кезінде біз орнататын REVIEW_SHA айнымалысына қолданылмайды.

Біз Bash сценарийінде қажетті сыртқы деректерді жасаймыз generate_artifacts, ол екі GitLab құбыр артефактілерін жасайды:

  • файл releases.yml шығарылым деректерімен,
  • файл common_envs.sh, экспортталатын орта айнымалы мәндерін қамтитын.

Файл мазмұны generate_artifacts бізден табасыз мысалдары бар репозиторийлер. Деректерді қабылдаудың өзі мақаланың тақырыбы емес, файл болып табылады common_envs.sh біз үшін маңызды, өйткені werf жұмысы соған байланысты. Оның мазмұнына мысал:

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'

Сіз мұндай сценарийдің шығысын пайдалана аласыз, мысалы, Bash функциясын пайдалана отырып source.

Енді қызықты бөлік келді. Қолданбаны құрастыру да, орналастыру да дұрыс жұмыс істеуі үшін оны қамтамасыз ету қажет werf.yaml болды бірдей ең аз дегенде бір құбырдың ішінде. Егер бұл шарт орындалмаса, werf құрастыру және, мысалы, орналастыру кезінде есептейтін кезеңдердің қолтаңбалары әртүрлі болады. Бұл орналастыру қатесіне әкеледі, себебі... орналастыруға қажетті сурет жоқ болады.

Басқаша айтқанда, егер сайт кескінін құрастыру кезінде шығарылымдар мен нұсқалар туралы ақпарат бірдей болса және орналастыру кезінде жаңа нұсқа шығарылса және ортаның айнымалы мәндері әртүрлі мәндерге ие болса, онда орналастыру қатемен орындалмайды: Өйткені, жаңа нұсқаның артефакті әлі салынбаған.

Егер ұрпақ werf.yaml сыртқы деректерге байланысты (мысалы, ағымдағы нұсқалардың тізімі, біздің жағдайымызда), онда мұндай деректердің құрамы мен мәндері құбыр ішінде жазылуы керек. Бұл сыртқы параметрлер жиі өзгерсе, әсіресе маңызды.

Біз боламыз сыртқы деректерді қабылдау және жазу GitLab-тағы құбырдың бірінші кезеңінде (Алдын ала құрастыру) және оларды әрі қарай пішінде жіберіңіз GitLab CI артефакті. Бұл сізге конфигурацияда бірдей конфигурациямен құбыр жұмыстарын (құру, орналастыру, тазалау) іске қосуға және қайта бастауға мүмкіндік береді. werf.yaml.

Сахна мазмұны Алдын ала құрастыру файл .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

Артефакттағы сыртқы деректерді түсіріп алған соң, стандартты GitLab CI құбыр желісі кезеңдерін пайдаланып құрастыруға және орналастыруға болады: Құру және орналастыру. Біз құбырды GitHub werf репозиторийіндегі ілгектер арқылы іске қосамыз (яғни, GitHub репозиторийінде өзгерістер болған кезде). Оларға арналған деректерді бөлімдегі GitLab жобасы сипаттарынан табуға болады CI/CD параметрлері -> Құбыр триггерлері, содан кейін GitHub ішінде сәйкес Webhook жасаңыз (Параметрлер -> Webhooks).

Құрастыру кезеңі келесідей болады:

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 сахнадан құрастыру кезеңіне екі артефакт қосады Алдын ала құрастыру, сондықтан біз құрылымды пайдаланып дайындалған кіріс деректерімен айнымалыларды экспорттаймыз source common_envs.sh. Біз құбырды кестеге сәйкес іске қосудан басқа барлық жағдайда құрылыс кезеңін бастаймыз. Кестеге сәйкес біз тазалауға арналған құбырды өткіземіз - бұл жағдайда құрастыруды орындаудың қажеті жоқ.

Орналастыру кезеңінде біз екі тапсырманы сипаттайтын боламыз - YAML үлгісін пайдаланып, өндіріске және әзірлеу схемаларына орналастыру үшін бөлек:

.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

Тапсырмалар werf орналастыруды орындайтын кластер контекстін көрсетуде ғана ерекшеленеді (WERF_KUBE_CONTEXT) және цикл ортасының айнымалы мәндерін орнату (environment.name и environment.url), олар кейін Helm диаграмма үлгілерінде пайдаланылады. Біз үлгілердің мазмұнын бермейміз, себебі... бұл тақырып үшін қызықты ештеңе жоқ, бірақ сіз оларды мына жерден таба аласыз мақалаға арналған репозиторийлер.

Соңғы байланыс

Werf нұсқалары жиі шығарылатындықтан, жаңа кескіндер жиі жасалады және Docker тізілімі үнемі өсіп отырады. Сондықтан, саясаттар негізінде кескінді автоматты түрде тазалауды конфигурациялау міндетті болып табылады. Мұны істеу өте оңай.

Іске асыру үшін сізге қажет:

  • үшін тазалау қадамын қосыңыз .gitlab-ci.yml;
  • Тазалау тапсырмасының мерзімді орындалуын қосу;
  • Жазу рұқсат белгісі бар орта айнымалы мәнін орнатыңыз.

Тазалау кезеңін қосу .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

Біз мұның барлығын дерлік біршама жоғарырақ көрдік – тек оны тазалау үшін алдымен Docker тізіліміндегі кескіндерді жою құқығы бар таңбалауышпен Docker тізіліміне кіру қажет (автоматты түрде шығарылған GitLab CI тапсырма белгісі жоқ. мұндай құқықтары бар). Токенді GitLab жүйесінде алдын ала жасау керек және оның мәні орта айнымалысында көрсетілуі керек WERF_IMAGES_CLEANUP_PASSWORD жоба (CI/CD параметрлері -> Айнымалылар).

Қажетті кестемен тазалау тапсырмасын қосу ішінде орындалады CI/CD ->
Жоспарлар
.

Міне, Docker тізіліміндегі жоба бұдан былай пайдаланылмаған кескіндерден үнемі өспейді.

Практикалық бөлімнің соңында мақаланың толық тізімі мына жерде қолжетімді екенін еске саламын жүру:

нәтиже

  1. Біз логикалық құрастыру құрылымын алдық: әр нұсқаға бір артефакт.
  2. Жинақ әмбебап болып табылады және werf жаңа нұсқалары шыққан кезде қолмен өзгертулерді қажет етпейді: веб-сайттағы құжаттама автоматты түрде жаңартылады.
  3. Әртүрлі контурлар үшін екі сурет жиналған.
  4. Ол тез жұмыс істейді, өйткені Кэштеу мүмкіндігінше пайдаланылады - werf жаңа нұсқасы шығарылғанда немесе GitHub ілгегі шолу тапсырмасына шақырылғанда, өзгертілген нұсқасы бар сәйкес артефакт қана қайта құрылады.
  5. Пайдаланылмаған кескіндерді жою туралы ойлаудың қажеті жоқ: werf саясаттарына сәйкес тазалау Docker тізілімін тәртіпте сақтайды.

қорытындылар

  • werf пайдалану жиынның өзін кэштеу және сыртқы репозиторийлермен жұмыс істеу кезінде кэштеу есебінен жинаққа жылдам жұмыс істеуге мүмкіндік береді.
  • Сыртқы Git репозиторийлерімен жұмыс істеу әр уақытта бүкіл репозиторийді клондау немесе күрделі оңтайландыру логикасы бар дөңгелекті қайта ойлап табу қажеттілігін жояды. werf кэшті пайдаланады және клондауды тек бір рет жасайды, содан кейін пайдаланады fetch және қажет болғанда ғана.
  • Құрастыру конфигурация файлында Go үлгілерін пайдалану мүмкіндігі werf.yaml нәтижесі сыртқы деректерге тәуелді жинақты сипаттауға мүмкіндік береді.
  • Werf-те орнатуды пайдалану артефактілерді жинауды айтарлықтай жылдамдатады - кэшке байланысты, бұл барлық құбырларға ортақ.
  • werf тазалауды конфигурациялауды жеңілдетеді, бұл әсіресе динамикалық түрде құру кезінде маңызды.

PS

Біздің блогта да оқыңыз:

Ақпарат көзі: www.habr.com

пікір қалдыру