ProHoster > Блог > Administracija > Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu
Isprobavanje novih alata za izgradnju i automatizaciju implementacije u Kubernetesu
Zdravo! U posljednje vrijeme objavljeno je mnogo zgodnih alata za automatizaciju i za pravljenje Docker slika i za implementaciju u Kubernetes. S tim u vezi, odlučio sam da se poigram sa Gitlabom, kako da proučim njegove mogućnosti i, naravno, postavim cevovod.
Ovaj sajt je inspirisan kubernetes.io, koji se generiše iz izvorni kodovi automatski, a za svaki poslani zahtjev za povlačenjem, robot automatski generiše pretpreglednu verziju stranice s vašim promjenama i pruža vezu za pregled.
Pokušao sam da napravim sličan proces od nule, ali u potpunosti izgrađen na Gitlab CI i besplatnim alatima koje sam koristio za postavljanje aplikacija na Kubernetes. Danas ću vam konačno reći nešto više o njima.
Članak će pokriti alate kao što su: hugo, qbec, kaniko, git-crypt и GitLab CI sa stvaranjem dinamičnog okruženja.
Kao primjer našeg projekta, pokušat ćemo napraviti web stranicu za objavljivanje dokumentacije izgrađenu na Hugu. Hugo je generator statičkog sadržaja.
Za one koji nisu upoznati sa statičkim generatorima, reći ću vam nešto više o njima. Za razliku od običnih motora sajtova sa bazom podataka i nekom vrstom php-a, koji na zahtev korisnika generišu stranice u hodu, statički generatori su raspoređeni malo drugačije. Oni vam omogućavaju da uzmete izvor, obično skup datoteka u Markdown markup i predlošcima tema, a zatim ih prevedete u potpuno gotovu stranicu.
Odnosno, na izlazu ćete dobiti strukturu direktorija i skup generiranih html datoteka koje možete jednostavno prenijeti na bilo koji jeftini hosting i dobiti radnu stranicu.
Možete instalirati Hugo lokalno i isprobati ga:
Inicijalizacija nove stranice:
hugo new site docs.example.org
I u isto vrijeme git spremište:
cd docs.example.org
git init
Za sada je naš sajt netaknut i da bi se nešto pojavilo na njemu, prvo treba da povežemo temu, tema je samo skup šablona i postavljenih pravila po kojima se generiše naš sajt.
Kao temu ćemo koristiti naučiti, koji je, po mom mišljenju, najprikladniji za sajt sa dokumentacijom.
Želeo bih da obratim posebnu pažnju na činjenicu da ne moramo da spremamo fajlove tema u spremište našeg projekta, već ga jednostavno možemo povezati pomoću git podmodul:
Tako će u našem spremištu biti samo fajlovi direktno povezani sa našim projektom, a povezana tema će ostati kao veza do određenog spremišta i urezivanje u njemu, odnosno uvijek se može izvući iz originalnog izvora i ne plašiti se nekompatibilnih promjena.
Popravimo konfiguraciju config.toml:
baseURL = "http://docs.example.org/"
languageCode = "en-us"
title = "My Docs Site"
theme = "learn"
Već u ovoj fazi možete pokrenuti:
hugo server
I to na adresi http://localhost:1313/ provjerite našu novokreiranu stranicu, sve promjene napravljene u direktoriju automatski ažuriraju otvorenu stranicu u pretraživaču, vrlo zgodno!
Pokušajmo napraviti naslovnu stranicu u content/_index.md:
# My docs site
## Welcome to the docs!
You will be very smart :-)
Snimak ekrana novokreirane stranice
Da biste generirali web lokaciju, samo pokrenite:
hugo
Sadržaj direktorija publika/ i biće vaša stranica.
Da, usput, hajde da to odmah uvedemo .gitignore:
echo /public > .gitignore
Ne zaboravite izvršiti naše promjene:
git add .
git commit -m "New site created"
2. Priprema Dockerfile-a
Vrijeme je da definiramo strukturu našeg spremišta. Obično koristim nešto poput:
dockerfiles/ - sadrže direktorije s Dockerfiles i sve što je potrebno za izgradnju naših docker slika.
razviti/ - sadrži direktorije za postavljanje naših aplikacija u Kubernetes
Tako ćemo usput kreirati naš prvi Dockerfile dockerfiles/website/Dockerfile
FROM alpine:3.11 as builder
ARG HUGO_VERSION=0.62.0
RUN wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz -C /usr/local/bin
ADD . /src
RUN hugo -s /src
FROM alpine:3.11
RUN apk add --no-cache darkhttpd
COPY --from=builder /src/public /var/www
ENTRYPOINT [ "/usr/bin/darkhttpd" ]
CMD [ "/var/www" ]
Kao što vidite, Dockerfile sadrži dva OD, ova mogućnost se zove višestepena izgradnja i omogućava vam da isključite sve nepotrebno iz završne docker slike.
Dakle, konačna slika će sadržavati samo darkhttpd (laki HTTP server) i publika/ - sadržaj naše statički generirane stranice.
Ne zaboravite izvršiti naše promjene:
git add dockerfiles/website
git commit -m "Add Dockerfile for website"
3. Upoznavanje kaniko
Kao graditelj docker slika, odlučio sam koristiti kaniko, budući da njegov rad ne zahtijeva prisustvo docker demona, a sam sklop se može izvesti na bilo kojoj mašini i pohraniti keš direktno u registar, čime se oslobađa potrebe za punopravnim postojanim skladištem.
Da biste napravili sliku, samo pokrenite kontejner sa kaniko executor i proslijedite mu trenutni kontekst izgradnje, možete to učiniti lokalno, putem dockera:
Gde registry.gitlab.com/kvaps/docs.example.org/website - naziv vaše docker slike, nakon izgradnje će se automatski pokrenuti u docker registru.
Parametar --skladiste omogućava vam da keširate slojeve u docker registru, u datom primjeru oni će biti pohranjeni registry.gitlab.com/kvaps/docs.example.org/website/cache, ali možete odrediti drugu stazu s parametrom --cache-repo.
Snimak ekrana docker-registra
4. Uvod u qbec
Qbec je alat za primenu koji vam omogućava da deklarativno opišete manifeste svoje aplikacije i primenite ih na Kubernetes. Korištenje Jsonnet-a kao glavne sintakse čini vrlo lakim opisivanje razlika za više okruženja, a također gotovo potpuno eliminira ponavljanje koda.
Ovo može biti posebno istinito u slučajevima kada trebate implementirati aplikaciju u nekoliko klastera s različitim parametrima i želite ih deklarativno opisati u Gitu.
Qbec vam također omogućava da prikažete Helmove karte tako što ćete im proslijediti potrebne parametre i zatim raditi na njima na isti način kao i obični manifesti, uključujući mogućnost primjene različitih mutacija na njih, a to, zauzvrat, eliminira potrebu za korištenjem ChartMuseuma. To jest, možete pohraniti i prikazati grafikone direktno iz git-a, gdje im je mjesto.
Kao što sam već rekao, sve implementacije ćemo pohraniti u direktorij razviti/:
Ovdje nas prvenstveno zanima spec.environments, qbec je već kreirao podrazumevano okruženje za nas i uzeo adresu servera i imenski prostor iz našeg trenutnog kubeconfig-a.
Sada prilikom raspoređivanja na default okruženje, qbec će se uvijek implementirati samo na specificirani Kubernetes klaster i na specificirani imenski prostor, tj. više ne morate prelaziti između konteksta i prostora imena da biste se implementirali.
Ako je potrebno, uvijek možete ažurirati postavke u ovoj datoteci.
Sva vaša okruženja su opisana u qbec.yaml, i u datoteci params.libsonnet, koji kaže gdje trebate uzeti parametre za njih.
Zatim vidimo dva direktorija:
komponente / - svi manifesti za našu aplikaciju će biti pohranjeni ovdje, mogu se opisati iu jsonnet iu regularnim yaml datotekama
okruženja/ - ovdje ćemo opisati sve varijable (parametre) za naše okruženje.
Podrazumevano imamo dva fajla:
environments/base.libsonnet - sadržavat će zajedničke parametre za sva okruženja
okruženja/default.libsonnet - sadrži parametre redefinirane za okruženje default
hajde da otvorimo environments/base.libsonnet i tamo dodajte parametre za našu prvu komponentu:
U ovoj datoteci smo opisali tri Kubernetes entiteta odjednom, a to su: razvoj, usluga и Ulaz. Po želji, mogli bismo ih premjestiti u različite komponente, ali u ovoj fazi nam je jedna dovoljna.
sintaksa jsonnet vrlo sličan običnom json-u, u principu, običan json je već važeći jsonnet, tako da će vam u početku možda biti lakše koristiti online usluge kao što su yaml2json da konvertujete vaš uobičajeni yaml u json, ili ako vaše komponente ne sadrže nikakve varijable, onda se one mogu opisati u obliku običnog yaml-a.
Prilikom rada sa jsonnet Preporučujem vam da instalirate dodatak za svoj uređivač
Na primjer, postoji dodatak za vim vim-jsonnet, koji uključuje isticanje sintakse i automatski se izvršava jsonnet fmt pri svakom spremanju (zahteva da se instalira jsonnet).
Sve je spremno, sada možemo početi sa implementacijom:
Da vidimo šta imamo, pokrenimo:
qbec show default
Na izlazu ćete vidjeti renderirane yaml manifeste koji će biti primijenjeni na zadani klaster.
Odlično, sada se prijavite:
qbec apply default
Na izlazu ćete uvijek vidjeti šta će se raditi u vašem klasteru, qbec će od vas tražiti da prihvatite promjene upisivanjem y možete potvrditi svoje namjere.
Gotovo, naša aplikacija je postavljena!
Ako su promjene napravljene, uvijek možete pokrenuti:
qbec diff default
da vidite kako će ove promjene utjecati na trenutnu implementaciju
Ne zaboravite izvršiti naše promjene:
cd ../..
git add deploy/website
git commit -m "Add deploy for website"
5. Isprobajte Gitlab-runner sa Kubernetes-executorom
Do nedavno sam koristio samo obične gitlab-runner na unaprijed pripremljenoj mašini (LXC kontejner) sa shell- ili docker-executorom. U početku smo imali nekoliko ovih trkača globalno definiranih u našem gitlabu. Napravili su docker slike za sve projekte.
Ali, kako je praksa pokazala, ova opcija nije najidealnija, kako u pogledu praktičnosti, tako iu smislu sigurnosti. Mnogo je bolje i ideološki ispravno imati odvojene trkače raspoređene za svaki projekat, pa čak i za svako okruženje.
Srećom, to uopće nije problem, jer ćemo se sada rasporediti gitlab-runner direktno kao dio našeg projekta u Kubernetesu.
Gitlab pruža gotov helm chart za implementaciju gitlab-runnera u Kubernetes. Dakle, sve što trebate znati je registracioni token za naš projekat u Postavke -> CI / CD -> Runners i prenesi ga na kormilo:
yga8y-jdCusVDn_t4Wxc - registracioni token za vaš projekat.
rbac.create=true - daje trkaču potreban broj privilegija da može kreirati podove za obavljanje naših zadataka koristeći kubernetes-executor.
Ako je sve urađeno kako treba, trebali biste vidjeti registrovanog trkača u odjeljku Runners, u postavkama vašeg projekta.
Snimak ekrana dodanog trkača
Je li to tako jednostavno? - da, tako je jednostavno! Nema više muke s ručnom registracijom trkača, od sada će se trkači automatski kreirati i uništavati.
6. Postavite Helm karte s QBEC-om
Pošto smo odlučili da razmotrimo gitlab-runner dio našeg projekta, vrijeme je da ga opišemo u našem Git repozitoriju.
Mogli bismo ga opisati kao zasebnu komponentu sajt, ali u budućnosti planiramo implementirati različite kopije sajt vrlo često, za razliku od gitlab-runner, koji će biti raspoređen samo jednom po Kubernetes klasteru. Pa hajde da inicijalizujemo zasebnu aplikaciju za to:
cd deploy
qbec init gitlab-runner
cd gitlab-runner
Ovaj put nećemo ručno opisivati Kubernetes entitete, već ćemo uzeti gotov Helm grafikon. Jedna od prednosti qbec-a je mogućnost prikazivanja Helmovih grafikona direktno iz Git repozitorija.
Ali čuvanje tajni u Gitu nije sigurno, zar ne? Dakle, moramo ih pravilno šifrirati.
Obično zbog jedne varijable to nema uvijek smisla. Možete prenijeti tajne na qbec i kroz varijable okruženja vašeg CI sistema.
Ali vrijedi napomenuti da postoje i složeniji projekti koji mogu sadržavati mnogo više tajni, bit će izuzetno teško sve ih proći kroz varijable okruženja.
Osim toga, u ovom slučaju, ne bih vam mogao reći o tako divnom alatu kao što je git-crypt.
git-crypt Pogodan je i po tome što vam omogućava da sačuvate čitavu istoriju tajni, kao i da upoređujete, spajate i rešavate konflikte na isti način kao što smo to radili u slučaju Gita.
Prva stvar nakon instalacije git-crypt moramo generirati ključeve za naše spremište:
git crypt init
Ako imate PGP ključ, odmah se možete dodati kao saradnika za ovaj projekat:
Na ovaj način uvijek možete dešifrirati ovo spremište koristeći svoj privatni ključ.
Ako nemate PGP ključ i od njega se ne očekuje, onda možete ići drugim putem i izvesti ključ projekta:
git crypt export-key /path/to/keyfile
Dakle, svako ko posjeduje izvezen keyfile moći će dešifrirati vaše spremište.
Vrijeme je da otkrijemo našu prvu tajnu.
Da vas podsjetim da smo još uvijek u imeniku deploy/gitlab-runner/gdje imamo imenik tajne/, šifrirajmo sve datoteke u njemu, za to ćemo kreirati datoteku secrets/.gitattributes sa ovakvim sadržajem:
Kao što se vidi iz sadržaja, svi fajlovi po maski * proći će git-crypt, sa izuzetkom .gitattributes
Ovo možemo provjeriti pokretanjem:
git crypt status -e
Na izlazu dobijamo listu svih fajlova u spremištu za koje je omogućeno šifrovanje
To je to, sada možemo bezbedno izvršiti naše promene:
cd ../..
git add .
git commit -m "Add deploy for gitlab-runner"
Da biste blokirali spremište, dovoljno je izvršiti:
git crypt lock
i odmah će se svi šifrirani fajlovi pretvoriti u nešto binarno, biće ih nemoguće pročitati.
Da dešifrujete spremište, pokrenite:
git crypt unlock
8. Kreirajte sliku kutije sa alatima
Slika kutije alata je slika sa svim alatima koje ćemo koristiti za implementaciju našeg projekta. Koristit će ga gitlab runner za obavljanje tipičnih zadataka postavljanja.
Ovdje je sve jednostavno, stvaramo novo dockerfiles/toolbox/Dockerfile sa ovakvim sadržajem:
FROM alpine:3.11
RUN apk add --no-cache git git-crypt
RUN QBEC_VER=0.10.3
&& wget -O- https://github.com/splunk/qbec/releases/download/v${QBEC_VER}/qbec-linux-amd64.tar.gz
| tar -C /tmp -xzf -
&& mv /tmp/qbec /tmp/jsonnet-qbec /usr/local/bin/
RUN KUBECTL_VER=1.17.0
&& wget -O /usr/local/bin/kubectl
https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/linux/amd64/kubectl
&& chmod +x /usr/local/bin/kubectl
RUN HELM_VER=3.0.2
&& wget -O- https://get.helm.sh/helm-v${HELM_VER}-linux-amd64.tar.gz
| tar -C /tmp -zxf -
&& mv /tmp/linux-amd64/helm /usr/local/bin/helm
Kao što možete vidjeti, na ovoj slici instaliramo sve uslužne programe koje smo koristili za implementaciju naše aplikacije. Ne trebamo ovde osim ako kubectl, ali biste se možda željeli poigrati s tim prilikom postavljanja cjevovoda.
Takođe, da bismo mogli da komuniciramo sa Kubernetesom i da se rasporedimo na njega, moramo da postavimo ulogu za podove koje generiše gitlab-runner.
Da biste to učinili, idite u direktorij sa gitlab-runner'om:
cd deploy/gitlab-runner
i dodajte novu komponentu komponenti/rbac.jsonnet:
Mislim da to možete sa sigurnošću nazvati verzijom v0.0.1 i dodajte oznaku:
git tag v0.0.1
Okačiti ćemo oznake kad god trebamo objaviti novu verziju. Oznake u Docker slikama bit će mapirane na Git oznake. Svaki push s novom oznakom će inicijalizirati izgradnju slike s tom oznakom.
Hoće izvršiti git push --tags, i pogledajte naš prvi cjevovod:
Snimak ekrana prvog cjevovoda
Vrijedi naglasiti da su gradnje zasnovane na oznakama dobre za pravljenje docker slika, ali ne i za implementaciju aplikacije u Kubernetes. Budući da se nove oznake također mogu dodijeliti starim urezivanju, u ovom slučaju, inicijalizacija cjevovoda za njih će dovesti do postavljanja stare verzije.
Da bi se riješio ovaj problem, izrada docker slika obično je vezana za oznake, a implementacija aplikacije na granu majstor, u kojem su verzije prikupljenih slika tvrdo kodirane. U ovom slučaju možete inicijalizirati vraćanje jednostavnim vraćanjem majstor-grane.
10. Pokrenite automatizaciju
Da bi Gitlab-runner dešifrirao naše tajne, moramo eksportirati ključ spremišta i dodati ga našim varijablama CI okruženja:
--root some/app - omogućava vam da definirate direktorij određene aplikacije
--force:k8s-context __incluster__ - ovo je magična varijabla koja kaže da će se implementacija dogoditi u istom klasteru u kojem je pokrenut gtilab-runner. Ovo je neophodno, inače će qbec pokušati pronaći odgovarajući Kubernetes server u vašem kubeconfigu
-cekaj - prisiljava qbec da čeka dok resursi koje kreira ne pređu u stanje Ready i tek onda završi uspješnim izlaznim kodom.
-da - samo onemogućava interaktivnu ljusku Jesi li siguran? tokom raspoređivanja.
I poslije git push vidjet ćemo kako su naše aplikacije raspoređene:
Snimak ekrana drugog cjevovoda
11. Artefakti i sklapanje pri guranje do mastera
Obično su gornji koraci dovoljni za izgradnju i isporuku gotovo svih mikroservisa, ali ne želimo da dodajemo oznaku svaki put kada trebamo ažurirati web lokaciju. Stoga ćemo ići na dinamičniji način i podesiti implementaciju sažetka u glavnoj grani.
Ideja je jednostavna: sada naša slika sajt će se obnavljati svaki put kada to budete pritisnuli majstor, a zatim se automatski implementira u Kubernetes.
Napominjemo da smo dodali granu majstor к ref za posao build_website i sada koristimo $CI_COMMIT_REF_NAME umjesto $CI_COMMIT_TAG, to jest, riješimo se tagova u Gitu i sada ćemo gurnuti sliku s imenom grane urezivanja koja je inicijalizirala vaš cjevovod. Vrijedi napomenuti da će ovo raditi i sa oznakama, što će nam omogućiti da sačuvamo snimke stranice sa određenom verzijom u docker-registru.
Kada naziv docker oznake za novu verziju stranice može biti nepromijenjen, još uvijek moramo opisati promjene za Kubernetes, inače jednostavno neće ponovo postaviti aplikaciju sa nove slike, jer neće primijetiti nikakve promjene u manifest raspoređivanja.
Opcija --vm:ext-str digest="$DIGEST" za qbec - omogućava vam da proslijedite eksternu varijablu u jsonnet. Želimo da se naša aplikacija ponovo raspoređuje u klaster sa svakim izdanjem. Više ne možemo koristiti ime oznake, koje sada može biti nepromijenjeno, jer se moramo vezati za određenu verziju slike i pokrenuti implementaciju kada se promijeni.
Ovdje će nam pomoći Kanikova sposobnost da sačuva sažetak slike u datoteku (opcija --digest-file)
Zatim ćemo prenijeti ovu datoteku i pročitati je u vrijeme postavljanja.
Ažurirajmo parametre za naše deploy/website/environments/base.libsonnet koji će sada izgledati ovako:
Gotovo, sada uključite bilo kakvu obvezu majstor inicijalizira izgradnju docker slike za sajt, a zatim ga rasporedite u Kubernetes.
Ne zaboravite izvršiti naše promjene:
git add .
git commit -m "Configure dynamic build"
Provjerite to poslije git push trebali bismo vidjeti nešto ovako:
Snimak ekrana cjevovoda za master
U principu, ne moramo ponovo postavljati gitlab-runner sa svakim pritiskom, osim ako se, naravno, ništa nije promijenilo u njegovoj konfiguraciji, popravimo to u .gitlab-ci.yml:
Vrijeme je da diverzificiramo naš cevovod dinamičnim okruženjima.
Prvo, ažurirajmo posao build_website u našem .gitlab-ci.yml, uklanjajući blok sa njega samo, što će primorati Gitlab da ga pokrene na bilo kojem urezivanju na bilo koju granu:
Oni će se pokrenuti pritiskom na bilo koju granu osim master i pokrenut će verziju stranice za pregled.
Vidimo novu opciju za qbec: --app-tag - omogućava vam da označite implementirane verzije aplikacije i radite samo unutar ove oznake; kada kreirate i uništavate resurse u Kubernetesu, qbec će raditi samo na njima.
Dakle, ne možemo kreirati posebno okruženje za svaku recenziju, već jednostavno ponovo koristiti isto.
Ovdje također koristimo qbec primijeniti pregledumjesto qbec primijeniti default - ovo je upravo trenutak kada ćemo pokušati opisati razlike za naše sredine (recenzija i zadano):
Hajde da dodamo pregled okruženje u deploy/website/qbec.yaml
Zatim ga deklariramo deploy/website/params.libsonnet:
local env = std.extVar('qbec.io/env');
local paramsMap = {
_: import './environments/base.libsonnet',
default: import './environments/default.libsonnet',
review: import './environments/review.libsonnet',
};
if std.objectHas(paramsMap, env) then paramsMap[env] else error 'environment ' + env + ' not defined in ' + std.thisFile
I upišite prilagođene parametre za to deploy/website/environments/review.libsonnet:
// this file has the param overrides for the default environment
local base = import './base.libsonnet';
local slug = std.extVar('qbec.io/tag');
local subdomain = std.extVar('subdomain');
base {
components+: {
website+: {
name: 'example-docs-' + slug,
domain: subdomain + '.docs.example.org',
},
},
}
Pogledajmo i posao izbliza stop_review, aktivirat će se kada se grana ukloni i tako da gitlab ne pokuša provjeriti na njoj se koristi GIT_STRATEGY: nema, kasnije ćemo klonirati majstor-granati i brisati recenziju kroz nju.
Malo zbunjujuće, ali još nisam pronašao ljepši način.
Alternativna opcija bi bila da se svaka recenzija rasporedi u imenski prostor hotela, koji se uvijek može uništiti u cijelosti.
Sve radi? - super, izbrišite našu test granu: git checkout master, git push origin :test, provjeravamo da li su poslovi za brisanje okruženja radili bez grešaka.
Ovdje odmah želim pojasniti da bilo koji programer u projektu može kreirati grane, može se i mijenjati .gitlab-ci.yml fajl i pristupne tajne varijable.
Stoga se snažno preporučuje da se njihova upotreba dozvoli samo za zaštićene grane, na primjer u majstorili kreirajte poseban skup varijabli za svako okruženje.
13 Pregledajte aplikacije
Pregledajte aplikacije ovo je gitlab funkcija koja vam omogućava da dodate dugme za svaki fajl u spremištu da biste ga brzo pregledali u primenjenom okruženju.
Da bi se ova dugmad pojavila, potrebno je da kreirate datoteku .gitlab/route-map.yml i opisati u njemu sve transformacije staza, u našem slučaju to će biti vrlo jednostavno: