Pag-tag na nakabatay sa nilalaman sa werf collector: bakit at paano ito gumagana?

Pag-tag na nakabatay sa nilalaman sa werf collector: bakit at paano ito gumagana?

werf ay ang aming open source na GitOps CLI utility para sa pagbuo at paghahatid ng mga application sa Kubernetes. SA ilabas ang v1.1 isang bagong tampok ang ipinakilala sa kolektor ng imahe: pag-tag ng mga larawan ayon sa nilalaman o pag-tag na nakabatay sa nilalaman. Hanggang ngayon, ang karaniwang pamamaraan ng pag-tag sa werf ay nagsasangkot ng pag-tag ng mga larawan ng Docker sa pamamagitan ng Git tag, Git branch o Git commit. Ngunit lahat ng mga scheme na ito ay may mga disadvantages na ganap na nalutas ng bagong diskarte sa pag-tag. Ang mga detalye tungkol dito at kung bakit ito napakahusay ay nasa ilalim ng hiwa.

Paglulunsad ng isang set ng mga microservice mula sa isang Git repository

Ang isang sitwasyon ay madalas na nangyayari kapag ang isang aplikasyon ay nahahati sa marami o mas kaunting mga independiyenteng serbisyo. Ang mga pagpapalabas ng mga serbisyong ito ay maaaring mangyari nang nakapag-iisa: ang isa o higit pang mga serbisyo ay maaaring ilabas sa isang pagkakataon, habang ang iba ay dapat na patuloy na gumana nang walang anumang mga pagbabago. Ngunit mula sa punto ng view ng pag-iimbak ng code at pamamahala ng proyekto, mas maginhawang panatilihin ang mga naturang serbisyo ng aplikasyon sa isang solong imbakan.

May mga sitwasyon kapag ang mga serbisyo ay tunay na independyente at hindi nauugnay sa isang aplikasyon. Sa kasong ito, sila ay matatagpuan sa magkahiwalay na mga proyekto at ang kanilang pagpapalabas ay isasagawa sa pamamagitan ng magkahiwalay na mga proseso ng CI/CD sa bawat proyekto.

Gayunpaman, sa katotohanan, ang mga developer ay madalas na naghahati ng isang application sa ilang mga microservice, ngunit ang paglikha ng isang hiwalay na repository at proyekto para sa bawat isa... ay isang malinaw na overkill. Ito ang sitwasyong ito ang tatalakayin pa: ang ilang mga naturang microservice ay matatagpuan sa isang solong repositoryo ng proyekto at ang mga paglabas ay nangyayari sa pamamagitan ng isang proseso sa CI/CD.

Pag-tag ayon sa sangay ng Git at tag ng Git

Sabihin nating ginagamit ang pinakakaraniwang diskarte sa pag-tag - tag-o-sangay. Para sa mga sangay ng Git, ang mga larawan ay na-tag gamit ang pangalan ng sangay, para sa isang sangay sa isang pagkakataon mayroon lamang isang nai-publish na larawan sa pangalan ng sangay na iyon. Para sa mga Git tag, ang mga larawan ay na-tag ayon sa pangalan ng tag.

Kapag ang isang bagong Git tag ay ginawaβ€”halimbawa, kapag ang isang bagong bersyon ay inilabasβ€”isang bagong Docker tag ay gagawin para sa lahat ng mga larawan ng proyekto sa Docker Registry:

  • myregistry.org/myproject/frontend:v1.1.10
  • myregistry.org/myproject/myservice1:v1.1.10
  • myregistry.org/myproject/myservice2:v1.1.10
  • myregistry.org/myproject/myservice3:v1.1.10
  • myregistry.org/myproject/myservice4:v1.1.10
  • myregistry.org/myproject/myservice5:v1.1.10
  • myregistry.org/myproject/database:v1.1.10

Ang mga bagong pangalan ng larawang ito ay ipinapasa sa mga template ng Helm sa configuration ng Kubernetes. Kapag sinimulan ang pag-deploy gamit ang command werf deploy ina-update ang field image sa Kubernetes resource manifests at restarting ang kaukulang resources dahil sa binagong pangalan ng imahe.

problema: sa kaso kung saan, sa katunayan, ang mga nilalaman ng imahe ay hindi nagbago mula noong nakaraang rollout (Git tag), ngunit ang Docker tag lamang nito, ito ay nangyayari. dagdag i-restart ang application na ito at, nang naaayon, posible ang ilang downtime. Bagama't walang tunay na dahilan para isagawa ang pag-restart na ito.

Bilang resulta, sa kasalukuyang scheme ng pag-tag, kinakailangan na bakod ang ilang hiwalay na mga repositoryo ng Git at lumitaw ang problema sa pag-aayos ng paglulunsad ng ilang mga repositoryo na ito. Sa pangkalahatan, ang gayong pamamaraan ay lumalabas na sobrang kargado at kumplikado. Mas mainam na pagsamahin ang maraming mga serbisyo sa isang solong imbakan at lumikha ng mga tag ng Docker upang walang mga hindi kinakailangang pag-restart.

Pag-tag sa pamamagitan ng Git commit

Ang werf ay mayroon ding diskarte sa pag-tag na nauugnay sa Git commits.

Ang Git-commit ay isang identifier para sa mga nilalaman ng isang Git repository at nakasalalay sa kasaysayan ng pag-edit ng mga file sa Git repository, kaya tila lohikal na gamitin ito para sa pag-tag ng mga imahe sa Docker Registry.

Gayunpaman, ang pag-tag ng Git commit ay may parehong mga disadvantages gaya ng pag-tag ng mga sangay ng Git o mga tag ng Git:

  • Maaaring gumawa ng isang walang laman na commit na hindi nagbabago ng anumang mga file, ngunit ang tag ng Docker ng larawan ay babaguhin.
  • Maaaring gumawa ng merge commit na hindi nagbabago sa mga file, ngunit babaguhin ang tag ng Docker ng larawan.
  • Maaaring gumawa ng commit na nagbabago sa mga file na iyon sa Git na hindi na-import sa imahe, at ang tag ng Docker ng imahe ay muling babaguhin.

Ang pag-tag sa pangalan ng sangay ng Git ay hindi nagpapakita ng bersyon ng larawan

May isa pang problema na nauugnay sa diskarte sa pag-tag para sa mga sangay ng Git.

Gumagana ang pagta-tag ayon sa pangalan ng sangay hangga't ang mga commit sa sangay na iyon ay nakolekta nang sunud-sunod sa magkakasunod na pagkakasunud-sunod.

Kung sa kasalukuyang scheme ang user ay magsisimulang muling buuin ang isang lumang commit na nauugnay sa isang partikular na sangay, pagkatapos ay isusulat muli ng werf ang imahe gamit ang kaukulang tag ng Docker na may bagong binuo na bersyon ng imahe para sa lumang commit. Ang mga deployment na gumagamit ng tag na ito mula ngayon ay may panganib na makakuha ng ibang bersyon ng larawan kapag nagre-restart ng mga pod, bilang resulta kung saan mawawalan ng koneksyon ang aming application sa CI system at magiging desynchronize.

Bilang karagdagan, sa sunud-sunod na pag-push sa isang branch na may maikling panahon sa pagitan ng mga ito, ang lumang commit ay maaaring i-compile sa mas bago: ang lumang bersyon ng larawan ay o-overwrite ang bago gamit ang Git branch tag. Ang ganitong mga problema ay maaaring malutas sa pamamagitan ng isang CI/CD system (halimbawa, sa GitLab CI ang pipeline ng huli ay inilunsad para sa isang serye ng mga commit). Gayunpaman, hindi lahat ng system ay sumusuporta dito at dapat mayroong isang mas maaasahang paraan upang maiwasan ang gayong pangunahing problema.

Ano ang content-based tagging?

Kaya, ano ang content-based na pag-tag - pag-tag ng mga larawan ayon sa nilalaman.

Upang lumikha ng mga tag ng Docker, hindi Git primitives (Git branch, Git tag...) ang ginagamit, ngunit isang checksum na nauugnay sa:

  • nilalaman ng larawan. Ang tag ng image ID ay nagpapakita ng nilalaman nito. Kapag gumagawa ng bagong bersyon, hindi magbabago ang identifier na ito kung hindi nagbago ang mga file sa larawan;
  • kasaysayan ng paglikha ng larawang ito sa Git. Ang mga larawang nauugnay sa iba't ibang sangay ng Git at iba't ibang kasaysayan ng build sa pamamagitan ng werf ay magkakaroon ng magkakaibang mga tag ng ID.

Ang nasabing tag ng identifier ay ang tinatawag na pirma ng entablado ng larawan.

Ang bawat larawan ay binubuo ng isang hanay ng mga yugto: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch atbp. Ang bawat yugto ay may isang identifier na nagpapakita ng mga nilalaman nito βˆ’ lagda sa entablado (stage signature).

Ang huling larawan, na binubuo ng mga yugtong ito, ay na-tag ng tinatawag na lagda ng hanay ng mga yugtong ito - yugto ng lagda, - na ginagawang pangkalahatan para sa lahat ng mga yugto ng larawan.

Para sa bawat larawan mula sa configuration werf.yaml sa pangkalahatang kaso, magkakaroon ng sarili nitong lagda at, nang naaayon, isang tag ng Docker.

Ang pirma sa entablado ay malulutas ang lahat ng mga problemang ito:

  • Lumalaban sa walang laman na Git commit.
  • Ang Resistant to Git ay commit na nagbabago ng mga file na hindi nauugnay sa larawan.
  • Hindi humahantong sa problema sa pag-overhauling ng kasalukuyang bersyon ng imahe kapag nag-restart ng mga build para sa lumang Git na commit ng isang sangay.

Ito na ngayon ang inirerekomendang diskarte sa pag-tag at ang default sa werf para sa lahat ng CI system.

Paano paganahin at gamitin sa werf

Ang utos ay mayroon na ngayong kaukulang opsyon werf publish: --tag-by-stages-signature=true|false

Sa isang CI system, ang diskarte sa pag-tag ay tinukoy ng command werf ci-env. Noong nakaraan, ang parameter ay tinukoy para dito werf ci-env --tagging-strategy=tag-or-branch. Ngayon, kung tinukoy mo werf ci-env --tagging-strategy=stages-signature o huwag tukuyin ang opsyong ito, gagamitin ng werf ang diskarte sa pag-tag bilang default stages-signature. Koponan werf ci-env ay awtomatikong itatakda ang mga kinakailangang flag para sa utos werf build-and-publish (O werf publish), kaya walang karagdagang mga opsyon ang kailangang tukuyin para sa mga utos na ito.

Halimbawa, ang utos:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature

...maaaring lumikha ng mga sumusunod na larawan:

  • registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
  • registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6

Dito 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d ay isang lagda ng mga yugto ng imahe backendAt f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - lagda ng mga yugto ng imahe frontend.

Kapag gumagamit ng mga espesyal na function werf_container_image ΠΈ werf_container_env Hindi na kailangang baguhin ang anuman sa mga template ng Helm: ang mga function na ito ay awtomatikong bubuo ng mga tamang pangalan ng imahe.

Halimbawang configuration sa isang CI system:

type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy

Higit pang impormasyon sa pagsasaayos ay makukuha sa dokumentasyon:

Sa kabuuan

  • Bagong opsyon werf publish --tag-by-stages-signature=true|false.
  • Bagong halaga ng opsyon werf ci-env --tagging-strategy=stages-signature|tag-or-branch (kung hindi tinukoy, ang default ay stages-signature).
  • Kung ginamit mo dati ang mga opsyon sa pag-tag para sa Git commits (WERF_TAG_GIT_COMMIT o opsyon werf publish --tag-git-commit COMMIT), pagkatapos ay tiyaking lumipat sa diskarte sa pag-tag yugto-pirma.
  • Mas mainam na agad na lumipat ng mga bagong proyekto sa bagong scheme ng pag-tag.
  • Kapag lumipat sa werf 1.1, ipinapayong ilipat ang mga lumang proyekto sa bagong scheme ng pag-tag, ngunit ang lumang tag-o-sangay ay suportado pa rin.

Nilulutas ng pag-tag na nakabatay sa nilalaman ang lahat ng problemang sakop sa artikulo:

  • Docker tag name resistance sa walang laman na Git commit.
  • Ang paglaban ng pangalan ng tag ng Docker sa Git ay gumagawa na nagbabago ng mga file na hindi nauugnay sa imahe.
  • Hindi humahantong sa problema sa pag-overhauling ng kasalukuyang bersyon ng imahe kapag nag-restart ng mga build para sa lumang Git commit para sa mga sangay ng Git.

Gamitin ito! At huwag kalimutang bisitahin kami sa GitHubupang lumikha ng isang isyu o makahanap ng isang umiiral na, magbigay ng isang plus, lumikha ng isang PR, o panoorin lamang ang pagbuo ng proyekto.

PS

Basahin din sa aming blog:

Pinagmulan: www.habr.com

Magdagdag ng komento