Pemasangan dinamik dan penggunaan imej Docker dengan werf menggunakan contoh tapak dokumentasi versi

Kami telah bercakap tentang alat GitOps kami lebih daripada sekali. werf, dan kali ini kami ingin berkongsi pengalaman kami dalam memasang tapak dengan dokumentasi projek itu sendiri - werf.io (versi Rusianya ialah en.werf.io). Ini adalah tapak statik biasa, tetapi pemasangannya menarik kerana ia dibina menggunakan bilangan artifak yang dinamik.

Pemasangan dinamik dan penggunaan imej Docker dengan werf menggunakan contoh tapak dokumentasi versi

Masuk ke nuansa struktur tapak: menjana menu biasa untuk semua versi, halaman dengan maklumat tentang keluaran, dsb. - kami tidak akan. Sebaliknya, mari kita fokus pada isu dan ciri pemasangan dinamik dan sedikit pada proses CI/CD yang disertakan.

Pengenalan: cara tapak berfungsi

Sebagai permulaan, dokumentasi werf disimpan bersama kodnya. Ini mengenakan keperluan pembangunan tertentu yang secara amnya di luar skop artikel ini, tetapi sekurang-kurangnya boleh dikatakan bahawa:

  • Fungsi werf baharu tidak seharusnya dikeluarkan tanpa mengemas kini dokumentasi dan, sebaliknya, sebarang perubahan dalam dokumentasi membayangkan pelepasan versi baharu werf;
  • Projek ini mempunyai pembangunan yang agak intensif: versi baharu boleh dikeluarkan beberapa kali sehari;
  • Sebarang operasi manual untuk menggunakan tapak dengan versi dokumentasi baharu sekurang-kurangnya membosankan;
  • Projek ini menggunakan pendekatan semantik pembuatan versi, dengan 5 saluran kestabilan. Proses pelepasan melibatkan laluan berurutan versi melalui saluran untuk meningkatkan kestabilan: daripada alfa kepada pepejal batu;
  • Tapak ini mempunyai versi bahasa Rusia, yang "hidup dan berkembang" (iaitu, kandungan yang dikemas kini) selari dengan versi utama (iaitu, bahasa Inggeris).

Untuk menyembunyikan semua "dapur dalam" ini daripada pengguna, menawarkan sesuatu yang "hanya berfungsi", kami lakukan alat pemasangan dan kemas kini werf yang berasingan - Adakah multiwerf. Anda hanya perlu menentukan nombor keluaran dan saluran kestabilan yang anda sedia untuk digunakan, dan multiwerf akan menyemak sama ada terdapat versi baharu pada saluran dan memuat turunnya jika perlu.

Dalam menu pilihan versi di tapak web, versi terkini werf tersedia dalam setiap saluran. Secara lalai, mengikut alamat werf.io/documentation versi saluran paling stabil untuk keluaran terkini dibuka - ia juga diindeks oleh enjin carian. Dokumentasi untuk saluran tersedia di alamat berasingan (contohnya, werf.io/v1.0-beta/documentation untuk keluaran beta 1.0).

Secara keseluruhan, laman web ini mempunyai versi berikut yang tersedia:

  1. root (dibuka secara lalai),
  2. untuk setiap saluran kemas kini aktif setiap keluaran (contohnya, werf.io/v1.0-beta).

Untuk menjana versi tapak tertentu, secara amnya, cukup untuk menyusunnya menggunakan Jekylldengan berjalan dalam direktori /docs perintah sepadan repositori werf (jekyll build), selepas bertukar kepada teg Git versi yang diperlukan.

Ia hanya tinggal untuk menambah bahawa:

  • utiliti itu sendiri (werf) digunakan untuk pemasangan;
  • Proses CI/CD dibina berdasarkan GitLab CI;
  • dan semua ini, sudah tentu, berjalan di Kubernetes.

tugas-tugas

Sekarang mari kita rumuskan tugas yang mengambil kira semua spesifik yang diterangkan:

  1. Selepas menukar versi werf pada mana-mana saluran kemas kini dokumentasi di tapak hendaklah dikemas kini secara automatik.
  2. Untuk pembangunan anda perlu boleh kadang-kadang lihat versi pratonton tapak.

Tapak ini mesti disusun semula selepas menukar versi pada mana-mana saluran daripada tag Git yang sepadan, tetapi dalam proses membina imej kami akan mendapat ciri berikut:

  • Memandangkan senarai versi pada saluran berubah, hanya perlu membina semula dokumentasi untuk saluran yang versinya telah berubah. Lagipun, membina semula semuanya tidak begitu bagus.
  • Set saluran untuk keluaran mungkin berubah. Pada satu ketika, sebagai contoh, mungkin tiada versi pada saluran yang lebih stabil daripada keluaran akses awal 1.1, tetapi lama-kelamaan ia akan muncul - dalam kes ini, bukankah anda patut menukar pemasangan secara manual?

Ia ternyata bahawa pemasangan bergantung pada menukar data luaran.

РСализация

Memilih Pendekatan

Sebagai alternatif, anda boleh menjalankan setiap versi yang diperlukan sebagai pod berasingan dalam Kubernetes. Pilihan ini membayangkan bilangan objek yang lebih besar dalam kelompok, yang akan berkembang dengan peningkatan dalam bilangan keluaran werf yang stabil. Dan ini, seterusnya, membayangkan penyelenggaraan yang lebih kompleks: setiap versi mempunyai pelayan HTTP sendiri, dan dengan beban yang kecil. Sudah tentu, ini juga memerlukan kos sumber yang lebih besar.

Kami mengambil jalan yang sama memasang semua versi yang diperlukan dalam satu imej. Statik terkumpul semua versi tapak terletak dalam bekas dengan NGINX, dan trafik ke Deployment yang sepadan datang melalui NGINX Ingress. Struktur ringkas - aplikasi tanpa kewarganegaraan - membolehkan anda menskalakan Deployment dengan mudah (bergantung pada beban) menggunakan Kubernetes itu sendiri.

Untuk lebih tepat, kami mengumpul dua imej: satu untuk litar pengeluaran, yang kedua adalah tambahan untuk litar dev. Imej tambahan digunakan (dilancarkan) hanya pada litar pembangun bersama-sama dengan yang utama dan mengandungi versi tapak daripada komit semakan, dan penghalaan antara mereka dilakukan menggunakan sumber Ingress.

werf vs git klon dan artifak

Seperti yang telah disebutkan, untuk menjana statik tapak untuk versi dokumentasi tertentu, anda perlu membina dengan menukar kepada teg repositori yang sesuai. Anda juga boleh melakukan ini dengan mengklonkan repositori setiap kali anda membina, memilih teg yang sesuai daripada senarai. Walau bagaimanapun, ini adalah operasi yang agak intensif sumber dan, lebih-lebih lagi, memerlukan menulis arahan yang tidak remeh... Satu lagi kelemahan yang serius ialah dengan pendekatan ini tidak ada cara untuk menyimpan sesuatu semasa pemasangan.

Di sini utiliti werf itu sendiri datang untuk membantu kami, melaksanakan caching pintar dan membolehkan anda menggunakan repositori luaran. Menggunakan werf untuk menambah kod dari repositori akan mempercepatkan pembinaan dengan ketara, kerana werf pada asasnya mengklon repositori sekali dan kemudian dilaksanakan sahaja fetch jika perlu. Di samping itu, apabila menambah data dari repositori, kami hanya boleh memilih direktori yang diperlukan (dalam kes kami ini ialah direktori docs), yang akan mengurangkan jumlah data tambahan dengan ketara.

Memandangkan Jekyll ialah alat yang direka untuk menyusun data statik dan tidak diperlukan dalam imej akhir, adalah logik untuk menyusun dalam artifak werf, dan ke dalam imej akhir import hanya hasil kompilasi.

Kami menulis werf.yaml

Jadi, kami memutuskan bahawa kami akan menyusun setiap versi dalam artifak werf yang berasingan. Bagaimanapun kita kita tidak tahu berapa banyak artifak ini akan ada semasa pemasangan, jadi kami tidak boleh menulis konfigurasi binaan tetap (secara tegasnya, kami masih boleh, tetapi ia tidak akan berkesan sepenuhnya).

werf membolehkan anda menggunakan Pergi templat dalam fail konfigurasi anda (werf.yaml), dan ini memungkinkan menjana konfigurasi dengan cepat bergantung pada data luaran (apa yang anda perlukan!). Data luaran dalam kes kami ialah maklumat tentang versi dan keluaran, yang berdasarkannya kami mengumpulkan bilangan artifak yang diperlukan dan sebagai hasilnya kami memperoleh dua imej: werf-doc ΠΈ werf-dev untuk berjalan pada litar yang berbeza.

Data luaran dihantar melalui pembolehubah persekitaran. Berikut adalah komposisi mereka:

  • RELEASES β€” baris dengan senarai keluaran dan versi semasa werf yang sepadan, dalam bentuk senarai nilai yang dipisahkan ruang dalam format <ΠΠžΠœΠ•Π _Π Π•Π›Π˜Π—Π>%<ΠΠžΠœΠ•Π _Π’Π•Π Π‘Π˜Π˜>. Contoh: 1.0%v1.0.4-beta.20
  • CHANNELS β€” baris dengan senarai saluran dan versi werf semasa yang sepadan, dalam bentuk senarai nilai yang dipisahkan ruang dalam format <ΠšΠΠΠΠ›>%<ΠΠžΠœΠ•Π _Π’Π•Π Π‘Π˜Π˜>. Contoh: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION β€” versi keluaran werf untuk dipaparkan secara lalai di tapak (tidak semestinya perlu memaparkan dokumentasi mengikut nombor keluaran tertinggi). Contoh: v1.0.4-beta.20
  • REVIEW_SHA β€” cincang komit semakan yang anda perlukan untuk membina versi untuk gelung ujian.

Pembolehubah ini akan diisi dalam saluran paip GitLab CI, dan bagaimana sebenarnya ditulis di bawah.

Pertama sekali, untuk kemudahan, kami tentukan dalam werf.yaml Pergi pembolehubah templat, berikan mereka nilai daripada pembolehubah persekitaran:

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

Perihalan artifak untuk menyusun versi statik tapak secara amnya adalah sama untuk semua kes yang kami perlukan (termasuk menjana versi akar, serta versi untuk litar pembangun). Oleh itu, kami akan mengalihkannya ke dalam blok berasingan menggunakan fungsi tersebut define - untuk penggunaan semula seterusnya include. Kami akan menyampaikan hujah berikut kepada templat:

  • Version β€” versi yang dijana (nama tag);
  • Channel β€” nama saluran kemas kini yang artifak dijana;
  • Commit β€” commit hash, jika artifak dijana untuk commit semakan;
  • konteks.

Penerangan Templat Artifak

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

Nama artifak mestilah unik. Kita boleh mencapai ini, sebagai contoh, dengan menambah nama saluran (nilai pembolehubah .Channel) sebagai akhiran kepada nama artifak: artifact: doc-{{ .Channel }}. Tetapi anda perlu memahami bahawa apabila mengimport daripada artifak, anda perlu merujuk kepada nama yang sama.

Apabila menerangkan artifak, ciri werf berikut digunakan: melekap. Pemasangan yang menunjukkan direktori perkhidmatan build_dir membolehkan anda menyimpan cache Jekyll antara saluran paip, yang dengan ketara mempercepatkan pemasangan semula.

Anda juga mungkin perasan penggunaan fail tersebut releases.yml ialah fail YAML dengan data keluaran yang diminta daripada Github.com (artifak yang diperoleh semasa melaksanakan saluran paip). Ia diperlukan semasa menyusun tapak, tetapi dalam konteks artikel itu menarik bagi kami kerana ia bergantung pada keadaannya pemasangan semula hanya satu artifak β€” artifak versi akar tapak (ia tidak diperlukan dalam artifak lain).

Ini dilaksanakan menggunakan pernyataan bersyarat if Pergi templat dan reka bentuk {{ $Root.Files.Get "releases.yml" | sha256sum }} dalam pentas peringkat. Ia berfungsi seperti berikut: apabila membina artifak untuk versi akar (pembolehubah .Channel sama dengan root) cincang fail releases.yml mempengaruhi tandatangan seluruh peringkat, kerana ia adalah sebahagian daripada nama tugas Ansible (parameter name). Justeru, apabila berubah kandungan fail releases.yml artifak yang sepadan akan dipasang semula.

Sila beri perhatian juga untuk bekerja dengan repositori luaran. Dalam imej artifak daripada repositori werf, hanya direktori ditambah /docs, dan bergantung pada parameter yang diluluskan, data teg yang diperlukan atau komit semakan ditambah serta-merta.

Untuk menggunakan templat artifak untuk menjana perihalan artifak versi saluran dan keluaran yang dipindahkan, kami mengatur gelung pada pembolehubah .WerfVersions Π² werf.yaml:

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

Kerana gelung akan menghasilkan beberapa artifak (kami harap begitu), perlu mengambil kira pemisah di antara mereka - urutan --- (Untuk maklumat lanjut tentang sintaks fail konfigurasi, lihat dokumentasi). Seperti yang ditakrifkan sebelum ini, apabila memanggil templat dalam gelung, kami lulus parameter versi, URL dan konteks akar.

Begitu juga, tetapi tanpa gelung, kami memanggil templat artifak untuk "kes khas": untuk versi akar, serta versi daripada komit semakan:

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

Sila ambil perhatian bahawa artifak untuk komit semakan hanya akan dibina jika pembolehubah ditetapkan .WerfReviewCommit.

Artifak sudah sedia - sudah tiba masanya untuk mula mengimport!

Imej akhir, yang direka untuk dijalankan pada Kubernetes, ialah NGINX biasa dengan fail konfigurasi pelayan ditambah nginx.conf dan statik daripada artifak. Sebagai tambahan kepada artifak versi akar tapak, kita perlu mengulangi gelung pada pembolehubah .WerfVersions untuk mengimport artifak saluran dan versi keluaran + ikut peraturan penamaan artifak yang kami pakai sebelum ini. Memandangkan setiap artifak menyimpan versi tapak untuk dua bahasa, kami mengimportnya ke tempat yang disediakan oleh konfigurasi.

Perihalan imej akhir 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 -}}

Imej tambahan, yang, bersama-sama dengan yang utama, dilancarkan pada litar dev, mengandungi hanya dua versi tapak: versi dari komit semakan dan versi akar tapak (terdapat aset umum dan, jika anda ingat , keluarkan data). Oleh itu, imej tambahan akan berbeza daripada yang utama hanya dalam bahagian import (dan, sudah tentu, dalam nama):

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

Seperti yang dinyatakan di atas, artifak untuk komit semakan akan dijana hanya apabila pembolehubah persekitaran yang ditetapkan dijalankan REVIEW_SHA. Adalah mungkin untuk tidak menjana imej werf-dev sama sekali jika tiada pembolehubah persekitaran REVIEW_SHA, tetapi untuk pembersihan mengikut dasar Imej Docker dalam werf berfungsi untuk imej werf-dev, kami akan membiarkannya dibina hanya dengan artifak versi akar (ia sudah dibina), untuk memudahkan struktur saluran paip.

Perhimpunan sudah siap! Mari kita beralih kepada CI/CD dan nuansa penting.

Saluran paip dalam GitLab CI dan ciri binaan dinamik

Apabila menjalankan binaan kita perlu menetapkan pembolehubah persekitaran yang digunakan werf.yaml. Ini tidak terpakai pada pembolehubah REVIEW_SHA, yang akan kami tetapkan semasa memanggil saluran paip daripada cangkuk GitHub.

Kami akan menjana data luaran yang diperlukan dalam skrip Bash generate_artifacts, yang akan menghasilkan dua artifak saluran paip GitLab:

  • fail releases.yml dengan data keluaran,
  • fail common_envs.sh, yang mengandungi pembolehubah persekitaran untuk dieksport.

Kandungan fail generate_artifacts anda akan dapati dalam kami repositori dengan contoh. Menerima data itu sendiri bukan subjek artikel, tetapi fail common_envs.sh adalah penting bagi kami, kerana kerja werf bergantung padanya. Contoh kandungannya:

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'

Anda boleh menggunakan output skrip sedemikian, contohnya, menggunakan fungsi Bash source.

Sekarang datang bahagian yang menyeronokkan. Agar kedua-dua binaan dan penggunaan aplikasi berfungsi dengan betul, adalah perlu untuk memastikannya werf.yaml adalah sama paling tidak dalam satu saluran paip. Jika syarat ini tidak dipenuhi, maka tandatangan peringkat yang werf mengira semasa pemasangan dan, sebagai contoh, penempatan, akan berbeza. Ini akan membawa kepada ralat penggunaan, kerana... imej yang diperlukan untuk penempatan akan hilang.

Dalam erti kata lain, jika semasa pemasangan imej tapak maklumat tentang keluaran dan versi adalah sama, dan pada masa penggunaan versi baharu dikeluarkan dan pembolehubah persekitaran mempunyai nilai yang berbeza, maka penggunaan akan gagal dengan ralat: lagipun, artifak versi baharu itu belum lagi dibina.

Jika generasi werf.yaml bergantung pada data luaran (contohnya, senarai versi semasa, seperti dalam kes kami), maka komposisi dan nilai data tersebut harus direkodkan dalam saluran paip. Ini amat penting jika parameter luaran berubah agak kerap.

Kami akan menerima dan merekod data luaran pada peringkat pertama saluran paip dalam GitLab (Prabina) dan menghantarnya lagi dalam bentuk Artifak GitLab CI. Ini akan membolehkan anda menjalankan dan memulakan semula kerja saluran paip (membina, menggunakan, membersihkan) dengan konfigurasi yang sama masuk werf.yaml.

Kandungan pentas Prabina fail .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

Setelah menangkap data luaran dalam artifak, anda boleh membina dan menggunakan menggunakan peringkat saluran paip CI GitLab standard: Bina dan Gunakan. Kami melancarkan saluran paip itu sendiri menggunakan cangkuk dari repositori GitHub werf (iaitu, apabila terdapat perubahan dalam repositori GitHub). Data untuk mereka boleh didapati dalam sifat projek GitLab dalam bahagian tersebut Tetapan CI/CD -> Pencetus saluran paip, dan kemudian buat Webhook yang sepadan dalam GitHub (Tetapan -> Webhooks).

Peringkat binaan akan kelihatan seperti ini:

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 akan menambah dua artifak dari peringkat ke peringkat binaan Prabina, jadi kami mengeksport pembolehubah dengan data input yang disediakan menggunakan konstruk source common_envs.sh. Kami memulakan peringkat binaan dalam semua kes, kecuali untuk melancarkan saluran paip mengikut jadual. Mengikut jadual, kami akan menjalankan saluran paip untuk pembersihan - dalam kes ini tidak perlu melakukan pemasangan.

Pada peringkat penggunaan, kami akan menerangkan dua tugas - secara berasingan untuk penggunaan ke litar pengeluaran dan pembangun, menggunakan templat 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

