Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Lähteed IaC (Infrastruktuur kui kood) koosneb mitte ainult koodist, mis hoitakse hoidlas, vaid ka inimestest ja protsessidest, mis seda koodi ümbritsevad. Kas on võimalik taaskasutada tarkvaraarenduse lähenemisi infrastruktuuri haldamisel ja kirjeldamisel? Hoidke seda mõtet meeles, kui loete artiklit.

Inglise versioon

See on minu esinemisest järgnevaga DevopsConf 2019-05-28.

Esitlused ja videod

Infrastruktuur kui bash ajalugu

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Kujutage ette, et tulete uude projekti ja teile öeldakse: «meil on Infrastruktuur kui kood«. Reaalsuses selgub, Infrastruktuur kui bash ajalugu või näiteks Dokumentatsioon kui bash ajalugu. See on täiesti reaalne olukord, näiteks sarnast juhtumit kirjeldas Denis Lysenko oma ettekandes Kuidas asendada kogu infrastruktuur ja hakata rahulikult magama, ta rääkis, kuidas nad bash ajaloost said sujuva infrastruktuuri projektis.

Mõningase soovi korral võib öelda, et Infrastruktuur kui bash ajalugu see on nagu kood:

  1. uuendatavus: saate võtta bash ajalugu, käivitada sealt käsud ja võib-olla, muide, saate välja töötava konfiguratsiooni.
  2. versioneerimine: kas tead, kes sisse logis ja mida tegi, uuesti ei ole garanteeritud, et see viib teid töötava konfiguratsioonini.
  3. lugu: ajalugu sellest, kes ja mida tegi. Ainult et te ei saa seda kasutada, kui server kaob.

Mida siis teha?

Infrastruktuur kui kood

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Isegi selline kummaline juhtum nagu Infrastruktuur kui bash ajalugu võib venitada Infrastruktuur kui kood, kuid kui me tahame teha midagi keerulisemat kui vana hea LAMP-server, peame tunnistama, et seda koodi tuleb kuidagi muuta, muuta, täiustada. Edasi vaatame paralleele Infrastruktuur kui kood ja tarkvara arendusega.

D.R.Y.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Kõvaketta arendamise projektis oli alamülesanne korrapäraselt seadistada SDS: vabastame uue versiooni — see tuleb juurutada edasiseks testimiseks. Ülesanne on äärmiselt lihtne:

  • mine ssh kaudu siia ja tee käsk.
  • koi sinna fail.
  • siin muuda seadistust.
  • seal käivita teenus
  • PROFIT!

Kirjeldatud loogika jaoks on täiesti piisav bash, eriti projekti varases etapis, kui see alles alustab. See on hea, et kasutate bash., kuid aja jooksul tekkis vajadus arendada midagi sarnast, kuid pisut erinevat. Esimene, mis pähe tuleb: kopeerimine ja kleepimine. Ja nüüd on meil juba kaks väga sarnast skripti, mis teevad peaaegu sama asja. Aja jooksul on skriptide arv kasvanud ja oleme seisma jäänud olukorras, kus on olemas teatud äriloogika, mida tuleb installatsiooni vahel erinevates skriptides sünkroonida, mis on üsna keeruline.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Selgub, et selline praktika nagu D.R.Y. (Do not Repeat Yourself) on olemas. Idee on kasutada olemasolevat koodi uuesti. See kõlab lihtsalt, kuid me ei jõudnud selleni kohe. Meie puhul oli see elementaarne idee: eraldada konfigureerimised skriptidest. St, et äriloogika, kuidas installatsioon üles ehitatakse, on eraldi, konfigureerimised eraldi.

S.O.L.I.D. CFM jaoks

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Aja jooksul projekt kasvas ja loomulik jätk oli Ansible'i tekkimine. Peamine põhjus, miks see tekkis, oli selleks, et meeskonnas oli eksklusiivne oskus ja bash ei ole mõeldud keerulise loogika jaoks. Ansible hakkas samuti sisaldama keerulist loogikat. Selleks, et keeruline loogika ei muutuks kaoseks, on tarkvaraarenduses olemas koodi korraldamise printsiibid S.O.L.I.D. Näiteks mainis Grigori Petrov oma ettekandes «Miks on IT-spetsialistile vajalik isiklik bränd», et inimene on nii üles ehitatud, et tal on lihtsam opereerida mingite sotsiaalsete substantsidega, tarkvara arenduses on need objektid. Kui neid kahte ideed kokku siduda ja edasi arendada, siis võib märkida, et infrastruktuuri kirjeldamisel saab samuti kasutada S.O.L.I.D. et tulevikus oleks lihtsam seda loogikat toetada ja muuta.

Üksiku vastutuse põhimõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Iga klass täidab vaid ühte ülesannet.

Ära peaks segama koodi ja looma monoliitseid jumalikku makaronimonstre. Infrastruktuur peaks koosnema lihtsatest tellistest. Selgub, et kui jagada Ansible'i playbook väikesteks tükkideks, loe Ansible'i rolle, siis on neid lihtsam hallata.

Avatuse ja suletuse põhimõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Avatus/suletus põhimõte.

  • Avatud laiendamiseks: see tähendab, et objekti käitumist saab laiendada, luues uusi tüüpe objekte.
  • Suletud muutmiseks: objekti käitumise laiendamisega ei tohiks teha muudatusi koodis, mis neid objekte kasutab.

Alguses käivitasime testimisstruktuuri virtuaalmasinatel, kuid kuna äri loogika käivitamine oli eraldi teostusest, suutsime probleemideta lisada bare metal'i lahendusi.

Liskovi asenduspõhimõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Barbara Liskovi asenduspõhimõte. Programmis olevad objektid peavad olema asendatavad oma alamliikide instantsidega ilma programmi korrektse täitmise muutmiseta.

Kui vaadata laiemalt, siis ei ole see konkreetse projekti eripära, kuidas seda rakendada. S.O.L.I.D., see käsitleb üldiselt CFM-i, näiteks on teises projektis vajalik paigaldada valmis Java rakendus erinevate Java, rakenduste serverite, andmebaaside, opsüsteemide jne peale. Selles näites vaatlen edasi järgmisi põhimõtteid. S.O.L.I.D.

Meie puhul on infrastruktuuri meeskonna vahel kokkulepe, et kui me installime rolli imbjava või oraclejava, siis peab meil olema java binaarne täideviimist faili. See on vajalik, kuna ülemised rollid sõltuvad sellest käitumisest; nad ootavad java olemasolu. Samal ajal võimaldab see meil asendada ühe java rakenduse/versiooni teisega, muutes samas rakenduse käivitamise loogikat.

Probleem peitub selles, et Ansible'is ei saa rakendada sellist, nagu tagajärjeks tekivad mõningad kokkulepped.

Liidese jagamise põhimõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Liidese jagamise põhimõte: „palju liideseid, mis on spetsiaalselt mõeldud klientidele, on parem kui üks üldotstarbeline liides.

Alguses proovisime kõik rakenduse käitamise varieeruvus koondada ühte Ansible playbook'i, kuid see oli keeruline hallata. Tõhusam lähenemine on, kui meil on välja spetsifitseeritud liides (kliendi ootused 443 port), siis saab konkreetse rakenduse jaoks koostada infrastruktuuri eraldi plokkidest.

Sõltuvuse pööramise põhimõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Sõltuvuse pööramise põhimõte. Ülemiste tasandite moodulid ei tohiks sõltuda alumiste tasandite moodulitest. Mõlemad moodulitüübid peaksid sõltuma abstraktsioonidest. Abstraktsioonid ei tohiks sõltuda detailidest. Detailid peaksid sõltuma abstraktsioonidest.

Siin põhineb näide antipatternil.

  1. Ühel meie kliendil oli privaatne pilv.
  2. Pilves tellisime virtuaalmasinaid.
  3. Kuid pilve eripära tõttu oli rakenduse juurutamine seotud sellega, millisele hüpervisorile VM sattus.

See, kõrgtasandi rakenduse juurutamise loogika ning sõltuvused voogasid aluspinnase hüperviisori tasanditele, mis tekitas probleeme selle loogika uuesti kasutamisel. Ära tee nii.

Interaktsioon

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Infrastruktuur koodina tähendab mitte ainult koodi, vaid ka suhete loomist koodi ja inimese vahel, ning arendajate koostööd infrastruktuuri vallas.

Bus factor

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Kujutage ette, et teie projektil on Vassili. Vassili teab kõike teie infrastruktuurist, aga mis juhtub, kui Vassili äkki kaduma peaks? See on täiesti reaalne olukord, sest teda võib buss otsa sõita. Mõnikord juhtub seda. Kui selline olukord peaks tekkima ja teadmised koodist, selle struktuurist, toimimisest ning juurdepääsudest ja paroolidest ei ole meeskonnas jagatud, siis võib kokku puutuda mitmete ebameeldivate olukordadega. Selle riskide vähendamiseks ja teadmiste jagamiseks meeskonna vahel on erinevaid lähenemisviise.

Pair Devopsing

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

See ei ole nagu naljas, et adminid joovad õlut, muudavad paroole, ja paaride programmeerimise analoog. See tähendab, et kaks inseneri istuvad ühe arvuti, ühe klaviatuuri taha ja hakkavad koos teie infrastruktuuri seadistama: seadistavad serverit, kirjutavad Ansible'i rolle jne. See kõlab hästi, kuid meil ei toiminud. Siiski töötasid selle praktika erandid. Uus töötaja, tema mentor võtab koos temaga reaalse ülesande, töötab — edastab teadmisi.

Teine erandjuhtum on incident call. Probleemi ajal koguneb hädaolukorra grupp ja seotud isikud, määratakse üks juht, kes jagab oma ekraani ja väljendab oma mõttevoogu. Teised osalejad järgivad juhi mõtteid, vaatavad trikke konsoolist, kontrollivad, et ei oleks unustanud rida logis, õpivad süsteemist uut. See lähenemine töötas pigem tõhusamalt kui mitte.

Koodide ülevaatus

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Subjektiivselt on infrastruktuuri ja selle ülesehituse teadmiste jagamine olnud efektiivsem koodide ülevaatuse kaudu:

  • Infrastruktuur on kirjeldatud koodina hoidlas.
  • Muudatused toimuvad eraldi harus.
  • Murdmisettepaneku puhul võib näha infrastruktuuri muudatuste deltat.

Siin oli eripäraks see, et ülevaatajad valiti vaheldumisi, graafiku alusel, st oli mingi tõenäosus, et jõuad uude infrastruktuuri ossa.

Koodistiil

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Aja jooksul hakkasid ülevaatustes tekkima tüli, kuna igaühel oli oma stiil ja ülevaatajate vahetus tõi esile erinevaid stiile: 2 tühikut või 4, camelCase või snake_case. Selle rakendamine ei õnnestunud kohe.

  • Esimene idee oli soovitada linteri kasutamist, kuna insenerid on ju targad inimesed. Aga erinevad redaktorid, opsüsteemid, ei olnud mugavad.
  • See arenes botiks, mis iga probleemse kommi puhul saatis slacki sõnumi ja lisas linteri väljundi. Kuid enamikul juhtudel olid tähtsamad asjad ja kood jäi parandamata.

Roheline ehituse juht

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Aeg möödub ja oleme jõudnud arusaamale, et me ei saa lubada meisterkommi, mis ei läbida teatud teste. Voilà! Me leiutasime Roheline ehituse juhi, mida on juba pikka aega tarkvaraarenduses praktiseeritud:

  • Arendamine toimub eraldi harus.
  • Sellel harul käiakse testid läbi.
  • Kui testid ei läbi, siis kood ei pääse meisterisse.

Selle otsuse vastuvõtt oli väga valulik, kuna see tekitas palju vaidlusi, kuid see oli seda väärt, kuna ülevaatusele hakkasid tulema sulandumisettepanekud ilma stiilivääratusteta ja aja jooksul probleemsete kohtade arv hakkas vähenema.

IaC testimine

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Lisaks stiili kontrollimisele võib kasutada ka muid meetodeid, näiteks kontrollida, kas teie infrastruktuur suudab tõeliselt rakenduda. Või kontrollida, et muudatused infrastruktuuris ei tooks kaasa rahakaotust. Miks see vajalik võiks olla? Küsimus on keeruline ja filosoofiline, paremini vastata oleks jutuga, et kunagi oli Powershellis auto-skaala, mis ei kontrollinud piiritingimusi => loodi rohkem VM-e kui vajalik => klient kulutas rohkem raha kui planeeris. Ebameeldiv, kuid see viga oleks olnud täiesti võimalik varasematel etappidel kinni püüda.

Võib küsida, miks teha keeruline infrastruktuur veel keerulisemaks? Testid infrastruktuuri jaoks, nagu ka koodi jaoks, ei ole ülesehitamiseks, vaid teadmiseks, kuidas teie infrastruktuur peaks töötama.

IaC testimise piramide

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

IaC testimine: staatiline analüüs

Kui üles seada kogu infrastruktuur ja kontrollida, kas see töötab, võib see osutuda ajakulukaks ja nõuda palju pingutust. Seetõttu peab aluseks olema midagi, mis töötab kiiresti, on seda palju ja katab paljusid primitiivseid kohti.

Bash on keeruline

Vaatame lihtsat näidet. Kuidas valida kõik failid praeguses kaustas ja kopeerida need teise kohta. Esimene mõte, mis pähe tuleb:

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

Aga mis juhtub, kui failinimes on tühik? No okei, me ju teame, kuidas kasutada jutumärke:

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

Nüüd olete targad? Ei! Mida teha, kui kaustas pole midagi, st globimine ei tööta.

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

Kas nüüd olete targad? Ei... Unustasite, et failinimes võib olla n.

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

Staatilised analüüsivahendid

Eelmise sammu probleemi sai tuvastada, kui unustasime jutumärgid, selle jaoks on looduses palju vahendeid Shellcheck, neid on tõepoolest palju, ja tõenäoliselt leiate oma IDE jaoks lintimise vahendi oma tehnoloogiast.

Keel
Vahend

bash
Shellcheck

Ruby
RuboCop

python
Pylint

ansible
Ansible Lint

IaC testimine: üksustestid

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Kuidas me nägime eelmises näites, ei ole lintijad kõikvõimsad ja ei suuda märkida kõiki probleemseid kohti. Jätkates sarnaselt tarkvaraarenduse testimisega, võivad inimesed meenutada ühikute teste. Täiendavalt tulevad meelde shunit, junit, rspec, pytest. Aga mis teha ansible, chef, saltstack ja teistega?

Alguses rääkisime S.O.L.I.D. ja sellest, et meie infrastruktuur peaks koosnema väikestest tükkidest. Nüüd on nende aeg.

  1. Infrastruktuur jaguneb väikesteks tükkideks, näiteks Ansible'i rollideks.
  2. Käivitame mingi keskkonna, olgu see siis docker või virtuaalmasin.
  3. Rakendame sellele testkeskkonnale oma Ansible'i rolli.
  4. Kontrollime, et kõik toimib nagu oodatud (käivitame testid).
  5. Otsustame, kas on okei või ei.

IaC testimine: Ühikutestide tööriistad

Küsimus, mis on testid CFM jaoks? Võib lihtsalt skripti käivitada, kuid võib kasutada ka valmis lahendusi:

CFM
Vahend

Ansible
Testinfra

Chef
Inspec

Chef
Serverspec

saltstack
Goss

Näide testinfrast, kontrollime, et kasutajad test1, test2 eksisteerivad ja kuuluvad rühma 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

Mida valida? Küsimus on keeruline ja mitmeti mõistetav, siin on näide muudatusest projektides GitHub'is 2018-2019 aasta jooksul:

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

IaC Testimise raamistike

Kuidas kõike seda kokku koguda ja käivitada? Saab kõik ise ära teha kui on piisavalt insenere. Võib kasutada ka valmis lahendusi, kuigi neid pole just eriti palju:

CFM
Vahend

Ansible
Molecule

Chef
Test Kitchen

Terraform
Terratest

Näide muudatusest projektides GitHub'is 2018-2019 aasta jooksul:

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Molecule vs. Testkitchen

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Alguses proovisime kasutada testkitchen'i:

  1. Luua VM paralleelselt.
  2. Rakendada Ansible'i rolle.
  3. Käivitada inspec.

25-35 rolli jaoks töötas see 40-70 minutit, mis oli liiga kaua.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Järgmine samm oli minna Jenkins'i / Docker'i / Ansible'i / Molecule'i peale. Ideoloogiliselt on kõik sama.

  1. Lintida playbook'id.
  2. Lintida rollid.
  3. Käivitada konteiner
  4. Rakendada Ansible'i rolle.
  5. Käivitada testinfra.
  6. Kontrollida idempotentsust.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Lintimine 40 rolli jaoks ja testid kümne jaoks võttis umbes 15 minutit.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Valik sõltub paljuski mitmest tegurist, nagu näiteks kasutatav tehnoloogia, meeskonna ekspertiis jne. Igaühel on oma otsus, kuidas Unit-testimise küsimust lahendada.

IaC Testimine: Integratsioonitestid

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Infrastruktuuri testimise püramiidi järgmises etapis tulevad integreerimistestid. Need sarnanevad Unit-testidele:

  1. Infrastruktuur jaguneb väikesteks plokkideks, näiteks Ansible'i rollideks.
  2. Käivitame mingi keskkonna, olgu see siis docker või virtuaalmasin.
  3. Sellele testkeskkonnale rakendatakse hulgaliselt Ansible'i rolle.
  4. Kontrollime, et kõik töötas nagu ootasime (sooritame testid).
  5. Otsustame, kas on okei või ei.

Üldiselt ei kontrolli me süsteemi eraldi elemendi toimivust nagu unit-testides, vaid kontrollime, kuidas server on tervikuna konfigureeritud.

IaC testimine: lõpp-lõpuni testid

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Püramiidi tipus kohtavad meid lõpp-lõpuni testid. See tähendab, et me ei kontrolli eraldi serveri, eraldi skripti ega eraldi ploki toimivust meie infrastruktuuris. Kontrollime, et hulk servereid, mis on ühte, toimib meie ootuste kohaselt. Kahjuks ei ole mul olnud ette nähtud valmis lahendusi näha, võib-olla seetõttu, et infrastruktuur on sageli ainulaadne ja seda on raske mallida ning luua raamistikke testimiseks. Seega loovad kõik oma lahendusi. Uudishimu on olemas, aga vastust pole. Seetõttu räägin, mis on olemas, et inspireerida teisi mõtlema või juhatada mind sellele, et kõik on juba ammu meie eest välja mõeldud.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Projektil on pikk ajalugu. Seda kasutatakse suurtes organisatsioonides ja tõenäoliselt olete te kõik kaudselt kokku puutunud. Rakendus toetab mitmeid andmebaase, integratsioone jne. Teadmine, milline infrastruktuur välja näeb, on rida docker-compose faile, samas kui teadmine, milliseid teste ja millises keskkonnas käivitada – see on jenkins.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

See skeem töötas piisavalt kaua, kuni uurimise käigus proovisime seda Openskisse üle viia. Konteinerid jäid samaks, kuid käivitamise keskkond muutus (tervitused D.R.Y.-le jälle).

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Uurimistöö mõte arenes edasi ja Openskis avastasime sellise asja nagu APB (Ansible Playbook Bundle), mis võimaldab konteinersse pakkida teadmisi infrastruktuuri seadistamisest. See tähendab, et on olemas taastatav ja testitav teadmuspunkt, kuidas infrastruktuuri seadistada.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

See kõik kõlas hästi, kuni sattusime heterogeense infrastruktuuri peale: meil olid testide jaoks vajalikud Windowsi süsteemid. Lõpuks on teadmine, kuidas, kus ja mida seadistada ning testida, jäänud jenkinsisse.

Kokkuvõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Infrastruktuur kui kood on

  • Kood hoidlas.
  • Inimeste koostöö.
  • Infrastruktuuri testimine.

lingid

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster