Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Pristup IaC (Infrastruktura kao kod) se sastoji ne samo od koda koji je pohranjen u spremištu, već i od ljudi i procesa koji okružuju ovaj kod. Da li je moguće ponovo koristiti pristupe od razvoja softvera do upravljanja infrastrukturom i opisa? Bilo bi dobro da ovu ideju imate na umu dok čitate članak.

engleska verzija

Ovo je moj transkript predstave na DevopsConf 2019-05-28.

Slajdovi i video zapisi

Infrastruktura kao bash istorija

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Pretpostavimo da dođete na novi projekat, a oni vam kažu: „imamo Infrastruktura kao kod". U stvarnosti se ispostavilo Infrastruktura kao bash istorija ili na primjer Dokumentacija kao bash istorija. Ovo je vrlo realna situacija, na primjer, sličan slučaj opisao je Denis Lysenko u govoru Kako zamijeniti cijelu infrastrukturu i početi mirno spavati, ispričao je kako su dobili koherentnu infrastrukturu za projekat iz bash istorije.

Uz određenu želju, možemo to reći Infrastruktura kao bash istorija ovo je kao kod:

  1. reproduktivnost: Možete uzeti bash historiju, pokrenuti komande odatle, i možda ćete, usput, dobiti radnu konfiguraciju kao izlaz.
  2. verzijama: znate ko je ušao i šta je radio, opet, nije činjenica da će vas ovo dovesti do radne konfiguracije na izlazu.
  3. istorija: priča o tome ko je šta uradio. samo što ga nećete moći koristiti ako izgubite server.

Šta da radim?

Infrastruktura kao kod

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Čak i tako čudan slučaj kao Infrastruktura kao bash istorija možete ga povući za uši Infrastruktura kao kod, ali kada želimo da uradimo nešto komplikovanije od dobrog starog LAMP servera, doći ćemo do zaključka da ovaj kod treba nekako modifikovati, promeniti, poboljšati. Zatim bismo željeli razmotriti paralele između Infrastruktura kao kod i razvoj softvera.

DRY

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Na projektu razvoja sistema skladištenja, postojao je podzadatak periodično konfigurišite SDS: objavljujemo novo izdanje - potrebno ga je izbaciti radi daljeg testiranja. Zadatak je krajnje jednostavan:

  • prijavite se ovdje preko ssh-a i izvršite naredbu.
  • kopirajte datoteku tamo.
  • ispravite konfiguraciju ovdje.
  • tamo započnite uslugu
  • ...
  • PROFIT!

Za opisanu logiku, bash je više nego dovoljan, posebno u ranim fazama projekta, kada tek počinje. Ovo nije loše što koristite bash, ali s vremenom se javljaju zahtjevi da se implementira nešto slično, ali malo drugačije. Prva stvar koja pada na pamet je copy-paste. A sada već imamo dvije vrlo slične skripte koje rade skoro istu stvar. Vremenom je broj skripti rastao, a mi smo se suočili sa činjenicom da postoji određena poslovna logika za postavljanje instalacije koju treba sinhronizovati između različitih skripti, to je prilično komplikovano.

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Ispostavilo se da postoji praksa kao što je DRY (Ne ponavljaj se). Ideja je ponovno korištenje postojećeg koda. Zvuči jednostavno, ali nismo odmah došli do ovoga. U našem slučaju, to je bila banalna ideja: odvojiti konfiguracije od skripti. One. poslovna logika kako se instalacija postavlja zasebno, konfiguracije zasebno.

SOLID za CFM

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Vremenom je projekat rastao i prirodni nastavak bila je pojava Ansiblea. Glavni razlog njegovog pojavljivanja je što postoji stručnost u timu i što bash nije dizajniran za složenu logiku. Ansible je također počeo sadržavati složenu logiku. Kako bi se spriječilo da se složena logika pretvori u haos, postoje principi za organiziranje koda u razvoju softvera SOLID Takođe, na primer, Grigorij Petrov je u izveštaju „Zašto je IT stručnjaku potreban lični brend“ postavio pitanje da je čovek dizajniran tako da mu je lakše da operiše sa nekim društvenim subjektima, u razvoju softvera ovim su objekti. Ako spojimo ove dvije ideje i nastavimo da ih razvijamo, primijetit ćemo da ih također možemo koristiti SOLID kako bi se olakšalo održavanje i modifikacija ove logike u budućnosti.