Tugas pada dasarnya berbeza hanya dalam menunjukkan konteks kluster di mana werf harus melaksanakan penempatan (WERF_KUBE_CONTEXT), dan menetapkan pembolehubah persekitaran gelung (environment.name ΠΈ environment.url), yang kemudiannya digunakan dalam templat carta Helm. Kami tidak akan menyediakan kandungan templat, kerana... tiada apa-apa yang menarik di sana untuk topik yang dipersoalkan, tetapi anda boleh menemuinya repositori untuk artikel.

Sentuhan akhir

Memandangkan versi werf dikeluarkan agak kerap, imej baharu akan dibina dengan kerap, dan Pendaftaran Docker akan sentiasa berkembang. Oleh itu, adalah penting untuk mengkonfigurasi pembersihan imej automatik berdasarkan dasar. Ia sangat mudah untuk dilakukan.

Untuk melaksanakan anda perlu:

  • Tambahkan langkah pembersihan ke .gitlab-ci.yml;
  • Tambah pelaksanaan berkala tugas pembersihan;
  • Sediakan pembolehubah persekitaran dengan token akses tulis.

Menambah peringkat pembersihan ke .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

Kami telah melihat hampir semua ini sedikit lebih tinggi - hanya untuk membersihkannya anda perlu log masuk terlebih dahulu ke Docker Registry dengan token yang mempunyai hak untuk memadam imej dalam Docker Registry (token tugas GitLab CI yang dikeluarkan secara automatik tidak mempunyai hak sedemikian). Token mesti dibuat dalam GitLab terlebih dahulu dan nilainya mesti dinyatakan dalam pembolehubah persekitaran WERF_IMAGES_CLEANUP_PASSWORD projek (Tetapan CI/CD -> Pembolehubah).

Menambah tugas pembersihan dengan jadual yang diperlukan telah dilakukan CI/CD ->
Jadual
.

Itu sahaja: projek dalam Pendaftaran Docker tidak lagi akan terus berkembang daripada imej yang tidak digunakan.

Pada penghujung bahagian praktikal, izinkan saya mengingatkan anda bahawa penyenaraian penuh daripada artikel itu tersedia dalam Git:

Keputusan

  1. Kami menerima struktur pemasangan logik: satu artifak setiap versi.
  2. Pemasangan adalah universal dan tidak memerlukan perubahan manual apabila versi baru werf dikeluarkan: dokumentasi di tapak web dikemas kini secara automatik.
  3. Dua imej dipasang untuk kontur yang berbeza.
  4. Ia berfungsi dengan cepat, kerana Caching digunakan sebanyak mungkin - apabila versi baharu werf dikeluarkan atau cangkuk GitHub dipanggil untuk komit semakan, hanya artifak yang sepadan dengan versi yang diubah itu dibina semula.
  5. Tidak perlu memikirkan tentang memadam imej yang tidak digunakan: pembersihan mengikut dasar werf akan memastikan Pendaftaran Docker sentiasa teratur.

Penemuan

  • Menggunakan werf membolehkan pemasangan berfungsi dengan cepat kerana caching kedua-dua pemasangan itu sendiri dan caching apabila bekerja dengan repositori luaran.
  • Bekerja dengan repositori Git luaran menghapuskan keperluan untuk mengklon keseluruhan repositori setiap kali atau mencipta semula roda dengan logik pengoptimuman yang rumit. werf menggunakan cache dan melakukan pengklonan sekali sahaja, dan kemudian menggunakan fetch dan hanya apabila perlu.
  • Keupayaan untuk menggunakan templat Go dalam fail konfigurasi binaan werf.yaml membolehkan anda menerangkan perhimpunan yang hasilnya bergantung pada data luaran.
  • Menggunakan mount in werf dengan ketara mempercepatkan pengumpulan artifak - disebabkan oleh cache, yang biasa kepada semua saluran paip.
  • werf memudahkan untuk mengkonfigurasi pembersihan, yang amat penting apabila membina secara dinamik.

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen