Aproape de Anul Nou. Copiii din întreaga țară și-au trimis deja scrisori lui Moș Crăciun sau și-au dorit cadouri, iar principalul lor executant — unul dintre marii retailerii — se pregătea pentru apogeul vânzărilor. În luna decembrie, încărcătura pe data center-ul său crește de câteva ori. De aceea, compania a decis să modernizeze centrul de date și să introducă în funcțiune câteva zeci de servere noi în locul echipamentului care își depășise termenul de utilizare. Aici se încheie povestea pe fondul fulgilor de zăpadă care se învârte, iar thrillerul începe.

Echipamentele au sosit pe locație cu câteva luni înainte de vârful vânzărilor. Serviciul de exploatare, bineînțeles, știe cum și ce să configureze pe servere pentru a le introduce în mediu de producție. Dar era necesar să automatizăm acest proces și să eliminăm factorul uman. Mai mult, serverele înlocuiau un set de sisteme SAP, extrem de importante pentru companie, înainte de migrare.
Punerea în funcțiune a noilor servere era strict legată de termenul limită. Și mutarea acestuia ar fi amenințat atât livrarea a miliardului de cadouri, cât și migrarea sistemelor. Data nu ar fi putut fi schimbată nici măcar de o echipă în care să se afle Moș Crăciun sau Sf. Nicolae — mutarea sistemului SAP pentru gestionarea stocurilor se poate face doar o dată pe an. În noaptea dintre 31 decembrie și 1 ianuarie, uriașele depozite ale retailerului, echivalente cu 20 de terenuri de fotbal, își opresc activitatea timp de 15 ore. Iar aceasta este singura fereastră de timp pentru migrarea sistemului. Nu aveam voie să greșim la introducerea serverelor.
Îmi voi explica imediat: povestea mea reflectă instrumentele și procesul de management al configurațiilor pe care le folosește echipa noastră.
Complexul de management al configurațiilor constă din mai multe niveluri. Componenta cheie este sistemul CMS. În exploatarea industrială, lipsa unuia dintre niveluri ar duce inevitabil la minuni neplăcute.
Managementul instalării OS
Primul nivel este sistemul de management al instalării sistemelor de operare pe servere fizice și virtuale. Acesta creează configurații de bază pentru sistemele de operare, eliminând factorul uman.
Prin această sistemă, am obținut instanțe standardizate și pregătite pentru automatizare a serverelor cu sistem de operare. La „distribuire”, acestea au primit un set minim de utilizatori locali și chei publice SSH, precum și o configurație de sistem de operare coerentă. Am putut gestiona serverele prin intermediul CMS și eram siguri că, la nivel de sistem de operare, nu există surprize.
Sarcina „maximă” pentru sistemul de gestionare a instalării este de a configura automat serverele de la nivelul BIOS/Firmware până la sistemul de operare. Multe aici depind de hardware și de cerințele de configurare. Pentru hardware heterogen se poate considera . Dacă tot hardware-ul provine de la un singur furnizor, este adesea mai convenabil să folosești instrumente de gestionare deja existente (de exemplu, HP ILO Amplifier, DELL OpenManage etc.).
Pentru instalarea sistemului de operare pe servere fizice, am folosit Cobbler, bine cunoscut tuturor, în care este definit un set de profiluri de instalare coerente cu serviciul de operare. Atunci când se adaugă un nou server în infrastructură, inginerul leagă adresa MAC a serverului de profilul necesar în Cobbler. La prima pornire prin rețea, serverul primește o adresă temporară și un sistem de operare proaspăt. Apoi, este mutat în VLAN/IP-uri țintă și continuăm activitatea acolo. Da, schimbarea VLAN-ului durează și necesită coordonare, dar aduce o protecție suplimentară împotriva instalării accidentale a serverului în mediu de producție.
Serverele virtuale le-am creat pe baza șabloanelor pregătite cu ajutorul HashiCorp Packer. Motivul a fost același: pentru a preveni posibilele erori umane în instalarea sistemului de operare. Dar, spre deosebire de serverele fizice, Packer permite să nu folosim PXE, bootare rețea și schimbare de VLAN. Acest lucru a simplificat și ușurat crearea serverelor virtuale.

Fig. 1. Gestionarea instalării sistemelor de operare.
Gestionarea secretelor
Orice sistem de gestionare a configurațiilor conține date care trebuie să fie ascunse de utilizatorii de rând, dar sunt necesare pentru pregătirea sistemelor. Acestea includ parolele utilizatorilor locali și conturilor de serviciu, cheile certificatelor, diverse API Tokens etc. De obicei, acestea sunt numite „secrete”.
Dacă de la început nu se determină unde și cum să fie stocate aceste secrete, atunci, în funcție de strictețea cerințelor de securitate a informației, sunt posibile următoarele metode de stocare:
- directly in the configuration management code or in files in the repository;
- in specialized configuration management tools (e.g., Ansible Vault);
- in CI/CD systems (Jenkins/TeamCity/GitLab/etc.) or in configuration management systems (Ansible Tower/Ansible AWX);
- also secrets can be passed on 'manual management'. For example, placing them in an agreed location, which are then used by configuration management systems;
- various combinations of the above.
Each method has its downsides. The main one is the lack of access policies for secrets: it's impossible or difficult to determine who can use which secrets. Another disadvantage is the absence of access audit and a full lifecycle. How quickly can we replace a public key, for instance, that is hard-coded and used across several related systems?
We used the centralized secrets storage HashiCorp Vault. This allowed us to:
- store secrets securely. They are encrypted, and even if someone gains access to the Vault storage database (for instance, by restoring it from a backup), they won’t be able to read the secrets stored there;
- organize access policies for secrets. Users and applications can only access the 'dedicated' secrets assigned to them;
- perform access audits for secrets. Any actions taken with secrets are logged in the Vault audit log;
- organize a full 'lifecycle' for working with secrets. They can be created, revoked, set with expiration dates, etc.
- easily integrate with other systems needing access to secrets;
- and also apply end-to-end encryption, one-time passwords for OS and DB, certificates from authorized centers, etc.
Now let's move on to the central authentication and authorization system. It could have been done without it, but managing users across numerous related systems is too non-trivial. We set up authentication and authorization through the LDAP service. Otherwise, in the same Vault, we would have to constantly issue and track authentication tokens for users. Adding and removing users would turn into the quest: 'did I create/delete this user everywhere?'
We add another level to our system: secret management and central authentication/authorization:

Fig. 2. Secret management.
Gestionarea configurațiilor
Am ajuns la esența sistemului CMS. În cazul nostru, este vorba despre combinația Ansible și Red Hat Ansible AWX.
În loc de Ansible, pot fi folosite Chef, Puppet, SaltStack. Am ales Ansible pe baza mai multor criterii.
- În primul rând, este versatilitate. Setul de module gata pregătite pentru gestionare . Iar dacă nu este suficient, poți căuta pe GitHub și Galaxy.
- În al doilea rând, nu este necesar să instalezi și să întreții agenți pe echipamentele gestionate, să demonstrezi că nu afectează încărcătura și să confirmi absența "backdoor-urilor".
- În al treilea rând, Ansible are un prag de acces scăzut. Un inginer competent poate scrie un playbook funcțional în prima zi de utilizare a produsului.
Însă, doar Ansible în medii industriale nu era suficient pentru noi. Alte probleme legate de restricționarea accesului și auditul acțiunilor administratorilor ar fi apărut. Cum să delimităm accesul? Fiindcă era necesar ca fiecare departament să gestioneze (adică – să ruleze playbook-uri Ansible) un set propriu de servere. Cum să permită execuția unor playbook-uri Ansible doar anumitor angajați? Sau cum să urmărească cine a rulat un playbook, fără a crea multe conturi locale pe servere și echipamente gestionate prin Ansible?
Majoritatea acestor întrebări sunt rezolvate de Red Hat , sau proiectul său open-source upstream . De aceea l-am preferat pentru client.
Și un alt detaliu despre portretul sistemului nostru CMS. Playbook-ul Ansible trebuie să fie păstrat în sistemele de gestionare a repository-ului de cod. La noi, acest lucru este realizat cu ajutorul .
Deci, configurațiile sunt gestionate de combinația Ansible/Ansible AWX/GitLab (vezi Fig. 3). Desigur, AWX/GitLab sunt integrate cu un sistem unic de autentificare, iar playbook-ul Ansible este integrat cu HashiCorp Vault. Configurațiile ajung în medii de producție doar prin Ansible AWX, în care sunt stabilite toate "regulile jocului": cine și ce poate configura, de unde să obțină codul pentru gestionarea configurațiilor pentru CMS etc.

Fig. 3. Gestionarea configurațiilor.
Gestionarea testării
Configurația noastră este prezentată sub formă de cod. Prin urmare, trebuie să respectăm aceleași reguli ca dezvoltatorii de software. A fost necesar să organizăm procesele de dezvoltare, testare continuă, livrare și aplicare a codului de configurație pe serverele de producție.
Dacă acest lucru nu este realizat imediat, atunci rolurile scrise pentru configurație ar înceta să fie suportate și actualizate sau nu ar mai rula în producție. Remediul pentru această problemă este cunoscut și s-a dovedit eficient în acest proiect:
- fiecare rol este acoperit de teste modulare;
- teste sunt rulate automat la fiecare modificare a codului care gestionează configurațiile;
- modificările din codul de gestionare a configurațiilor ajung în mediu de producție doar după ce toate testele au fost trecute cu succes și după revizuirea codului.
Dezvoltarea codului și gestionarea configurațiilor au devenit mai calme și previzibile. Pentru a organiza testarea continuă, am folosit instrumentul GitLab CI/CD, iar framework-ul pentru organizarea testelor a fost .
La orice modificare în codul de gestionare a configurațiilor, GitLab CI/CD apelează Molecule:
- care verifică sintaxa codului,
- lancează un container Docker,
- aplică codul modificat în containerul creat,
- verifică rolul pentru idempotentă și rulează teste pentru acest cod (granularitatea aici este la nivelul rolului ansible, vezi Fig. 4).
Configurările în mediu de producție erau livrate cu ajutorul Ansible AWX. Inginerii responsabili de exploatare aplicau modificările din configurație prin șabloane predefinite. AWX cerea de fiecare dată, la aplicare, cea mai recentă versiune a codului din ramura principală GitLab. Astfel, am exclus utilizarea codului nevalidat sau învechit în mediu de producție. Este evident că codul ajungea în ramura principală doar după testare, revizuire și aprobat.

Fig. 4. Testarea automată a rolurilor în GitLab CI/CD.
Este o altă problemă legată de exploatarea sistemelor de producție. În viața reală, este foarte dificil să faci modificări în configurație doar prin codul CMS. Apar situații neprevăzute, când inginerul trebuie să schimbe configurația „aici și acum”, fără a aștepta corectarea codului, testarea, aprobatul etc.
Ca urmare, din cauza modificărilor manuale apar discrepanțe în configurațiile pe echipamente similare (de exemplu, pe noduri HA, configurația setărilor sysctl este diferită). Sau configurația reală de pe echipament diferă de cea specificată în codul CMS.
Așadar, pe lângă testarea continuă, verificăm mediile de producție pentru a detecta abateri de configurație. Am ales cea mai simplă opțiune: rularea codului de configurație CMS în modul „dry run”, adică fără aplicarea modificărilor, dar cu notificări despre toate abaterile între configurația planificată și cea reală. Am implementat acest lucru prin rulări periodice ale tuturor playbook-urilor Ansible cu opțiunea „—check” pe serverele de producție. De rularea și actualitatea playbook-ului se ocupă, ca întotdeauna, Ansible AWX (vezi Fig. 5):

Fig. 5. Verificări pentru abateri de configurație în Ansible AWX.
După verificările AWX, se trimite un raport despre abateri administratorilor. Aceștia analizează configurația problematică și apoi o corectează prin playbook-uri ajustate. Astfel, menținem configurația în mediul de producție, iar CMS este întotdeauna actualizat și sincronizat. Aceasta ne scutește de neplăcerile „minunilor” care apar atunci când codul CMS este aplicat pe servere „de producție”.
Acum avem un nivel important de testare, format din Ansible AWX/GitLab/Molecule (Fig. 6).

Fig. 6. Managementul testării.
Difficult? I don't dispute it. However, this comprehensive configuration management system has become an exhaustive answer to many questions related to server configuration automation. Now, the retailer's standard servers always have a strictly defined configuration. The CMS, unlike an engineer, will not forget to add the necessary settings, create users, and perform dozens or hundreds of required configurations.
În setările serverelor și medii nu există astăzi „cunoștințe secrete”. Toate caracteristicile necesare sunt reflectate în playbook. Nu mai există creativitate și instrucțiuni vagi: „instalează ca un Oracle obișnuit, dar trebuie să scrii câteva setări sysctl și să adaugi utilizatorii cu UID-ul corect. Întreabă-i pe cei din exploatare, ei știu.».
Posibilitatea de a detecta abaterile de configurație și de a le corecta anticipat oferă liniște. Fără un sistem de management al configurațiilor, acest proces arăta de obicei diferit. Problemele se acumulează până când, într-o zi, „explodează” în producție. Apoi are loc o analiză a incidentelor, se verifică și se corectează configurațiile. Și ciclul se repetă din nou.
Și, desigur, am redus timpul de punere în funcțiune a serverelor de la câteva zile la câteva ore.
În noaptea de Anul Nou, când copiii deschideau fericiți cadourile iar adulții își puneau dorințe sub sunetul clopotelor, inginerii noștri au migrat sistemul SAP pe servere noi. Chiar și Moș Crăciun va spune că cele mai frumoase minuni sunt cele bine pregătite.
P.S. Echipa noastră se confruntă adesea cu clienți care doresc să rezolve cât mai simplu sarcina de gestionare a configurațiilor. Ideal ar fi să fie ca prin magie — cu un singur instrument. Dar în realitate, lucrurile sunt mai complicate (da, din nou nu au adus gloanțe de argint): trebuie să creăm un întreg proces folosind instrumente convenabile pentru echipa clientului.
Autor: Serghei Artiomov, arhitect al departamentului «Infosisteme Jet»
Sursa: habr.com