Princip jedinstvene odgovornosti

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Svaka klasa obavlja samo jedan zadatak.

Nema potrebe za miješanjem koda i pravljenjem monolitnih božanskih špageti čudovišta. Infrastruktura bi se trebala sastojati od jednostavnih cigli. Ispostavilo se da ako podijelite Ansible playbook na male dijelove, pročitate Ansible uloge, onda ih je lakše održavati.

Otvoreno zatvoreno načelo

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Otvoreno/zatvoreno princip.

  • Otvoreno za proširenje: znači da se ponašanje entiteta može proširiti kreiranjem novih tipova entiteta.
  • Zatvoreno za promjenu: Kao rezultat proširenja ponašanja entiteta, ne bi trebale biti napravljene promjene u kodu koji koristi te entitete.

U početku smo postavili testnu infrastrukturu na virtuelne mašine, ali zbog činjenice da je poslovna logika implementacije bila odvojena od implementacije, dodali smo uvođenje na baremetall bez ikakvih problema.

Princip zamjene Liskov

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Princip zamjene Barbare Liskov. objekti u programu moraju biti zamjenjivi instancama njihovih podtipova bez promjene ispravnog izvršavanja programa

Ako pogledate šire, to nije odlika nijednog projekta koji se tu može primijeniti SOLID, generalno se radi o CFM-u, na primjer, na drugom projektu je potrebno postaviti upakiranu Java aplikaciju na razne Jave, aplikacijske servere, baze podataka, OS itd. Koristeći ovaj primjer, razmotrit ću daljnja načela SOLID

U našem slučaju postoji dogovor unutar infrastrukturnog tima da ako smo instalirali ulogu imbjava ili oraclejava, onda imamo java binarnu izvršnu datoteku. Ovo je neophodno jer Upstream uloge ovise o ovom ponašanju; U isto vrijeme, ovo nam omogućava da zamijenimo jednu implementaciju/verziju java s drugom bez promjene logike implementacije aplikacije.

Problem ovdje leži u činjenici da je to nemoguće implementirati u Ansibleu, zbog čega se pojavljuju neki dogovori unutar tima.

Princip segregacije interfejsa

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Princip razdvajanja interfejsa: „Mnoga sučelja specifična za klijenta su bolja od jednog interfejsa opšte namene.

U početku smo pokušali da svu varijabilnost implementacije aplikacije stavimo u jedan Ansible playbook, ali to je bilo teško podržati, a pristup kada imamo specificirano vanjsko sučelje (klijent očekuje port 443), onda se infrastruktura može sastaviti od pojedinačnih cigle za konkretnu implementaciju.

Princip inverzije zavisnosti

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Princip inverzije zavisnosti. Moduli na višim nivoima ne bi trebali ovisiti o modulima na nižim nivoima. Oba tipa modula moraju zavisiti od apstrakcija. Apstrakcije ne bi trebale zavisiti od detalja. Detalji moraju zavisiti od apstrakcija.

Ovdje će se primjer temeljiti na antiuzorku.

  1. Jedan od kupaca je imao privatni oblak.
  2. Naručili smo virtuelne mašine unutar oblaka.
  3. Ali zbog prirode oblaka, implementacija aplikacije bila je vezana za koji hipervizor je bio na VM.

One. Logika implementacije aplikacije na visokom nivou tekla je sa zavisnostima do nižih nivoa hipervizora, a to je značilo probleme prilikom ponovnog korišćenja ove logike. Nemojte to raditi na ovaj način.

interakcija

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Infrastruktura kao kod se ne odnosi samo na kod, već i na odnos između koda i ljudi, na interakcije između infrastrukturnih programera.

