Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Lähenemine . See on arusaadav. Lõppude lõpuks, just nemad andsid võimaluse konfigureerida täielikult virtuaalne andmekeskus: füüsilisi servereid, riiuleid, võrgu komponente ei ole ning kogu infrastruktuuri saab kirjeldada skriptide ja konfiguratsioonifailide abil. (Infrastructure as Code) koosneb mitte ainult koodist, mis hoitakse hoidlapis, vaid ka inimestest ja protsessidest, mis seda koodi ümbritsevad. Kas saame kasutada tarkvaraarenduses kasutatavaid lähenemisi infrastruktuuri haldamiseks ja kirjeldamiseks? Oluline on hoida seda mõtet meeles, kui loete seda artiklit.

Inglise versioon

See on minu esitas . Tundub, et DevopsConf 2019-05-28.

Esitlused ja videod

Infrastructure as bash history

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Oletame, et asute uuele projekti, ja teile öeldakse: 'meil on Infrastructure as Code'. Tõelisuses selgub, Infrastructure as bash history või näiteks Documentation as bash history. See on täiesti reaalne olukord, näiteks kirjeldas sellist juhtumit Denis Lysenko oma ettekandes Kuidas asendada kogu infrastruktuur ja hakata rahulikult magama, ta rääkis, kuidas bash ajaloost saadi korralik infrastruktuur projektis.

Mõningase soovi korral võib öelda, et Infrastructure as bash history see on nagu kood:

  1. konfiguratsiooni korduvus: saate võtta bash ajaloo, täita sealt käske, tõenäoliselt saate töökeskkonna tulemuseks.
  2. versioonimine: teate, kes logis sisse ja mida tegi, kuid ei ole garanteeritud, et see viib teid töökeskkonna tulemusele.
  3. ajalugu: ajalugu, kes ja mida tegi. Ainult te ei saa seda kasutada, kui kaotate serveri.

Mis siis teha?

Infrastructure as Code

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Isegi sellist kummalist juhtumit nagu Infrastructure as bash history on võimalik venitada Infrastructure as Code, kuid kui soovime teha midagi keerulisemat kui vana hea LAMPi server, jõuame sinna, et seda koodi tuleb mingil moel muuta, täiustada ja arendada. Edasi käsitleme paralleele Infrastructure as Code ja tarkvaraarenduse vahel.

D.R.Y.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Süvendatud andmekandmete arendusprojekti korral oli alateema perioodiliselt seadistada SDS: väljastame uue väljaande — see tuleb rakendada edasisteks testimiseks. Ülesanne on äärmiselt lihtne:

  • siia logige sisse ssh kaudu ja käivitage käsk.
  • seal kopeerige fail.
  • siin parandage konfi.
  • seal käivitage teenus.
  • …
  • PROFIT!

Kirjeldatud loogika jaoks on bash täiesti piisav, eriti projekti varases staadiumis, kui see alles alustab. See ei ole halb, et kasutate bash'i., kuid aja jooksul tekivad soovid luua midagi sarnast, kuid veidi erinevat. Esimene mõte, mis pähe tuleb: copy-paste. Ja nüüd on meil juba kaks väga sarnast skripti, mis teevad peaaegu sama. Aja jooksul on skriptide arv kasvanud ja oleme silmitsi seisnud olukorraga, kus on teatud äriloogika installatsiooni rakendamiseks, mida tuleb erinevate skriptide vahel sünkroniseerida, mis on üsna keeruline.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Selgub, et on olemas selline praktika nagu D.R.Y. (Ära Korda Iseennast). Idee on kasutada olemasolevat koodi uuesti. Kõlab lihtsalt, kuid me ei jõudnud selleni kohe. Meie puhul oli see lihtne idee: eraldada konfiguratsioonid skriptidest. St. äriloogika, kuidas installatsioon käivitub, eraldi, konfiguratsioonid eraldi.

S.O.L.I.D. for CFM

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Aja jooksul projekt kasvas ja loomulik jätk oli Ansible'i ilmumine. Peamine põhjus, miks see tekkis, on meeskonnas olemasolev ekspertisus ja see, et bash ei ole mõeldud keerukaks loogikaks. Ansible'i sisemuses on samuti keeruline loogika. Selleks, et keeruline loogika ei muutuks kaoseks, kasutatakse tarkvaraarenduses koodi organiseerimise põhimõtteid. S.O.L.I.D. Samuti mainis näiteks Grigori Petrov oma ettekandes „Miks IT-spetsialistile on isiklik bränd oluline“ küsimust, et inimene, nagu ta on loodud, suudab lihtsamalt töötada teatud sotsiaalsete elementidega, tarkvaraarenduses on need objektid. Kui neid kahte ideed ühendad ja edasi arendad, siis võib märgata, et infrastruktuuri kirjeldamisel saab kasutada S.O.L.I.D. et tulevikus oleks lihtsam seda loogikat toetada ja kohandada.

The Single Responsibility Principle

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Iga klass täidab vaid ühe ülesande.

Ärge segage koodi ja looge monoliitseid jumalikke makaronimonstre. Infrastruktuur peaks koosnema lihtsatest plokkidest. Selgub, et kui jagada Ansible'i playbook väikesteks tükkideks, st Ansible'i rollideks, siis on neid lihtsam toetada.

The Open Closed Principle

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Avatud/Suletud põhimõte.

  • Avatud laiendamiseks: tähendab, et üksuse käitumist saab laiendada, luues uusi üksuse tüüpe.
  • Suletud muutmiseks: käitumise laiendamise tõttu ei tohi teha muudatusi koodis, mis neid üksusi kasutab.

Alguses käivitasime testimisstrateegia virtuaalmasinatel, kuid kuna äri loogika oli eraldi rakendusest, saime probleemideta lisada baremetal installatsiooni.

Liskovi asendamise põhimõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Barbara Liskovi asendamise põhimõte. Programmis olevad objektid peavad olema asendatavad oma alamliikide eksemplaridega ilma programmi teostatavuse muutmiseta.

Kui vaadata laiemalt, siis ei ole see konkreetse projekti spetsiifilisus, vaid millega saab tegeleda. S.O.L.I.D., see puudutab CFM-i laiemalt, näiteks teises projektis tuleb juurutada kastiversioon Java rakendust erinevate Java, rakenduste serverite, andmebaaside, OS-ide jne peal. Seda näidet arvesse võttes vaatan edasi teisi põhimõtteid. S.O.L.I.D.

Meie puhul on infrastruktuuri meeskonna seas kokku lepitud, et kui me oleme installinud rolli imbjava või oraclejava, siis meil on olemas binaarne käivitatav fail java. See on vajalik, kuna ülemised rollid sõltuvad sellest käitumisest, nad ootavad java olemasolu. Samuti võimaldab see meil asendada ühe rakenduse / versiooni java teisega, muutmata samas rakenduse juurutamise loogikat.

Probleem peitub selles, et Ansible'is ei saa sellist asja rakendada, tulemusena tekivad meeskonnas mõned kokkulepped.

Liidese jagamise põhimõte

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Liidese jaotamise põhimõte: "palju liideseid, mis on spetsiaalselt loodud klientide jaoks, on parem kui üks üldine liides."

Alguses proovisime kogu rakenduse juurutamise varieeruvust koondada ühte Ansible playbook'i, kuid see oli keeruline hallata, ja lähenemine, kus meil on välisse määratud liides (kliendi ootus 443 port), võimaldab meil konkreetse rakenduse jaoks infrastruktuuri komponendina jaotada erinevatest plokkidest.

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

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Sõltuvuse pööramise põhimõte: Ülemise tasandi moodulid ei tohiks sõltuda alumise tasandi moodulitest. Mõlemad moodulitüübid peavad sõltuma abstraktsioonidest. Abstraktsioonid ei tohiks sõltuda detailidest. Detailid peavad sõltuma abstraktsioonidest.

Siin on näide, mis põhineb antipaternil.

  1. Ühel meie kliendil oli privaatne pilv.
  2. Pilves tellisime virtuaalmasinaid.
  3. Kuid pilve spetsiifilisuse tõttu sõltus rakenduse juurutamine sellest, millisele hüperviisorile VM sattus.

See, the high-level logic of application deployment and dependencies flowed down to the underlying levels of the hypervisor, which meant problems when reusing this logic. Ära nii tee.

Interaction

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Infrastructure as code is not just about code; it’s also about the relationships between code and people, about interactions between infrastructure developers.

Bus factor

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Let's assume there's Vasya on your project. Vasya knows everything about your infrastructure; what happens if he suddenly disappears? It's a very real situation, as he could get hit by a bus. Sometimes it happens. If that occurs and knowledge about the code, its structure, how it works, the login credentials, is not distributed within the team, then you may face a number of unpleasant situations. To minimize these risks and share knowledge within the team, various approaches can be used.

Pair DevOpsing

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

It's not like in the joke, where admins drank beer, changed passwords, and a parallel to pair programming. That is, two engineers sit at one computer, one keyboard, and start configuring your infrastructure together: setting up the server, writing Ansible roles, etc. Sounds great, but it didn't work for us. However, specific cases of this practice did work. A new employee comes in, their mentor takes a real task with them, they work together — passing on knowledge.

Another specific case is incident calls. During a problem, a group of on-duty and involved persons gathers, one leader is appointed, who shares their screen and verbalizes their thought process. Other participants follow the leader’s line of thought, peek at tricks from the console, check that a line in the log wasn’t missed, and learn something new about the system. This approach worked more often than not.

Code Review

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Subjectively, the more effective dissemination of knowledge about the infrastructure and how it is structured was done through code review:

  • The infrastructure is described in code in the repository.
  • Changes occur in a separate branch.
  • During a merge request, you can see the delta of changes in the infrastructure.

The highlight here was that reviewers were chosen in rotation, according to a schedule, meaning that with some probability, you would delve into a new part of the infrastructure.

Koodistiil

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Aja jooksul hakkasid arvustuste ajal tekkima erinevad arvamused, kuna arvustajatel oli oma stiil ja nende vaheldumisel sattusid nad kokku erinevate stiili valikutega: 2 tühikut või 4, camelCase või snake_case. Selle rakendamine ei õnnestunud kohe.

  • Esimene idee oli soovitada linter'i kasutamist, kuna kõik on ju insenerid, kõik on targad. Aga erinevad redigeerijad, operatsioonisüsteemid, see ei ole mugav.
  • See arenes botiks, mis igal probleemsel commit'il kirjutas Slack'i ja lisas linter'i väljundi. Aga enamasti oli rohkem tähtsamaid asju, ja kood jäi parandamata.

Roheline ehitusmeister

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Aeg möödub ja oleme jõudnud järeldusele, et ei saa lasta masterisse commite, mis ei läbi teatud teste. Voilà! Me leiutasime Roheline ehitusmeister, mis on juba ammu tarkvara arenduses praktiseeritud:

  • Arendustööd käivad eraldi harus.
  • Sellel harul käivad testid.
  • Kui testid ei läbi, siis kood ei pääse masterisse.

Selle otsuse vastuvõtmine oli väga raskendatud, kuna see põhjustas palju vaidlusi, kuid see oli seda väärt, kuna arvustustele hakkasid tulema liitumistaotlused, kus stiili üle ei vaieldud ja aja jooksul probleemsete kohtade arv hakkas vähenema.

IaC testimine

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Lisaks stiili kontrollimisele saab kasutada ka teisi asju, näiteks kontrollida, kas teie infrastruktuur tõepoolest suudab paigaldada. Või kontrollida, et infrastruktuuri muudatused ei tooda rahakaotust. Miks see võiks vajalik olla? Küsimus on keeruline ja filosoofiline, paremini vastata jutuga, et kunagi oli Powershell'i auto-skaleri, mis ei kontrollinud piirdeolukordi => loodi rohkem virtuaalmasinaid kui vajalik => klient kulutas rohkem raha, kui oli planeeritud. See ei olnud meeldiv, aga see viga oleks olnud täiesti võimalik varasemates etappides kinni püüda.

Võib küsida, miks teha keeruline infrastruktuur veelgi keerulisemaks? Infrastruktuuri testid, nagu ka koodile, ei ole lihtsustamise küsimus, vaid teadmine, kuidas teie infrastruktuur peaks töötama.

IaC testimise pyramida

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

IaC testimine: staatiline analüüs

Kui kohe paigaldatakse kogu infrastruktuur ja kontrollitakse, et see töötab, võib selguda, et see võtab tohutult aega ja nõuab palju ressursse. Seetõttu peaks aluseks olema midagi kiiret, mida on palju ja mis katab mitmeid primitiivseid kohti.

Bash on petlik

Vaatame üht banaalset näidet. Valige kõik failid praegusest kataloogist ja kopeerige need mujale. Esimene asi, 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 oleme ju targad, oskame kasutada jutumärke:

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

Tubli? Ei! Mis siis, kui kataloogis ei ole midagi, st globaalne otsing ei toimi.

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

Nüüd on tubli? Ei... Unustasime, 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üüsi tööriistad

Eelmise sammu probleemi oleks saanud tuvastada, kui oleksime unustanud jutumärgid, selleks on looduses palju vahendeid Shellcheck, neid on tõeliselt palju ja tõenäoliselt leiate oma IDE jaoks lintimise tööriista oma stack'i jaoks.

Keel
Tööriist

bash
Shellcheck

Ruby
RuboCop

python
Pylint

ansible
Ansible Lint

IaC Testimine: Üksuse Testid

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Kuidas me nägime eelmises näites, ei ole lintijad kõikvõimsad ja nad ei saa näidata kõiki probleemseid kohti. Jätkates sarnaselt tarkvaraarenduses testimisega, tuleb meelde unit testid. Siia tulevad kohe meelde shunit, junit, rspec, pytest. Aga mida siis teha ansible’i, chef’i, saltstack’i jms. jaoks?

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

  1. Infrastruktuur jaguneb väikesteks tellisteks, näiteks Ansible'i rollideks.
  2. Käivitub mingi keskkond, olgu see siis docker või virtuaalmasin.
  3. Sellele testkeskkonnale rakendame oma Ansible'i rolli.
  4. Kontrollime, et kõik töötas nagu ootame (teeme testid).
  5. Otsustame, kas on okei või ei.

IaC Testimine: Üksuse Testimise Tööriistad

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

CFM
Tööriist

Ansible
Testinfra

Chef
Inspec

Chef
Serverspec

saltstack
Goss

Näide testinfra jaoks, kontrollime, et kasutajad test1, test2 oleksid olemas ja kuuluksid gruppi 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 ei ole üheselt mõistetav, siin on näide muudatustest projektides github’is 2018-2019 aastal:

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

IaC Testimise Raamistikud

Kuidas kõik kokku panna ja käivitada? Võib võtta ja teha kõik ise olemasolevate inseneride piisava arvu korral. Või võib võtta valmis lahendused, ehkki neid ei ole just väga palju:

CFM
Tööriist

Ansible
Molecule

Chef
Test Kitchen

Terraform
Terratest

Näide muudatustest projektides github’is 2018-2019 aastal:

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 virtuaalmasin paralleelselt.
  2. Kasutage Ansible rolle.
  3. Käivitage inspec.

25-35 rolli puhul töötas see 40-70 minutit, mis oli liiga pikk aeg.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Järgmiseks sammuks oli üleminek jenkinsile / dockerile / ansible’ile / molecule’ile. Ideoloogiliselt on kõik sama.

  1. Lintige playbook’id.
  2. Lintige rollid.
  3. Käivitage konteiner.
  4. Kasutage Ansible rolle.
  5. Käivitage testinfra.
  6. Kontrollige idempotentsust.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

40 rolli lintimine ja kümnete testimine võttis aega umbes 15 minutit.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Valik sõltub paljuski mitmest tegurist, nagu kasutatav stekk, meeskonna ekspert ja nii edasi. Igaühel on enda viis, kuidas lahendada Unit testimise küsimus.

IaC Testimine: Integreerimistestid.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Järgmises infrastruktuuri testimise püramiidi astmes ilmuvad integreerimistestid. Need on sarnased Unit testidega:

  1. Infrastruktuur jaguneb väikesteks tükkideks, näiteks Ansible rollideks.
  2. Käivitub mingi keskkond, olgu see siis docker või virtuaalmasin.
  3. Selle testkeskkonna jaoks rakendatakse palju Ansible rolle.
  4. Kontrollime, et kõik toimis nagu ootasime (käivitame testid).
  5. Otsustame, kas on okei või ei.

Üldiselt ei kontrolli me eraldi süsteemi elemendi töökindlust nagu unit testides, vaid kontrollime, kuidas server on tervikuna kokku pandud.

IaC Testimine: Lõpp-lõpuks Testid.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Püramiidi tipus kohtame End to End teste. See tähendab, et me ei kontrolli eraldi serveri, eraldi skripti või eraldi infrastruktuuri tükki töökindlust. Me kontrollime, kuidas paljud serverid, mis on kokku liidetud, meie infrastruktuur töötab, nagu me ootasime. Kahjuks ei ole valmis lahendusi, mida olen näinud, tõenäoliselt seetõttu, et infrastruktuur on sageli ainulaadne ja seda on keeruline mallida ja luua raamistik selle testimiseks. Lõpptulemusena loovad kõik oma lahendused. Küsitlus on olemas, aga vastust ei ole. Seetõttu räägin sellest, mis on olemas, et innustada teisi mõtlema või suunata mind, et kõik, mida me varem ei avastanud, on juba leiutatud.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Projekt, millel on rikkalik ajalugu. Seda kasutatakse suurtes organisatsioonides ja tõenäoliselt olete teie kõigi kaudu olnud kaudselt seotud. Rakendus toetab mitmeid andmebaase, integratsiooni ja nii edasi. Teadmine, kuidas infrastruktuur võib välja näha, on palju docker-compose faile, ja teadmine, milliseid teste millistes keskkondades käivitada, on jenkins.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

See skeem töötas piisavalt kaua, kuni uuringud me üritasime seda viia Openshift’i. Konteinerid jäid samaks, kuid käituskeskkond muutus (tervitused D.R.Y.-le jälle).

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Uuringu mõte läks kaugemale ja OpenShiftis leiti selline asi nagu APB (Ansible Playbook Bundle), mis võimaldab pakkida teadmisi infrastruktuuri juurutamiseks konteinerisse. See tähendab, et olemas on reprodutseeritav ja testitav teadmiste punkt, kuidas infrastruktuuri seadistada.

Mida ma õppisin, testides 200 000 rida infrastruktuuri koodi

Kõik see kõlas hästi, kuni jäänud heterogeense infrastruktuuri taha: testimiseks on meil vajalik Windows. Lõpuks istub teadmine sellest, kuidas, kus ja millal juurutada ning testida, Jenkinsis.

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 veebimajutus DDoS-kaitsega veebisaitidele, VPS VDS serverid 🔥 Osta usaldusväärne veebimajutus DDoS-kaitsega veebisaitidele, VPS VDS serverid - ProHoster