Perakitan dinamis dan penyebaran gambar Docker dengan werf menggunakan contoh situs dokumentasi versi

Kami telah berbicara tentang alat GitOps werf kami lebih dari sekali , tetapi kali ini kami ingin berbagi pengalaman membangun situs dengan dokumentasi proyek - werf.io (versi Rusia-nya adalah ru.werf.io ). Ini adalah situs statis biasa, tetapi rakitannya menarik karena dibangun menggunakan sejumlah artefak yang dinamis.



Pergilah ke nuansa struktur situs: menghasilkan menu umum untuk semua versi, halaman dengan informasi tentang rilis, dll. - kami tidak akan. Sebagai gantinya, kami fokus pada masalah dan fitur perakitan dinamis dan sedikit pada proses CI / CD yang menyertainya.

Pendahuluan: bagaimana situs diatur


Untuk mulai dengan, dokumentasi werf disimpan bersama dengan kodenya. Ini membuat persyaratan pengembangan tertentu yang umumnya melampaui ruang lingkup artikel ini, tetapi setidaknya kita dapat mengatakan bahwa:

  • Fungsi werf baru tidak boleh dirilis tanpa memperbarui dokumentasi dan, sebaliknya, setiap perubahan dalam dokumentasi menyiratkan rilis versi werf baru;
  • Proyek ini memiliki pengembangan yang agak intensif: versi baru mungkin keluar beberapa kali sehari;
  • Setiap penyebaran manual situs dengan versi baru dari dokumentasi setidaknya membosankan;
  • Proyek ini mengadopsi pendekatan versi semantik, dengan 5 saluran stabilitas. Proses rilis melibatkan bagian berurutan versi melalui saluran untuk meningkatkan stabilitas: dari alpha ke rock-solid;
  • Situs ini memiliki versi bahasa Rusia, yang "hidup dan berkembang" (yaitu, konten yang diperbarui) secara paralel dengan versi utama (yaitu bahasa Inggris).

Untuk menyembunyikan dari semua pengguna "dapur dalam" ini, menawarkan apa yang "hanya berfungsi", kami membuat alat instalasi dan pembaruan werf yang terpisah - ini adalah multiwerf . Cukup untuk menunjukkan nomor rilis dan saluran stabilitas yang siap Anda gunakan, dan multiwerf akan memeriksa apakah ada versi baru pada saluran dan mengunduhnya jika perlu.

Versi werf terbaru di setiap saluran tersedia di menu pilihan versi di situs. Secara default, versi saluran paling stabil untuk rilis terbaru terbuka di werf.io/documentation - ini juga diindeks oleh mesin pencari. Dokumentasi untuk saluran tersedia di masing-masing alamat (misalnya, werf.io/v1.0-beta/documentation untuk rilis beta 1.0).

Total, situs ini memiliki versi berikut:

  1. root (terbuka secara default)
  2. untuk setiap saluran pembaruan aktif dari setiap rilis (misalnya, werf.io/v1.0-beta ).

Untuk menghasilkan versi tertentu dari situs dalam kasus umum, cukup mengkompilasinya menggunakan alat Jekyll dengan menjalankan perintah yang sesuai ( jekyll build ) di direktori /docs dari repositori werf, setelah beralih ke tag Git dari versi yang diperlukan.

Tinggal menambahkan saja:

  • utilitas itu sendiri (werf) digunakan untuk perakitan;
  • Proses CI / CD didasarkan pada GitLab CI;
  • dan semua ini, tentu saja, berfungsi di Kubernetes.

Tugasnya


Sekarang kami merumuskan tugas yang memperhitungkan semua spesifik yang dijelaskan:

  1. Setelah mengubah versi werf pada saluran pembaruan apa pun, dokumentasi di situs harus diperbarui secara otomatis .
  2. Untuk pengembangan, Anda harus dapat melihat pratinjau versi awal situs .

Rekompilasi situs harus dilakukan setelah mengubah versi pada saluran apa pun dari tag Git yang sesuai, tetapi dalam proses membangun gambar kita akan mendapatkan fitur berikut:

  • Karena daftar versi di saluran berubah, Anda hanya perlu memasang kembali dokumentasi untuk saluran di mana versi telah berubah. Lagi pula, merakit kembali semuanya tidak terlalu indah.
  • Serangkaian saluran untuk rilis dapat bervariasi. Di beberapa titik waktu, misalnya, versi pada saluran mungkin tidak lebih stabil daripada rilis awal akses 1.1, tetapi seiring waktu mereka akan muncul - jangan mengubah perakitan dengan tangan dalam kasus ini?

Ternyata perakitan tergantung pada perubahan data eksternal .

Implementasi


Pilihan pendekatan


Atau, Anda dapat menjalankan setiap versi yang diperlukan dengan pod terpisah di Kubernetes. Opsi ini menyiratkan jumlah objek yang lebih besar di cluster, yang akan tumbuh dengan peningkatan jumlah rilis werf yang stabil. Dan ini pada gilirannya menyiratkan layanan yang lebih kompleks: setiap versi memiliki server HTTP sendiri, dan dengan beban kecil. Tentu saja, ini memerlukan biaya yang lebih tinggi untuk sumber daya.

Kami menyusuri jalur perakitan semua versi yang diperlukan dalam satu gambar . Statika yang dikompilasi dari semua versi situs berada dalam wadah dengan NGINX, dan lalu lintas ke Penyebaran yang sesuai datang melalui NGINX Ingress. Struktur sederhana - aplikasi tanpa kewarganegaraan - membuatnya mudah untuk skala Penempatan (tergantung pada beban) menggunakan Kubernetes itu sendiri.

Untuk lebih tepatnya, kami mengumpulkan dua gambar: satu untuk sirkuit produksi, yang lain untuk sirkuit dev. Gambar tambahan digunakan (diluncurkan) hanya pada sirkuit dev bersama-sama dengan yang utama dan berisi versi situs dari komit ulasan, dan routing di antara mereka dilakukan menggunakan sumber daya Ingress.

werf vs git clone dan artefak


Seperti yang telah disebutkan, untuk menghasilkan statika situs untuk versi dokumentasi tertentu, Anda perlu membangun dengan beralih ke tag repositori yang sesuai. Kita juga bisa melakukan ini dengan mengkloning repositori setiap kali selama perakitan, memilih tag yang sesuai dari daftar. Namun, ini adalah operasi yang menghabiskan banyak sumber daya dan, terlebih lagi, membutuhkan penulisan instruksi non-sepele ... minus serius lainnya - dengan pendekatan ini tidak ada cara untuk cache sesuatu selama perakitan.

Di sini utilitas werf datang ke bantuan kami, yang mengimplementasikan caching cerdas dan memungkinkan penggunaan repositori eksternal . Menggunakan werf untuk menambahkan kode dari repositori akan secara signifikan mempercepat pembangunan, seperti werf pada dasarnya melakukan repositori sekali, dan kemudian hanya fetch jika perlu. Selain itu, ketika menambahkan data dari repositori, kita hanya dapat memilih direktori yang diperlukan (dalam kasus kami, ini adalah direktori docs ), yang secara signifikan akan mengurangi jumlah data yang ditambahkan.

Karena Jekyll adalah alat yang dirancang untuk mengkompilasi statika dan tidak diperlukan dalam gambar akhir, akan logis untuk mengkompilasi dalam artefak werf , dan hanya mengimpor hasil kompilasi ke dalam gambar akhir.

Menulis werf.yaml


Jadi, kami memutuskan bahwa kami akan mengkompilasi setiap versi dalam artefak werf yang terpisah. Namun, kami tidak tahu berapa banyak artefak ini akan terjadi selama perakitan , oleh karena itu kami tidak dapat menulis konfigurasi perakitan tetap (secara tegas, kami masih bisa, tetapi itu tidak akan sepenuhnya efektif).

werf memungkinkan Anda untuk menggunakan templat Go dalam file konfigurasi Anda ( werf.yaml ), dan ini memungkinkan untuk membuat konfigurasi "on the fly" tergantung pada data eksternal (apa yang Anda butuhkan!). Data eksternal dalam kasus kami adalah informasi tentang versi dan rilis, atas dasar di mana kami mengumpulkan jumlah artefak yang diperlukan dan mendapatkan dua gambar sebagai hasilnya: werf-doc dan werf-dev untuk meluncurkan di jalur yang berbeda.

Data eksternal dilewatkan melalui variabel lingkungan. Berikut komposisinya:

  • RELEASES - sebuah baris dengan daftar rilis dan versi terkini dari werf, dalam bentuk daftar, dipisahkan oleh spasi, dalam format <_>%<_> . Contoh: 1.0%v1.0.4-beta.20
  • CHANNELS - baris dengan daftar saluran dan versi werf saat ini, dalam bentuk daftar dengan ruang nilai dalam format <>%<_> . Contoh: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION - Versi rilis werf untuk ditampilkan secara default di situs (tidak selalu diperlukan untuk menampilkan dokumentasi untuk nomor rilis tertinggi). Contoh: v1.0.4-beta.20
  • REVIEW_SHA - hash dari ulasan komit yang darinya Anda perlu mengumpulkan versi untuk loop tes.

Variabel-variabel ini akan diisi dalam pipa GitLab CI, dan bagaimana tepatnya dijelaskan di bawah ini.

Pertama-tama, untuk kenyamanan, kami mendefinisikan variabel Go-templat di werf.yaml menetapkan nilai dari variabel lingkungan:

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

Deskripsi artefak untuk mengkompilasi statika versi situs umumnya sama untuk semua kasus yang kita butuhkan (termasuk generasi versi root, serta versi untuk rangkaian dev). Oleh karena itu, kami akan menempatkannya di blok terpisah menggunakan fungsi define - untuk digunakan kembali selanjutnya dengan include . Kami akan meneruskan argumen berikut ke templat:

  • Version - versi yang dihasilkan (nama tag);
  • Channel - nama saluran pembaruan yang menghasilkan artefak;
  • Commit - komit hash jika artifak dihasilkan untuk ulasan komit;
  • konteks.

Deskripsi Template Artefak
 {{- 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 artefak harus unik. Kita dapat mencapai ini, misalnya, dengan menambahkan nama saluran (nilai variabel .Channel ) sebagai akhiran untuk nama artifact: artifact: doc-{{ .Channel }} . Tetapi Anda perlu memahami bahwa saat mengimpor dari artefak, Anda harus merujuk nama yang sama.

Saat menggambarkan artefak, fitur werf seperti mount digunakan . Pemasangan dengan direktori layanan build_dir memungkinkan Anda untuk menyimpan cache Jekyll di antara mulai pipa, yang sangat mempercepat pembangunan kembali .

Anda mungkin juga telah memperhatikan penggunaan file releases.yml - ini adalah file YAML dengan data rilis yang diminta dari github.com (artefak yang diperoleh dengan mengeksekusi pipa). Hal ini diperlukan saat menyusun situs, tetapi dalam konteks artikel kami tertarik pada fakta bahwa hanya satu artefak , artefak versi situs root , yang tergantung pada kondisinya (pada artefak lain tidak diperlukan).

Ini diimplementasikan menggunakan operator kondisional untuk templat {{ $Root.Files.Get "releases.yml" | sha256sum }} go dan {{ $Root.Files.Get "releases.yml" | sha256sum }} {{ $Root.Files.Get "releases.yml" | sha256sum }} di panggung panggung . Ini berfungsi sebagai berikut: ketika merakit artefak untuk versi root (variabel .Channel adalah root ), hash dari file releases.yml mempengaruhi tanda tangan dari seluruh tahapan, karena itu adalah komponen dari nama pekerjaan yang dimungkinkan (parameter name ). Dengan demikian, ketika mengubah isi file releases.yml , artefak yang sesuai akan dibangun kembali.

Perhatikan juga untuk bekerja dengan repositori eksternal. Hanya direktori /docs yang ditambahkan ke gambar artefak dari repositori werf , dan tergantung pada parameter yang dikirimkan, data dari tag yang diperlukan atau komit peninjauan ditambahkan segera.

Untuk menggunakan templat artefak untuk menghasilkan deskripsi artefak dari versi saluran dan rilis yang ditransfer, kami mengatur loop pada variabel .WerfVersions di werf.yaml :

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

Karena loop akan menghasilkan beberapa artefak (kami harap demikian), perlu untuk mempertimbangkan pemisah di antara mereka - urutan --- (untuk informasi lebih lanjut tentang sintaks dari file konfigurasi, lihat dokumentasi ). Seperti yang ditentukan sebelumnya, saat Anda memanggil templat dalam satu lingkaran, kami meneruskan parameter versi, URL, dan konteks root.

Demikian pula, tetapi sudah tanpa loop, kami memanggil template artefak untuk "kasus khusus": untuk versi root, serta versi dari komit ulasan:

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

Harap perhatikan bahwa artefak untuk komit ulasan hanya akan dikumpulkan jika variabel .WerfReviewCommit .

Artefak sudah siap - saatnya untuk mengimpor!

Gambar terakhir, yang dirancang untuk dijalankan di Kubernetes, adalah NGINX biasa, di mana file konfigurasi server nginx.conf dan statika dari artefak ditambahkan. Selain artefak versi root situs, kita perlu mengulangi loop pada variabel .WerfVersions untuk mengimpor artefak dari versi saluran dan rilis + perhatikan aturan penamaan artefak yang kita adopsi sebelumnya. Karena setiap artefak menyimpan versi situs untuk dua bahasa, kami mengimpornya ke tempat-tempat yang disediakan oleh konfigurasi.

Deskripsi gambar werf-doc akhir
 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 -}} 

Gambar tambahan, yang, bersama dengan gambar utama, diluncurkan di sirkuit dev, hanya berisi dua versi situs: versi dari komit ulasan dan versi root situs (ada aset umum dan, jika Anda ingat, lepaskan data). Dengan demikian, gambar tambahan dari gambar utama hanya akan berbeda di bagian impor (dan, tentu saja, 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 sudah disebutkan di atas, artefak untuk komit peninjauan hanya akan dihasilkan ketika werf mulai dengan variabel lingkungan yang REVIEW_SHA . Mungkin untuk tidak menghasilkan gambar werf-dev sama sekali jika tidak ada REVIEW_SHA lingkungan REVIEW_SHA , tetapi agar pembersihan kebijakan berbasis-werf-dev untuk gambar Docker berfungsi untuk gambar werf-dev, kami membiarkannya dikumpulkan hanya dengan artefak versi root (lagi pula, itu sudah terpasang), untuk menyederhanakan struktur pipa.

Majelis sudah siap! Kami beralih ke CI / CD dan nuansa penting.

Pipeline di GitLab CI dan fitur perakitan dinamis


Saat memulai perakitan, kita perlu mengatur variabel lingkungan yang digunakan di werf.yaml . Ini tidak berlaku untuk variabel REVIEW_SHA, yang akan kami atur saat pipa dipanggil dari kait GitHub.

Kami akan menghasilkan data eksternal yang diperlukan dalam skrip Bash generate_artifacts , yang akan menghasilkan dua artefak pipa GitLab:

  • file releases.yml dengan data rilis,
  • file common_envs.sh mengandung variabel lingkungan untuk diekspor.

Anda akan menemukan konten file generate_artifacts di repositori contoh kami. Memperoleh data bukan subjek artikel, tetapi file common_envs.sh penting bagi kami, karena pekerjaan werf tergantung padanya. Contoh isinya:

 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 dapat menggunakan output dari skrip tersebut, misalnya, menggunakan fungsi Bash source .

Dan sekarang untuk bagian yang menyenangkan. Agar aplikasi build dan deploy berfungsi dengan baik, Anda harus membuat werf.yaml sama untuk setidaknya satu pipeline . Jika kondisi ini tidak terpenuhi, maka tanda tangan dari tahapan yang tidak dihitung selama perakitan dan, misalnya, penyebaran, akan berbeda. Ini akan menyebabkan kesalahan penggunaan, seperti gambar yang diperlukan untuk penempatan tidak ada.

Dengan kata lain, jika selama perakitan gambar situs, informasi tentang rilis dan versi adalah satu, dan pada saat rilis versi baru dirilis dan variabel lingkungan memiliki nilai yang berbeda, maka penyebaran akan gagal dengan kesalahan: artefak versi baru belum dikumpulkan.

Jika generasi werf.yaml tergantung pada data eksternal (misalnya, daftar versi saat ini, seperti dalam kasus kami), maka komposisi dan nilai data tersebut harus dicatat dalam pipa. Ini sangat penting jika parameter eksternal berubah cukup sering.

Kami akan menerima dan menangkap data eksternal pada tahap pertama pipeline di GitLab ( Prebuild ) dan mentransfernya lebih jauh sebagai artefak GitLab CI . Ini akan memungkinkan Anda untuk memulai dan memulai kembali tugas-tugas pipa (build, deploy, cleanup) dengan konfigurasi yang sama di werf.yaml .

Isi tahap Prebuild dari file .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 

Dengan mengambil data eksternal dalam sebuah artefak, Anda dapat membangun dan menggunakan menggunakan tahapan pipa GitLab CI standar: Build and Deploy. Kami meluncurkan pipa dengan kait dari wer repositori gerHub (mis. Ketika mengubah repositori di GitHub). Data untuk mereka dapat diambil di properti proyek GitLab di Pengaturan CI / CD -> Bagian pemicu Pipa , dan kemudian buat Webhook yang sesuai ( Pengaturan -> Webhooks ) di GitHub.

Tahap pembuatan akan terlihat 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 menambahkan dua artefak dari tahap Prebuild ke fase build, jadi kami mengekspor variabel dengan input yang disiapkan menggunakan source common_envs.sh . Kami memulai tahap perakitan dalam semua kasus, kecuali untuk peluncuran pipa sesuai jadwal. Sesuai dengan jadwal, pipa akan diluncurkan untuk pembersihan - kita tidak perlu membangun dalam hal ini.

Pada tahap penerapan, kami menjelaskan dua tugas - secara terpisah untuk penempatan ke sirkuit produksi dan dev, 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-tugas pada dasarnya berbeda hanya dengan menunjukkan konteks cluster yang werf harus melaksanakan penyebaran ( WERF_KUBE_CONTEXT ) dan mengatur variabel lingkungan dari kontur ( environment.name dan environment.url ), yang kemudian digunakan dalam templat grafik Helm. Konten template tidak akan diberikan, karena tidak ada yang menarik untuk topik ini, tetapi Anda dapat menemukannya di repositori artikel .

Sentuhan terakhir


Karena versi werf dirilis cukup sering, gambar baru akan sering dikumpulkan, dan Docker Registry akan terus tumbuh. Oleh karena itu, perlu untuk mengkonfigurasi pembersihan otomatis gambar oleh kebijakan. Sangat mudah dilakukan.

Untuk implementasi Anda perlu:

  • Tambahkan langkah pemurnian ke .gitlab-ci.yml ;
  • Tambahkan tugas pembersihan berkala;
  • Setel variabel lingkungan dengan token akses tulis.

Tambahkan tahap 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 

Hampir semua dari kita telah melihat ini sedikit lebih tinggi - hanya untuk pembersihan Anda harus terlebih dahulu masuk ke Docker Registry dengan token yang memiliki hak untuk menghapus gambar di Docker Registry (token tugas GitLab CI yang dikeluarkan secara otomatis tidak memiliki hak seperti itu). Token harus dimasukkan ke GitLab terlebih dahulu dan nilainya harus ditentukan dalam variabel lingkungan WERF_IMAGES_CLEANUP_PASSWORD proyek (Pengaturan CI / CD -> Variabel) .

Menambahkan tugas pembersihan dengan jadwal yang diperlukan dilakukan dalam CI / CD ->
Jadwal

Itu dia: proyek di Docker Registry tidak akan lagi tumbuh terus-menerus dari gambar yang tidak digunakan.

Di akhir bagian praktis, saya ingat bahwa daftar lengkap dari artikel tersebut tersedia di Git :


Hasil


  1. Kami mendapat struktur build logis: satu artefak per versi.
  2. Perakitan bersifat universal dan tidak memerlukan perubahan manual ketika versi baru werf dirilis: dokumentasi di situs diperbarui secara otomatis.
  3. Dua gambar dikumpulkan untuk kontur yang berbeda.
  4. Ini bekerja cepat karena caching digunakan secara maksimal - ketika versi baru werf dilepaskan atau kait GitHub dipanggil untuk komit ulasan, hanya artefak yang sesuai dengan versi yang dimodifikasi yang dibangun kembali.
  5. Tidak perlu berpikir tentang menghapus gambar yang tidak digunakan: pembersihan kebijakan werf akan menjaga ketertiban di Docker Registry.

Kesimpulan


  • Menggunakan werf memungkinkan perakitan bekerja dengan cepat berkat caching baik perakitan itu sendiri maupun caching ketika bekerja dengan repositori eksternal.
  • Git- . werf , fetch .
  • Go- werf.yaml , .
  • werf โ€” , pipeline.
  • werf , .

PS


:

Source: https://habr.com/ru/post/id478690/


All Articles