
Megközelítés IaC (Infrastructure as Code) nemcsak a kódból áll, amely egy adattárházban tárolódik, hanem az emberekből és folyamatokból is, amelyek körülveszik ezt a kódot. Használhatók-e a szoftverfejlesztésből származó megközelítések az infrastruktúra kezelésében és leírásában? Jó, ha az elméletet szem előtt tartjuk, miközben olvassuk a cikket.
Ez a feljegyzésem a Gyorsan emlékezzünk vissza, hogyan működik a moduláris aritmetika. Az óra már egy ismert koncepció. Az órák használata .
Prezentációk és videók
- Száraz futás 2019-04-24
Infrastructure as bash history

Tegyük fel, hogy új projektre érkezik, ahol azt mondják: „van nekünk Infrastructure as Code„. A valóságban kiderül, Infrastructure as bash history vagy például Documentation as bash history. Ez egy teljesen valóságos helyzet, például Denis Lysenko egy hasonló esetet ismertetett a , elmondta, hogy a bash history alapján hogyan alakítottak ki egy jól működő infrastruktúrát a projekten.
Az emberi akarattal mondhatjuk, hogy Infrastructure as bash history ez olyan, mint a kód:
- az újraindítások során?: kiveheti a bash history-t, végrehajthatja a parancsokat onnan, és valószínűleg egy működő konfigurációt kap a végén.
- verziókezelés: tudja, ki lépett be és mit csinált, de nem biztos, hogy ez a végén egy működő konfigurációhoz vezet.
- történet: a történet, hogy ki és mit csinált. De nem tudja használni, ha elveszíti a szervert.
Mit tegyünk?
Infrastructure as Code

Még egy olyan különös eset is, mint Infrastructure as bash history lehet, hogy sokáig húzódik a Infrastructure as Code, de amikor valami bonyolultabb dolgot akarunk létrehozni, mint a régi jól ismert LAMP szerver, akkor arra jutunk, hogy ezt a kódot valamilyen módon módosítani kell, megváltoztatni, fejleszteni. A továbbiakban a párhuzamokat fogjuk vizsgálni az Infrastructure as Code és a szoftverfejlesztés között.
D.R.Y.

A tárolórendszer fejlesztésénél volt egy alfeladat : új verziót adunk ki - ezt ki kell terjeszteni a további teszteléshez. A feladat rendkívül egyszerű:
- ikon itt ssh-n keresztül belépni, és hajtson végre egy parancsot.
- ide másolja a fájlt.
- itt módosítsa a konfigurációt.
- ott indítsa el a szolgáltatást.
- …
- NYERESÉG!
A leírt logikához teljes mértékben elegendő a bash, különösen a projekt korai szakaszában, amikor éppen csak indul. Ez , de idővel felmerülnek a kérések arra, hogy valami hasonlót, de kicsit másként valósítsunk meg. Az első, ami eszünkbe jut, a másolás-beillesztés. Így már két nagyon hasonló scriptünk van, amelyek szinte ugyanazt csinálják. Idővel a script-ek száma megnőtt, és szembesültünk azzal, hogy van egy bizonyos üzleti logika az installációk kiépítésére, amelyet szinkronizálnunk kell a különböző scriptek között, ami elég bonyolult.

Kiderült, hogy létezik egy ilyen gyakorlat: D.R.Y. (Ne Ismételd Meg Magad). Az ötlet az, hogy újrahasználjuk a meglévő kódot. Egyszerűen hangzik, de nem jutottunk el ide azonnal. A mi esetünkben ez egy banális ötlet volt: a konfigurációkat külön választani a scriptektől. Tehát az üzleti logika az installáció kiépítése során külön, a konfigurációk külön.
S.O.L.I.D. CFM-re

Idővel a projekt nőtt, és az Ansible megjelenése lett. Fő oka ennek a csapatban lévő szakértelem, és hogy a bash nem alkalmas bonyolult logikákhoz. Az Ansible is összetett logikát tartalmazott. Ahhoz, hogy a bonyolult logika ne váljon káosszá, a szoftverfejlesztés során léteznek a kód szervezésének alapelvei. S.O.L.I.D. Például Grigory Petrov a "Miért fontos a személyes márka az IT szakembereknek" előadásában felvetette, hogy az ember természete szerint könnyebben bánik valamilyen társadalmi entitásokkal, a szoftverfejlesztésben ezek az objektumok. Ha ezeket az ötleteket ötvözzük és tovább fejlesztjük, észrevehetjük, hogy az infrastruktúra leírásában is S.O.L.I.D. ezáltal könnyebben fenntartható és módosítható logikát jelent.
Az Egyszerűsített Felelősség Elve

Minden osztály csak egy feladatot lát el.
Ne keverjük a kódot, és ne hozzunk létre monolitikus, isteni makaron monstereket. Az infrastruktúrának egyszerű építőkockákból kell állnia. Kiderült, hogy, ha az Ansible playbook-t kis darabokra törjük, olvasható Ansible szerepekre, akkor könnyebb őket karbantartani.
A Nyitott-Zárt Elv

A nyitott/zárt elv.
- Nyitottak az bővítésre: azt jelenti, hogy egy entitás viselkedése új entitástípusok létrehozásával bővíthető.
- Zártak a módosításra: az entitás viselkedésének bővítése miatt nem szabad változtatni azon a kódon, amely ezeket az entitásokat használja.
Kezdetben tesztinfrastruktúrát indítottunk virtuális gépeken, de mivel az üzleti logika külön volt a megvalósítástól, problémamentesen hozzáadtuk a telepítést bare metal-ra.
A Liskov Helyettesítési Elv

Barbara Liskov Helyettesítési Elve. A programban található objektumoknak helyettesíthetőknek kell lenniük a típusaik példányaival anélkül, hogy a program helyessége megváltozna.
Ha tágabban nézzük, nem egy specifikus projekt sajátossága, hogy ott alkalmazható. S.O.L.I.D., ez alapvetően a CFM-ről szól, például egy másik projektben dobozos Java alkalmazást kell telepíteni különböző Java, alkalmazás szerverek, adatbázisok, operációs rendszerek fölé, stb. E példán fogom megvizsgálni a további elveket. S.O.L.I.D.
A mi esetünkben az infrastruktúra csapat keretein belül megegyeztünk, hogy ha beállítjuk az imbjava vagy oraclejava szerepet, akkor van egy bináris végrehajtható fájlunk, java. Erre szükség van, mivel a magasabb szintű szerepek függenek ettől a viselkedéstől, elvárják a java meglétét. Ugyanakkor ez lehetővé teszi számunkra, hogy egy java megvalósítást/verziót lecseréljünk anélkül, hogy megváltoztatnánk az alkalmazás telepítési logikáját.
A probléma itt abban rejlik, hogy az Ansible-ben nem lehet megvalósítani ilyen, mint következmény, a csapaton belül megjelennek valamilyen megállapodások.
Az Interfész Megosztási Elv

Az interfész megosztásának elve: „több interfész, amely kifejezetten az ügyfelek számára készült, jobb, mint egy általános célú interfész.”
Kezdetben megpróbáltuk a teljes variabilitást egy Ansible playbookba sűríteni, de ez nehezen támogatható volt, és a megközelítés, amikor a követelmény specifikált külső interfész (az ügyfél várja a 443-as portot), lehetővé teszi számunkra, hogy a konkrét megvalósításhoz különböző építőelemekből építsük fel az infrastruktúrát.
A Függőségi Inverziós Elv

A függőségek inverziójának elve. A magasabb szintű moduloknak nem szabad függeniük az alacsonyabb szintű moduloktól. Mindkét modul típusnak az absztrakcióktól kell függenie. Az absztrakcióknak nem szabad függeniük a részletektől. A részleteknek az absztrakcióktól kell függeniük.
Itt egy példa az antidizájnra fog épülni.
- Az egyik ügyfelünknél privát felhő állt rendelkezésre.
- A felhőn belül virtuális gépeket rendeltünk.
- De a felhő sajátosságai miatt az alkalmazás telepítése attól függött, hogy melyik hypervisorra került a VM.
Tehát a magas szintű alkalmazástelepítési logika, a függőségek a hypervisor alacsonyabb szintjein haladtak, ami problémákat jelentett a logika újrahasznosításában. Ezt nem kéne.
Interakció

A kód infrastruktúra nemcsak a kódra vonatkozik, hanem a kód és az ember közötti kapcsolatokra is, a infrastuktúra fejlesztői közötti interakciókra.
Busz faktor

Tegyük fel, hogy van egy Vasja a projektben. Vasja mindent tud az infrastruktúrádról, mi történik, ha Vasja egyszer csak eltűnik? Ez egy teljesen valóságos helyzet, hiszen elütheti őt egy busz. Néha előfordul ilyesmi. Ha ez megtörténik, és a kódról, annak struktúrájáról, működéséről, jelszavakról és felhasználónevekről való tudás nincs elosztva a csapatban, akkor számos kellemetlen helyzettel szembesülhetsz. A kockázatok minimalizálása és a tudás csapaton belüli elosztása érdekében különböző megközelítéseket alkalmazhatunk.
Páros Devops

Ez nem olyan, mint , hogy az adminisztrátorok sört isznak, jelszavakat cserélnek, és a páros programozás analógja. Tehát két mérnök ül le egy számítógéphez, egy billentyűzethez, és elkezdik közösen beállítani az infrastruktúrádat: beállítani a szervert, Ansible szerepet írni, stb. Jól hangzik, de nálunk nem működött. Azonban a gyakorlat egyes konkrét esetei működtek. Egy új munkatárs érkezett, a mentora valós feladatot vesz fel vele, dolgozik — átadja a tudást.
Egy másik példája ennek az incident call. Probléma esetén összehívják a felelős csapatokat, és kijelölnek egy vezetőt, aki megosztja a képernyőjét és elmondja a gondolatmenetét. A többi résztvevő követi a vezető gondolatmenetét, megnézi a konzolból származó trükköket, ellenőrzik, hogy nem hagytak-e ki egy sort a naplóból, új dolgokat tudnak meg a rendszerről. Ez a megközelítés inkább működött, mint nem.
Kódellenőrzés

Szubjektíven, a tudás infrastruktúráról és annak működéséről történő elosztása hatékonyabban zajlott kódellenőrzésen keresztül:
- Az infrastruktúra kódban van leírva a tárolóban.
- A módosítások külön ágon történnek.
- A merge request során látható az infrastruktúra módosításainak delta.
Az érdekessége az volt, hogy a felülvizsgálók sorban, ütemezés szerint lettek kiválasztva, ami azt jelenti, hogy bizonyos valószínűséggel egy új infrastruktúra szakaszba kerülsz.
Kódstílus

Idővel kezdték el zavarni a revíziók során felmerülő ellentétek, mivel a revíziózóknak saját stílusuk volt, és a rotáció miatt különböző stílusokkal találkoztak: 2 vagy 4 szóköz, camelCase vagy snake_case. Ezt nem könnyen sikerült bevezetni.
- Az első ötlet az volt, hogy ajánljuk a linter használatát, hiszen végül is mérnökök vagyunk, mindannyian okosak. De különböző szerkesztők és operációs rendszerek miatt ez nem volt kényelmes.
- Ez egy botra fejlődött, amely minden problémás commit után írt a Slackbe, és csatolta a linter kimenetét. De a legtöbb esetben fontosabb feladatok merültek fel, és a kód javítatlan maradt.
Zöld Build Master

Idő telik, és arra a következtetésre jutottunk, hogy nem engedhetünk be a masterbe olyan commiteket, amelyek nem teljesítenek bizonyos teszteket. Voila! Feltaláltuk a Zöld Build Master-t, amelyet már régóta alkalmaznak a szoftverfejlesztés során:
- A fejlesztés külön ágon zajlik.
- Ezen az ágon futtatták a teszteket.
- Ha a tesztek nem teljesülnek, a kód nem kerül a masterbe.
A döntés elfogadása elég fájdalmas volt, mivel számos vitát váltott ki, de megérte, mert a revíziókra érkező összevonási kérelmek stílusviták nélkül érkeztek, és idővel a problémás esetek száma csökkent.
IaC Tesztelés

A stílus ellenőrzésén kívül más dolgokat is használhatunk, például ellenőrizhetjük, hogy az infrastruktúrája valóban telepíthető-e. Vagy megvizsgálhatjuk, hogy az infrastruktúra módosításai nem vezetnek-e pénzveszteséghez. Miért lehet szükség erre? A kérdés bonyolult és filozófikus, legjobban egy mesével tudom illusztrálni, hogy egyszer volt egy auto-scaler Powershell-en, amely nem ellenőrizte a határfeltételeket => több VM jött létre, mint amennyire szükség volt => az ügyfél többet költött, mint tervezett. Nem jó érzés, de ezt a hibát nagyon korai szakaszokban meg lehetett volna fogni.
Megkérdezheti, hogy miért kell még bonyolultabbá tenni a bonyolult infrastruktúrát? Az infrastruktúrára vonatkozó tesztek, akárcsak a kód számára, nem az egyszerűsítésről szólnak, hanem arról, hogy tudjuk, hogyan kell az infrastruktúránknak működnie.
IaC Tesztelési Piramis

IaC Tesztelés: Statikus Elemzés
Ha az egész infrastruktúrát egyszerre telepítjük és ellenőrizzük, hogy működik, akkor kiderülhet, hogy ez rengeteg időt vesz igénybe, és sok időt követel. Ezért valaminek gyorsan működőnek kell lennie, sok van belőle, és számos primitív helyet lefed.
A Bash nehéz
Nézzünk egy banális példát. Válasszuk ki az összes fájlt a jelenlegi könyvtárból, és másoljuk át egy másik helyre. Az első, ami eszembe jut:
for i in * ; do
cp $i /some/path/$i.bak
doneDe mi van, ha a fájl nevében szóköz van? Nos, rendben van, okosak vagyunk, tudjuk használni a idézőjeleket:
for i in * ; do cp "$i" "/some/path/$i.bak" ; doneJól csináltuk? Nem! Mi van, ha a könyvtárban nincs semmi, azaz nem működik a globálás.
find . -type f -exec mv -v {} dst/{}.bak ;Most jól csináltuk? Nem… Elfelejtettük, hogy a fájl nevében lehet n.
touch x
mv x "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dirStatikus elemző eszközök
A korábbi lépés problémáját észlelhettük, amikor elfelejtettük az idézőjeleket, erre számos eszköz áll rendelkezésre. , valójában sokan vannak, és valószínűleg talál egy lintert a saját IDE-jéhez a technológiai stackjéhez.
Nyelv
Eszköz
bash
Ruby
python
ansible
IaC Tesztelés: Egység Tesztek

Ahogy azt a korábbi példából láttuk, a linerek nem mindenhatóak, és nem tudnak minden problémát kiemelni. A szoftverfejlesztés tesztelésével analóg módon emlékezhetünk az egységtesztekre. Azonnal eszembe jut , , , . De mi a helyzet az ansible-lal, chef-fel, saltstack-kel és hasonlókkal?
Kezdetben arról beszéltünk, hogy S.O.L.I.D. és hogy az infrastruktúránknak kis építőelemekből kell állnia. Most elérkezett az idejük.
- Az infrastruktúra apró építőelemekre bontható, például Ansible szerepekre.
- Egy adott környezetet állítunk fel, legyen az docker vagy virtuális gép.
- Ezen a tesztkörnyezeten alkalmazzuk az Ansible szerepünket.
- Ellenőrizzük, hogy minden a várakozásaink szerint működött (teszteket futtatunk).
- Döntünk, hogy oké vagy nem oké.
IaC Tesztelés: Egység Tesztelő Eszközök
A kérdés az, hogy mik azok a tesztek a CFM-hez? Egyszerűen futtathatunk egy szkriptet, de használhatunk kész megoldásokat is:
CFM
Eszköz
Ansible
Chef
Chef
saltstack
Példa a testinfra-ra, ellenőrizzük, hogy a felhasználók test1, test2 léteznek és a csoport tagjai sshusers:
def test_default_users(host):
users = ['test1', 'test2']
for login in users:
assert host.user(login).exists
assert 'sshusers' in host.user(login).groupsMit válasszunk? A kérdés bonyolult és nem egyértelmű, itt van egy példa a github projekteken történt változásokra 2018-2019 között:

IaC Tesztelő Keretrendszerek
Felmerül a kérdés, hogyan lehet mindezt összegyűjteni és futtatni? Lehet a megfelelő számú mérnök rendelkezésre állása esetén. Vagy lehet kész megoldásokat választani, bár nem sok van belőlük:
CFM
Eszköz
Ansible
Chef
Terraform
Példa a github projekteken történt változásokra 2018-2019 között:

Molecule vs. Testkitchen

Kezdetben mi :
- Hozzunk létre párhuzamosan virtuális gépet.
- Alkalmazzuk az Ansible szerepeket.
- Futtassuk az Inspec-t.
25-35 szerep esetén 40-70 percet vett igénybe, ami hosszú volt.

A következő lépés a Jenkins / Docker / Ansible / Molecule átállása volt. Ideológiailag minden ugyanaz.
- Linteljük a playbookokat.
- Linteljük a szerepeket.
- Indítsuk el a konténert.
- Alkalmazzuk az Ansible szerepeket.
- Futtassuk a Testinfra-t.
- Ellenőrizzük az idempotenciát.

A 40 szerepre vonatkozó lintelés és a tesztek körülbelül 15 percet vettek igénybe.

A választás sok tényezőtől függ, például a használt stacktől, a csapat szakértelmétől stb. Itt mindenkinek magának kell eldöntenie, hogyan közelíti meg az egységtesztelés kérdését.
IaC Tesztelés: Integrációs Tesztek

A tesztelési piramis következő szintjén integrációs tesztek jelennek meg. Ezek hasonlítanak az egységtesztekhez:
- Az infrastruktúra apró darabokra, például Ansible szerepekre bomlik.
- Egy adott környezetet állítunk fel, legyen az docker vagy virtuális gép.
- Ezt a tesztkörnyezetet alkalmazzuk több Ansible szerepekkel.
- Ellenőrizzük, hogy minden úgy működik, ahogy várjuk (futtatjuk a teszteket).
- Döntünk, hogy oké vagy nem oké.
Durván szólva, nem az egyes rendszeralkotók működését ellenőrizzük, mint az egységteszteknél, hanem azt, hogy a szerver összességében hogyan van konfigurálva.
IaC Tesztelés: Végső Tesztek

A piramis csúcsán végső tesztek várnak ránk. Tehát nem az egyes szerverek, egyes szkriptek, egyes építőelemek működését ellenőrizzük az infrastruktúránkban. Ellenőrizzük, hogy a különböző szerverek, amelyek egy egységes infrastruktúrát alkotnak, úgy működnek, ahogy azt várjuk. Sajnos dobozos megoldásokat eddig nem láttam, valószínűleg azért, mert az infrastruktúrák gyakran egyediek, és nehéz sablonosítani őket és keretrendszert kidolgozni a tesztelésre. Ennek eredményeként mindenki saját megoldásokat alkot. Igény van rá, de válasz nem létezik. Ezért elmondom, mi a helyzet, hogy másokat jó gondolatokra inspiráljak, vagy hogy valaki rávilágítson, hogy ezt már régen kitalálták.

Egy gazdag történelemmel bíró projekt. Nagy szervezetekben használják, és valószínűleg mindannyian közvetve találkoztunk vele. Az alkalmazás számos adatbázist, integrációt, stb. támogat. Az infrastruktúra megvalósulásának ismerete sok docker-compose fájlt jelent, a tudás pedig azt, hogy milyen teszteket kell futtatni melyik környezetben - ez a Jenkins.

Ez a séma viszonylag sokáig működött, amíg meg nem próbáltuk ezt átvinni az Openshiftbe. A konténerek változatlanok maradtak, de a végrehajtási környezet megváltozott (üdvözöljük újra a D.R.Y.-t).

A kutatás gondolata továbbfejlődött, és az OpenShift-ben egy APB (Ansible Playbook Bundle) nevű dolog került elő, amely lehetővé teszi, hogy tudást csomagoljunk be egy konténerbe az infrastruktúra kiépítésének módjáról. Vagyis van egy reprodukálható, tesztelhető tudáspont arról, hogyan kell kiépíteni az infrastruktúrát.

Mindez jól hangzott, amíg nem ütköztünk heterogén infrastruktúrába: a tesztekhez Windows-ra volt szükség. Végül a tudás arról, hogy hol, hogyan kell kiépíteni és tesztelni, a Jenkins-ben van.
Következtetés

Infrastruktúra mint kód
- Kód a tárolóban.
- Emberek közötti interakció.
- Az infrastruktúra tesztelése.
linkek
- Száraz futás 2019-04-24
- &
Forrás: habr.com
