werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

27 Mei ing aula utama konferensi DevOpsConf 2019, dianakake minangka bagian saka festival kasebut RIT++ 2019, minangka bagéan saka bagean "Pangiriman Terus-terusan", laporan diwenehi "werf - alat kita kanggo CI/CD ing Kubernetes". Iku ngomong bab sing masalah lan tantangan sing saben wong ngadhepi nalika nyebarke kanggo Kubernetes, uga babagan nuansa sing bisa uga ora langsung katon. Nganalisis solusi sing bisa ditindakake, kita nuduhake kepiye cara iki ditindakake ing alat Open Source werf.

Wiwit presentation, sarana kita (sadurungé dikenal minangka dapp) wis tekan tonggak sejarah 1000 lintang ing GitHub - Muga-muga komunitas pangguna sing terus berkembang bakal nggawe urip luwih gampang kanggo akeh insinyur DevOps.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Dadi, ayo ngenalake video saka laporan (~ 47 menit, luwih informatif tinimbang artikel) lan ekstrak utama ing wangun teks. Tindak!

Ngirim kode menyang Kubernetes

Dhiskusi kasebut ora ana maneh babagan werf, nanging babagan CI / CD ing Kubernetes, tegese piranti lunak kita dikemas ing wadah Docker. (Aku ngomong babagan iki ing laporan 2016), lan K8s bakal digunakake kanggo mbukak ing produksi (luwih akeh babagan iki ing 2017 year).

Kepiye cara pangiriman ing Kubernetes?

  • Ana gudang Git kanthi kode lan instruksi kanggo mbangun. Aplikasi kasebut dibangun dadi gambar Docker lan diterbitake ing Registry Docker.
  • Repositori sing padha uga ngemot instruksi babagan cara nyebarake lan mbukak aplikasi kasebut. Ing tataran panyebaran, instruksi kasebut dikirim menyang Kubernetes, sing nampa gambar sing dikarepake saka registri lan diluncurake.
  • Kajaba iku, biasane ana tes. Sawetara iki bisa ditindakake nalika nerbitake gambar. Sampeyan uga bisa (minangka pandhuan padha) masang salinan aplikasi (ing K8s namespace kapisah utawa kluster kapisah) lan mbukak tes ana.
  • Pungkasan, sampeyan butuh sistem CI sing nampa acara saka Git (utawa klik tombol) lan nelpon kabeh tahapan sing ditunjuk: mbangun, nerbitake, nyebarake, nyoba.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Ana sawetara cathetan penting ing kene:

  1. Amarga kita duwe infrastruktur sing ora bisa diganti (Infrastruktur sing ora owah), gambar aplikasi sing digunakake ing kabeh tahapan (pementasan, produksi, lsp.), kudu ana siji. Aku ngomong babagan iki kanthi luwih rinci lan nganggo conto. kene.
  2. Amarga kita tindakake infrastruktur minangka pendekatan kode (IaC), kode aplikasi, instruksi kanggo assembling lan miwiti iku kudu persis ing siji gudang. Kanggo informasi luwih lengkap babagan iki, waca laporan padha.
  3. chain pangiriman (pangiriman) kita biasane ndeleng kaya iki: aplikasi dirakit, dites, dirilis (tahap rilis) lan iku - pangiriman wis kelakon. Nanging nyatane, pangguna entuk apa sing sampeyan luncurake, ora banjur nalika sampeyan dikirim menyang produksi, lan nalika dheweke bisa menyang kono lan produksi iki makarya. Dadi aku yakin rantai pangiriman bakal rampung mung ing tataran operasional (mlayu), utawa luwih tepat, sanajan nalika kode kasebut dibusak saka produksi (ngganti karo sing anyar).

Ayo bali menyang skema pangiriman ing ndhuwur ing Kubernetes: iki diciptakake ora mung dening kita, nanging kanthi harfiah saben wong sing ngatasi masalah iki. Nyatane, pola iki saiki diarani GitOps (sampeyan bisa maca liyane babagan istilah lan gagasan konco iku kene). Ayo ndeleng tahapan skema kasebut.

Tahap mbangun

Kayane sampeyan bisa ngomong babagan nggawe gambar Docker ing 2019, nalika kabeh wong ngerti carane nulis Dockerfiles lan mbukak. docker build?.. Ing ngisor iki nuansa sing arep digatekake:

  1. Bobot gambar prakara, supaya nggunakake multi-tatarankanggo ninggalake ing gambar mung aplikasi sing pancene perlu kanggo operasi.
  2. Jumlah lapisan kudu diminimalisir kanthi nggabungake rantai saka RUN-prentah miturut teges.
  3. Nanging, iki nambah masalah debugging, amarga nalika majelis tubrukan, sampeyan kudu golek printah tengen saka chain sing nyebabake masalah.
  4. kacepetan Majelis penting amarga kita pengin cepet muter metu owah-owahan lan ndeleng asil. Contone, sampeyan ora pengin mbangun maneh dependensi ing perpustakaan basa saben sampeyan nggawe aplikasi.
  5. Asring saka siji repositori Git sampeyan butuhake akeh gambar, sing bisa ditanggulangi dening sakumpulan Dockerfiles (utawa dijenengi tahapan ing siji file) lan skrip Bash kanthi rakitan urutane.

Iki mung pucuk gunung es sing diadhepi saben wong. Nanging ana masalah liyane, utamane:

  1. Asring ing tahap perakitan kita butuh apa-apa gunungan (contone, cache asil printah kaya apt ing direktori pihak katelu).
  2. Kita pengin Ansible tinimbang nulis ing cangkang.
  3. Kita pengin mbangun tanpa Docker (kok kita kudu mesin virtual tambahan kang kita kudu ngatur kabeh kanggo iki, nalika kita wis kluster Kubernetes kang kita bisa mbukak kontaner?).
  4. Déwan paralel, sing bisa dimangerteni kanthi macem-macem cara: beda perintah saka Dockerfile (yen multi-stage digunakake), sawetara commits saka gudang sing padha, sawetara Dockerfiles.
  5. Déwan sing disebarake: Kita arep kanggo ngumpulake iku ing pods sing "ephemeral" amarga cache ilang, kang tegese iku kudu disimpen nang endi wae dhewe.
  6. Pungkasan, aku menehi jeneng puncak kepinginan otomatis: Iku bakal becik kanggo pindhah menyang gudang, ngetik sawetara printah lan njaluk gambar siap-digawe, nglumpuk karo pangerten carane lan apa sing kudu dilakoni kanthi bener. Nanging, aku pribadi ora yakin manawa kabeh nuansa bisa diramalake kanthi cara iki.

Lan ing ngisor iki minangka proyek:

  • moby / buildkit - pembangun saka Docker Inc (wis digabungake karo versi Docker saiki), sing nyoba ngatasi kabeh masalah kasebut;
  • kaniko - pembangun saka Google sing ngidini sampeyan mbangun tanpa Docker;
  • Buildpacks.io - Usaha CNCF kanggo nggawe sihir otomatis lan, utamane, solusi sing menarik kanthi rebase kanggo lapisan;
  • lan akeh utilitas liyane, kayata mbangun, genuinetools/img...

... lan deleng jumlah lintang sing ana ing GitHub. Yaiku, ing tangan siji, docker build ana lan bisa nindakake soko, nanging ing kasunyatan masalah ora rampung rampung - bukti iki pangembangan paralel kolektor alternatif, saben kang solves sawetara bagéan saka masalah.

Majelis ing werf

Dadi kita kudu werf (sadurunge misuwur kaya dpp) - Utilitas open source saka perusahaan Flant, sing wis digawe pirang-pirang taun. Kabeh diwiwiti 5 taun kepungkur kanthi skrip Bash sing ngoptimalake rakitan Dockerfiles, lan sajrone 3 taun pungkasan, pangembangan lengkap wis ditindakake ing kerangka siji proyek kanthi repositori Git dhewe. (pisanan ing Ruby, banjur nulis maneh kanggo Go, lan ing wektu sing padha ganti jeneng). Apa masalah perakitan sing ditanggulangi ing werf?

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Masalah sing diwarnai biru wis ditindakake, mbangun paralel ditindakake ing host sing padha, lan masalah sing disorot warna kuning direncanakake bakal rampung ing pungkasan musim panas.

Tahap publikasi ing pendaptaran (nerbitake)

Kita nelpon docker push... - apa bisa angel ngunggah gambar menyang registri? Banjur pitakonan muncul: "Apa tag sing kudu dilebokake ing gambar kasebut?" Iku muncul kanggo alesan sing kita duwe Gitflow (utawa strategi Git liyane) lan Kubernetes, lan industri nyoba kanggo mesthekake yen apa sing kedadeyan ing Kubernetes ngetutake apa sing kedadeyan ing Git. Sawise kabeh, Git mung sumber bebener kita.

Apa sing angel babagan iki? Mesthekake reproducibility: saka komitmen ing Git, sing ora bisa diganti (ora owah), menyang gambar Docker, sing kudu tetep padha.

Iku uga penting kanggo kita nemtokake asal usul, amarga kita pengin ngerti saka sing nggawe aplikasi sing mlaku ing Kubernetes dibangun (banjur kita bisa nindakake bedane lan perkara sing padha).

Strategi Tagging

Sing pisanan prasaja git tag. Kita duwe pendaptaran kanthi gambar sing diwenehi tag minangka 1.0. Kubernetes duwe panggung lan produksi, ing ngendi gambar iki diunggah. Ing Git kita nggawe komitmen lan ing sawetara titik kita menehi tag 2.0. Kita ngumpulake miturut pandhuan saka repositori lan dilebokake ing registri kanthi tag 2.0. Kita muter metu menyang panggung lan, yen kabeh apik, banjur menyang produksi.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Masalah karo pendekatan iki kita sijine tag pisanan, lan mung banjur dites lan mbalek metu. Kenging punapa? Kaping pisanan, iku mung ora logis: kita nerbitake versi piranti lunak sing durung dites (ora bisa ditindakake, amarga kanggo mriksa, kita kudu menehi tag). Kapindho, path iki ora kompatibel karo Gitflow.

Pilihan kapindho yaiku git commit + tag. Cabang master duwe tag 1.0; kanggo ing pendaptaran - gambar disebarake kanggo produksi. Kajaba iku, kluster Kubernetes duwe pratinjau lan kontur pementasan. Sabanjure kita tindakake Gitflow: ing cabang utama kanggo pembangunan (develop) kita nggawe fitur-fitur anyar, nyebabake komitmen karo pengenal #c1. Kita ngumpulake lan nerbitake ing registri nggunakake pengenal iki (#c1). Kanthi pengenal sing padha, kita muter pratinjau. Kita nindakake perkara sing padha karo komitmen #c2 и #c3.

Nalika kita temen maujud sing ana cukup fitur, kita wiwiti stabil kabeh. Nggawe cabang ing Git release_1.1 (ing dhasar #c3 saka develop). Ora perlu ngumpulake rilis iki, amarga ... iki wis rampung ing langkah sadurunge. Mulane, kita mung bisa muter metu kanggo pementasan. Kita ndandani bug ing #c4 lan padha muter metu kanggo pementasan. Ing wektu sing padha, pembangunan lagi ditindakake develop, ngendi owah-owahan sing periodik dijupuk saka release_1.1. Ing sawetara titik, kita entuk komitmen sing disusun lan diunggah menyang pementasan, sing kita seneng (#c25).

Banjur kita gabung (karo maju cepet) cabang rilis (release_1.1) ing master. Kita menehi tag karo versi anyar ing komitmen iki (1.1). Nanging gambar iki wis diklumpukake ing registri, supaya ora ngumpulake maneh, kita mung nambah tag kapindho menyang gambar sing wis ana (saiki duwe tag ing registri). #c25 и 1.1). Sawisé iku, kita muter metu kanggo produksi.

Ana kekurangane mung siji gambar sing diunggah menyang pementasan (#c25), lan ing produksi iku beda-beda (1.1), nanging kita ngerti yen "fisik" iki minangka gambar sing padha saka registri.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Kerugian nyata yaiku ora ana dhukungan kanggo gabung, sampeyan kudu maju kanthi cepet.

Kita bisa luwih maju lan nindakake trik ... Ayo goleki conto Dockerfile sing prasaja:

FROM ruby:2.3 as assets
RUN mkdir -p /app
WORKDIR /app
COPY . ./
RUN gem install bundler && bundle install
RUN bundle exec rake assets:precompile
CMD bundle exec puma -C config/puma.rb

FROM nginx:alpine
COPY --from=assets /app/public /usr/share/nginx/www/public

Ayo nggawe file saka iku miturut prinsip ing ngisor iki:

  • SHA256 saka pengenal gambar sing digunakake (ruby:2.3 и nginx:alpine), yaiku checksum saka isine;
  • kabeh tim (RUN, CMD lan liya-liyane.);
  • SHA256 saka file sing ditambahake.

... lan njupuk checksum (maneh SHA256) saka file kasebut. Iki tapak asma kabeh sing nemtokake isi gambar Docker.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Ayo bali menyang diagram lan tinimbang commits kita bakal nggunakake teken kuwi, i.e. tag gambar karo teken.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Saiki, yen perlu, umpamane, kanggo nggabungake owah-owahan saka release menyang master, kita bisa nindakake commit gabungan nyata: bakal duwe pengenal beda, nanging teken padha. Kanthi pengenal sing padha, kita bakal muter gambar menyang produksi.

Kerugian yaiku saiki ora bisa nemtokake komitmen apa sing ditindakake kanggo produksi - checksum mung bisa digunakake ing siji arah. Masalah iki ditanggulangi dening lapisan tambahan karo metadata - Aku bakal pitutur marang kowe mengko.

Tagging ing werf

Ing werf, kita malah luwih maju lan lagi nyiapake mbangun sing disebarake kanthi cache sing ora disimpen ing siji mesin ... Dadi, kita mbangun rong jinis gambar Docker, sing diarani. panggung и gambar.

Repositori werf Git nyimpen instruksi khusus mbangun sing njlèntrèhaké macem-macem tahapan mbangun (sadurunge Instal, masang, sadurungeSetup, persiyapan). Kita ngumpulake gambar tataran pisanan kanthi teken sing ditetepake minangka checksum saka langkah pisanan. Banjur kita nambah kode sumber, kanggo gambar tataran anyar kita ngetung checksum sawijining ... Operasi iki diulang kanggo kabeh tahapan, minangka asil kang kita njaluk pesawat saka gambar panggung. Banjur kita nggawe gambar pungkasan, sing uga ngemot metadata babagan asale. Lan kita menehi tag gambar iki kanthi cara sing beda-beda (detail mengko).

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Upaminipun sawise iki commit anyar katon mung kode aplikasi wis diganti. Apa sing bakal kelakon? Kanggo owah-owahan kode, tambalan bakal digawe lan gambar panggung anyar bakal disiapake. Tandhane bakal ditemtokake minangka checksum gambar panggung lawas lan patch anyar. Gambar pungkasan anyar bakal dibentuk saka gambar iki. Prilaku sing padha bakal kedadeyan karo owah-owahan ing tahapan liyane.

Dadi, gambar panggung minangka cache sing bisa disimpen kanthi disebarake, lan gambar sing wis digawe saka iku diunggah menyang Docker Registry.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Reresik registri

Kita ora ngomong babagan mbusak lapisan sing tetep digantung sawise tag sing wis dibusak - iki minangka fitur standar saka Registry Docker dhewe. Kita ngomong babagan kahanan nalika akeh tag Docker nglumpukake lan kita ngerti manawa kita ora butuh sawetara, nanging njupuk papan (lan / utawa kita mbayar).

Apa strategi reresik?

  1. Sampeyan mung bisa nindakake apa-apa ora resik. Kadhangkala, luwih gampang mbayar sethithik kanggo papan ekstra tinimbang mbukak tag sing akeh banget. Nanging iki mung bisa nganti titik tartamtu.
  2. Reset lengkap. Yen sampeyan mbusak kabeh gambar lan mbangun mung sing saiki ing sistem CI, masalah bisa uga muncul. Yen wadhah kasebut diwiwiti maneh ing produksi, gambar anyar bakal dimuat - gambar sing durung dites dening sapa wae. Iki mateni ide infrastruktur sing ora bisa diganti.
  3. Biru-ijo. Siji registri wiwit kebanjiran - kita ngunggah gambar menyang liyane. Masalah sing padha karo cara sadurunge: ing titik apa sampeyan bisa mbusak registri sing wis mulai kebanjiran?
  4. Miturut wektu. Mbusak kabeh gambar lawas saka 1 sasi? Nanging mesthi ana layanan sing durung dianyari sajrone sasi ...
  5. Kanthi tangan nemtokake apa sing wis bisa dibusak.

Ana rong pilihan sing bener: aja ngresiki utawa kombinasi biru-ijo + kanthi manual. Ing kasus sing terakhir, kita ngomong babagan ing ngisor iki: yen sampeyan ngerti manawa wektu kanggo ngresiki pendaptaran, sampeyan nggawe sing anyar lan nambah kabeh gambar anyar sajrone, contone, sasi. Lan sawise sasi, ndeleng polong ing Kubernetes sing isih nggunakake pendaptaran lawas, lan transfer uga menyang pendaptaran anyar.

Apa kita teka werf? Kita ngumpulake:

  1. Kepala Git: kabeh tag, kabeh cabang - nganggep yen kita butuh kabeh sing diwenehi tag ing Git ing gambar (lan yen ora, kita kudu mbusak ing Git dhewe);
  2. kabeh polong sing saiki dipompa metu menyang Kubernetes;
  3. ReplicaSets lawas (apa mentas dirilis), lan kita uga rencana kanggo mindhai Rilis Helm lan pilih gambar paling anyar ana.

... lan gawe daftar putih saka set iki - dhaptar gambar sing ora bakal dibusak. Kita ngresiki kabeh liya, banjur kita nemokake gambar panggung yatim piatu lan uga mbusak.

Tahap nyebarake

Deklaratif sing bisa dipercaya

Titik pisanan sing dakkarepake ing panyebaran yaiku peluncuran konfigurasi sumber daya sing dianyari, diumumake kanthi deklaratif. Dokumen YAML asli sing njlèntrèhaké sumber daya Kubernetes mesthi beda banget karo asil sing bener mlaku ing kluster. Amarga Kubernetes nambahake konfigurasi:

  1. pengenal;
  2. informasi layanan;
  3. akeh nilai standar;
  4. bagean kanthi status saiki;
  5. owah-owahan sing digawe minangka bagéan saka webhook diakoni;
  6. asil karya saka macem-macem pengontrol (lan panjadwal).

Mulane, nalika konfigurasi sumber daya anyar katon (anyar), kita ora bisa mung njupuk lan nimpa konfigurasi saiki, "urip" karo (manggon). Kanggo nindakake iki, kita kudu mbandhingake anyar kanthi konfigurasi pungkasan sing ditrapake (pungkasan-applied) lan muter menyang manggon nampa patch.

Pendekatan iki diarani Gabungan 2 arah. Iki digunakake, contone, ing Helm.

Ana uga Gabungan 3 arah, sing beda karo:

  • mbandhingake pungkasan-applied и anyar, kita ndeleng apa sing wis dibusak;
  • mbandhingake anyar и manggon, kita ndeleng apa sing wis ditambahake utawa diganti;
  • patch summed ditrapake kanggo manggon.

Kita nyebarake luwih saka 1000 aplikasi nganggo Helm, mula kita urip kanthi gabungan 2 arah. Nanging, ana sawetara masalah sing wis ditanggulangi karo patch, sing mbantu Helm bisa mlaku kanthi normal.

Status rollout nyata

Sawise sistem CI kita nggawe konfigurasi anyar kanggo Kubernetes adhedhasar acara sabanjuré, iku ngirim kanggo nggunakake (nglamar) menyang kluster - nggunakake Helm utawa kubectl apply. Sabanjure, panggabungan N-way sing wis diterangake dumadi, ing ngendi API Kubernetes nanggapi kanthi nyetujoni sistem CI, lan kanggo pangguna.

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Nanging, ana masalah gedhe: sawise kabeh aplikasi sukses ora ateges rollout sukses. Yen Kubernetes ngerti owah-owahan apa sing kudu ditrapake lan ditrapake, kita isih ora ngerti apa asile. Contone, nganyari lan miwiti maneh pods ing frontend bisa sukses, nanging ora ing mburi, lan kita bakal njaluk versi beda saka gambar aplikasi mlaku.

Kanggo nindakake kabeh kanthi bener, skema iki mbutuhake tautan tambahan - tracker khusus sing bakal nampa informasi status saka API Kubernetes lan ngirimake kanggo analisis luwih lengkap babagan kahanan nyata. Kita nggawe perpustakaan Open Source ing Go - cubedog (ndeleng pengumumane kene), kang solves masalah iki lan dibangun menyang werf.

Prilaku tracker iki ing tingkat werf dikonfigurasi nggunakake anotasi sing diselehake ing Deployments utawa StatefulSets. Anotasi utama - fail-mode - ngerti makna ing ngisor iki:

  • IgnoreAndContinueDeployProcess - kita nglirwakake masalah muter komponen iki lan terus penyebaran;
  • FailWholeDeployProcessImmediately - kesalahan ing komponen iki mungkasi proses penyebaran;
  • HopeUntilEndOfDeployProcess - kita ngarep-arep sing komponen iki bakal bisa ing mburi penyebaran prajurit.

Contone, kombinasi sumber daya lan nilai anotasi iki fail-mode:

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Nalika kita nyebarake pisanan, database (MongoDB) bisa uga durung siyap - Penyebaran bakal gagal. Nanging sampeyan bisa ngenteni wayahe kanggo miwiti, lan penyebaran isih bakal njupuk Panggonan.

Ana rong anotasi liyane kanggo kubedog ing werf:

  • failures-allowed-per-replica - jumlah sing diijini tiba kanggo saben replika;
  • show-logs-until - ngatur wayahe nganti werf nuduhake (ing stdout) log saka kabeh mbalek metu pods. Default punika PodIsReady (kanggo nglirwakake pesen sing mbokmenawa ora dikarepake nalika lalu lintas wiwit teka ing pod), nanging nilai uga bener: ControllerIsReady и EndOfDeploy.

Apa maneh sing dikarepake saka panyebaran?

Saliyane rong poin sing wis diterangake, kita pengin:

  • kanggo ndeleng log - lan mung sing perlu, lan ora kabeh ing saurutan;
  • trek kemajuan, amarga yen proyek macet "meneng" kanggo sawetara menit, iku penting kanggo ngerti apa sing kedadeyan ing kono;
  • duwe rollback otomatis yen ana sing salah (lan mulane iku penting kanggo ngerti status nyata penyebaran). Rollout kudu atom: bisa nganti pungkasan, utawa kabeh bali menyang kahanan sadurunge.

Hasil

Kanggo kita minangka perusahaan, kanggo ngetrapake kabeh nuansa sing diterangake ing macem-macem tahap pangiriman (mbangun, nerbitake, nyebarake), sistem lan sarana CI cukup. werf.

Tinimbang kesimpulan:

werf - alat kita kanggo CI/CD ing Kubernetes (review lan laporan video)

Kanthi bantuan saka werf, kita wis nggawe kemajuan sing apik kanggo ngrampungake pirang-pirang masalah kanggo insinyur DevOps lan bakal seneng yen komunitas sing luwih akeh nyoba nyoba alat iki kanthi tumindak. Bakal luwih gampang kanggo entuk asil sing apik bebarengan.

Video lan minger

Video saka pagelaran (~47 menit):

Presentasi laporan:

PS

Laporan liyane babagan Kubernetes ing blog kita:

Source: www.habr.com

Add a comment