Faktor autobusa

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Pretpostavimo da imate Vasyu na svom projektu. Vasja zna sve o vašoj infrastrukturi, šta će se dogoditi ako Vasja iznenada nestane? Ovo je sasvim realna situacija, jer bi ga mogao udariti autobus. Ponekad se desi. Ako se to dogodi, a znanje o kodu, njegovoj strukturi, načinu rada, izgledu i lozinkama ne bude distribuirano među timom, tada možete naići na niz neugodnih situacija. Da biste minimizirali ove rizike i distribuirali znanje unutar tima, možete koristiti različite pristupe

Pair Devopsing

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

To nije kao kao šala, da su admini pili pivo, mijenjali lozinke i analogno programiranju u paru. One. dva inženjera sjednu za jedan računar, jednu tastaturu i zajedno počnu postavljati vašu infrastrukturu: postavljanje servera, pisanje Ansible uloge, itd. Zvuči lijepo, ali nama nije išlo. Ali posebni slučajevi ove prakse su uspjeli. Dolazi novi zaposlenik, njegov mentor zajedno sa njim preuzima pravi zadatak, radi i prenosi znanje.

Još jedan poseban slučaj je incidentni poziv. Tokom problema, okuplja se grupa dežurnih i uključenih, imenuje se jedan vođa, koji dijeli svoj ekran i izgovara tok misli. Ostali učesnici prate misli vođe, špijuniraju trikove sa konzole, proveravaju da nisu propustili red u dnevniku i uče nove stvari o sistemu. Ovaj pristup je djelovao češće nego ne.

Pregled koda

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Subjektivno, bilo je efikasnije širiti znanje o infrastrukturi i kako ona funkcionira korištenjem pregleda koda:

  • Infrastruktura je opisana kodom u spremištu.
  • Promjene se dešavaju u posebnoj grani.
  • Tokom zahtjeva za spajanjem, možete vidjeti deltu promjena u infrastrukturi.

Vrhunac je bio da su recenzenti birani jedan po jedan, prema rasporedu, tj. s određenim stepenom vjerovatnoće ćete se popeti u novi dio infrastrukture.

stil koda

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Vremenom su se počele pojavljivati ​​svađe tokom recenzija, jer... recenzenti su imali svoj stil i rotacija recenzenata ih je slagala sa različitim stilovima: 2 razmaka ili 4, camelCase ili snake_case. To nije bilo moguće odmah implementirati.

  • Prva ideja je bila preporučiti korištenje lintera, na kraju krajeva, svi su inženjeri, svi su pametni. Ali različiti uređivači, OS, nisu zgodni
  • Ovo je evoluiralo u bota koji je pisao u slack za svako problematično urezivanje i priložio izlaz lintera. Ali u većini slučajeva bilo je važnijih stvari koje treba uraditi i kod je ostao neispravljen.

Green Build Master

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Vrijeme prolazi, a mi smo došli do zaključka da se commiti koji ne prođu određene testove ne mogu dopustiti u master. Voila! Izmislili smo Green Build Master, koji se već duže vrijeme prakticira u razvoju softvera:

  • U toku je razvoj u posebnoj grani.
  • Testovi se izvode na ovoj temi.
  • Ako testovi ne uspiju, kod neće ući u master.

Donošenje ove odluke bilo je veoma bolno, jer... izazvalo mnogo kontroverzi, ali vredelo je, jer... Recenzije su počele primati zahtjeve za spajanje bez razlike u stilu, a vremenom je broj problematičnih područja počeo da se smanjuje.

IaC Testing

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Osim provjere stila, možete koristiti i druge stvari, na primjer, da provjerite da li se vaša infrastruktura zaista može implementirati. Ili provjerite da promjene u infrastrukturi neće dovesti do gubitka novca. Zašto bi ovo moglo biti potrebno? Pitanje je kompleksno i filozofsko, bolje je odgovoriti pričom da je na Powershell-u nekako postojao auto-skaler koji nije provjerio granične uslove => kreirano je više VM-ova nego što je potrebno => klijent je potrošio više novca nego što je planirano. Ovo nije baš ugodno, ali bilo bi sasvim moguće uhvatiti ovu grešku u ranijim fazama.

Moglo bi se zapitati, zašto složenu infrastrukturu činiti još složenijom? Testovi za infrastrukturu, baš kao i za kod, ne odnose se na pojednostavljenje, već na znanje kako bi vaša infrastruktura trebala funkcionirati.

IaC testna piramida

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

IaC testiranje: statička analiza

Ako smjestite cijelu infrastrukturu odjednom i provjerite da li radi, možda ćete otkriti da je potrebno puno vremena i puno vremena. Dakle, osnova mora biti nešto što brzo radi, toga ima dosta i pokriva dosta primitivnih mjesta.

Bash je lukav

Pogledajmo trivijalan primjer. odaberite sve datoteke u trenutnom direktoriju i kopirajte ih na drugu lokaciju. Prva stvar koja mi pada na pamet:

for i in * ; do 
    cp $i /some/path/$i.bak
done

Šta ako postoji razmak u imenu datoteke? Pa dobro, mi smo pametni, znamo da koristimo navodnike:

for i in * ; do cp "$i" "/some/path/$i.bak" ; done

Dobro urađeno? Ne! Šta ako nema ništa u imeniku, tj. globiranje neće raditi.

find . -type f -exec mv -v {} dst/{}.bak ;

Dobro urađeno sada? Ne... Zaboravio sam šta može biti u nazivu datoteke n.

touch x
mv x  "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dir

Alati za statičku analizu

Problem iz prethodnog koraka mogao bi se uhvatiti kada smo zaboravili citate, za to u prirodi postoje mnogi lijekovi Shellcheck, generalno ih ima puno, i najvjerovatnije možete pronaći linter za svoj stek pod vašim IDE.

Jezik
alatka

bash
Shellcheck

Rubin
RuboCop

python
pylint

ansible
Ansible Lint

IaC testiranje: Jedinični testovi

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Kao što smo vidjeli iz prethodnog primjera, linteri nisu svemoćni i ne mogu ukazati na sva problematična područja. Nadalje, po analogiji s testiranjem u razvoju softvera, možemo se prisjetiti jediničnih testova. Ono što mi odmah pada na pamet je shunit, junit, rspec, pytest. Ali šta učiniti sa ansibleom, chefom, saltstackom i drugima sličnim njima?

Na samom početku smo razgovarali SOLID i da se naša infrastruktura sastoji od malih cigli. Njihovo vrijeme je došlo.

  1. Infrastruktura je podijeljena na male cigle, na primjer, Ansible uloge.
  2. Neka vrsta okruženja je raspoređena, bilo da je to docker ili VM.
  3. Primjenjujemo našu Ansible ulogu na ovo testno okruženje.
  4. Provjeravamo da li je sve radilo kako smo očekivali (pokrećemo testove).
  5. Odlučujemo u redu ili ne ok.

IaC testiranje: Alati za testiranje jedinica

Pitanje, šta su testovi za CFM? Možete jednostavno pokrenuti skriptu ili možete koristiti gotova rješenja za ovo:

CFM
alatka

Ansible
Testinfra

glava
Inspektore

glava
Serverspec

saltstack
Goss

Primjer za testinfra, provjeravanje korisnika test1, test2 postoje i nalaze se u grupi sshusers:

def test_default_users(host):
    users = ['test1', 'test2' ]
    for login in users:
        assert host.user(login).exists
        assert 'sshusers' in host.user(login).groups

Šta odabrati? Pitanje je složeno i dvosmisleno, evo primjera promjena u projektima na githubu za 2018-2019:

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

IaC okviri za testiranje

Postavlja se pitanje: kako sve to spojiti i pokrenuti? Može uzmi i uradi to sam ako postoji dovoljan broj inženjera. Ili možete uzeti gotova rješenja, iako ih nema puno:

CFM
alatka

Ansible
Molecule

glava
Test Kitchen

Terraform
Terratest

Primjer promjena u projektima na githubu za 2018-2019:

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Molecule vs. Testkitchen

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

U početku mi probao koristiti testkitchen:

  1. Kreirajte VM paralelno.
  2. Primijenite Ansible uloge.
  3. Pokreni inspekciju.

Za 25-35 uloga radilo se 40-70 minuta, što je bilo dugo.

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Sljedeći korak je bio prelazak na jenkins/docker/ansible/molekule. Idiološki sve je isto

  1. Lint playbooks.
  2. Poravnajte uloge.
  3. Kontejner za lansiranje
  4. Primijenite Ansible uloge.
  5. Pokreni testinfra.
  6. Provjerite idempotenciju.

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Linting za 40 uloga i testovi za desetak počeli su trajati oko 15 minuta.

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Šta odabrati ovisi o mnogim faktorima, kao što su korišteni stek, stručnost u timu, itd. ovdje svako odlučuje za sebe kako da zatvori pitanje za testiranje jedinice

IaC testiranje: integracijski testovi

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Sljedeći korak u piramidi testiranja infrastrukture bit će integracijski testovi. Oni su slični jediničnim testovima:

  1. Infrastruktura je podijeljena na male cigle, na primjer Ansible uloge.
  2. Neka vrsta okruženja je raspoređena, bilo da je to docker ili VM.
  3. Za ovo testno okruženje važi mnogi Ansible role.
  4. Provjeravamo da li je sve radilo kako smo očekivali (pokrećemo testove).
  5. Odlučujemo u redu ili ne ok.

Grubo govoreći, ne provjeravamo performanse pojedinog elementa sistema kao u jediničnim testovima, mi provjeravamo kako je server konfigurisan kao cjelina.

IaC testiranje: Testovi od kraja do kraja

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Na vrhu piramide dočekuju nas testovi od kraja do kraja. One. Ne provjeravamo performanse zasebnog servera, zasebne skripte ili zasebne blokove naše infrastrukture. Provjeravamo da li su mnogi serveri povezani zajedno, naša infrastruktura radi kako očekujemo. Nažalost, nikada nisam vidio gotova kutijasta rješenja, vjerovatno zato što... Infrastruktura je često jedinstvena i teško ju je šablonizirati i stvoriti okvir za testiranje. Kao rezultat, svako kreira svoja sopstvena rešenja. Potražnja postoji, ali odgovora nema. Stoga ću vam reći šta postoji da bih natjerao druge na zdrave misli ili trljao nos u činjenici da je sve izmišljeno davno prije nas.

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Projekat sa bogatom istorijom. Koristi se u velikim organizacijama i vjerovatno je svako od vas indirektno ukrstio put s njim. Aplikacija podržava mnoge baze podataka, integracije itd. Znati kako bi infrastruktura mogla izgledati je mnogo docker-compose datoteka, a znati koje testove treba pokrenuti u kojem okruženju je Jenkins.

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Ova šema je radila dosta dugo, sve do okvira istraživanje nismo pokušali ovo prenijeti na Openshift. Kontejneri ostaju isti, ali okruženje za lansiranje se promijenilo (pozdrav DRY opet).

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Ideja istraživanja je otišla dalje i u openshift-u su pronašli nešto poput APB-a (Ansible Playbook Bundle), koji vam omogućava da upakujete znanje o tome kako postaviti infrastrukturu u kontejner. One. postoji ponovljiva, provjerljiva tačka znanja o tome kako postaviti infrastrukturu.

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Sve je ovo zvučalo dobro dok nismo naišli na heterogenu infrastrukturu: Windows nam je trebao za testove. Kao rezultat, znanje o tome šta, gdje, kako implementirati i testirati je u jenkinsu.

zaključak

Ono što sam naučio testiranjem 200 linija infrastrukturnog koda

Infrastruktura kakva je kod

  • Kod u spremištu.
  • Ljudska interakcija.
  • Infrastrukturno ispitivanje.

linkovi

izvor: www.habr.com

Dodajte komentar