.NET Core a Linux, DevOps a cavall

Hem desenvolupat DevOps com hem pogut. Érem 8 i en Vasya era el millor a Windows. De sobte, en Vasya se'n va anar i vaig tenir la tasca de llançar un nou projecte subministrat pel desenvolupament de Windows. Quan vaig abocar tota la pila de desenvolupament de Windows a la taula, em vaig adonar que la situació és un dolor...

Així comença la història Alexandra Sinchinova en DevOpsConf. Quan el principal especialista de Windows va deixar l'empresa, Alexander es va preguntar què havia de fer ara. Canvia a Linux, és clar! Alexander explicarà com va aconseguir crear un precedent i transferir part del desenvolupament de Windows a Linux utilitzant l'exemple d'un projecte implementat per a 100 usuaris finals.

.NET Core a Linux, DevOps a cavall

Com lliurar fàcilment un projecte a RPM mitjançant TFS, Puppet, Linux .NET core? Com mantenir la versió de la base de dades del projecte si el desenvolupament escolta les paraules Postgres i Flyway per primera vegada i la data límit és passat demà? Com integrar-se amb Docker? Com motivar els desenvolupadors de .NET perquè s'allunyin de Windows i els batuts en favor de Puppet i Linux? Com resoldre els conflictes ideològics si no hi ha força, ni ganes, ni recursos per servir Windows en producció? Sobre això, així com sobre Web Deploy, proves, CI, sobre les pràctiques d'ús de TFS en projectes existents i, per descomptat, sobre crosses trencades i solucions de treball, a la transcripció de l'informe d'Alexander.


Per tant, Vasya va marxar, la tasca és meva, els desenvolupadors estan esperant impacients amb forques. Quan finalment em vaig adonar que Vasya no podia ser retornat, em vaig posar a la feina. Per començar, vaig estimar el percentatge de Win VM a la nostra flota. La puntuació no era a favor de Windows.

.NET Core a Linux, DevOps a cavall

Com que estem desenvolupant activament DevOps, em vaig adonar que cal canviar alguna cosa en l'enfocament de treure una nova aplicació. Només hi havia una solució: si era possible, transferir-ho tot a Linux. Google em va ajudar: en aquell moment .Net ja s'havia portat a Linux i em vaig adonar que aquesta era la solució!

Per què .NET core juntament amb Linux?

Hi havia diverses raons per a això. Entre "pagar diners" i "no pagar", la majoria triarà aquest últim, com jo. Una llicència MSDB costa uns 1 dòlars, i el manteniment d'una flota de màquines virtuals de Windows arriba als centenars de dòlars. Per a una gran empresa, això suposa una gran despesa. Aixo es perqué estalvi - primer motiu. No és el més important, però sí un dels més significatius.

Les màquines virtuals de Windows ocupen més recursos que els seus germans Linux: són pesats. Donada la mida d'una gran empresa, vam triar Linux.

El sistema simplement s'integra en un CI existent. Ens considerem DevOps progressius, utilitzem Bamboo, Jenkins i GitLab CI, de manera que la majoria de nosaltres estem a Linux.

L'últim motiu és acompanyament convenient. Necessitava rebaixar el llindar d'entrada dels "mantenidors": nois que entenguin la part tècnica, garanteixin la continuïtat i donen servei des de la segona línia. Ja estaven familiaritzats amb la pila de Linux, de manera que els és molt més fàcil entendre el nou producte, donar-li suport i mantenir-lo, en lloc de gastar recursos addicionals per fer front a una funcionalitat de programari similar per a la plataforma Windows.

Requisits

Primer i abans que res - conveniència de la nova solució per als desenvolupadors. No tots estaven preparats per al canvi, sobretot després de la paraula parlada Linux. Els desenvolupadors volen el seu Visual Studio preferit, TFS amb autotests i batuts de creació. Com es fa el lliurament a la producció no és important per a ells. Per tant, vam decidir no canviar el procés habitual i deixar-ho tot sense canvis per al desenvolupament de Windows.

Necessites un nou projecte integrar a CI existent. Els rails ja hi eren i tota la feina s'havia de fer tenint en compte els paràmetres del sistema de gestió de la configuració, els estàndards de lliurament acceptats i els sistemes de seguiment.

Facilitat de manteniment i funcionament, com a condició per al llindar mínim d'entrada de tots els nous participants de diferents departaments i del departament de suport.

Termini - ahir.

Win equip de desenvolupament

Què feia llavors l'equip de Windows?

.NET Core a Linux, DevOps a cavall

Ara ho puc dir amb confiança IdentityServer 4 és una alternativa gratuïta a ADFS amb funcions similars, o el que sigui Entity Framework Core - un paradís per a desenvolupadors, on no us podeu molestar en escriure scripts SQL, sinó descriure consultes a la base de dades en termes de POO. Però després, quan vaig parlar del pla d'acció, vaig mirar aquesta pila com a cuneiforme sumeri, reconeixent només PostgreSQL i Git.

En aquell moment, vam utilitzar activament titella com a sistema de gestió de la configuració. En la majoria dels nostres projectes hem utilitzat GitLab CI, Elàstic, equilibrant serveis de gran càrrega utilitzant HAProxy va fer un seguiment de tot Zabbix, farcells Grafana и Prometeu, Jaeger, i tot això girava sobre trossos de ferro HPESXi en VMware. Tothom ho sap: un clàssic del gènere.

.NET Core a Linux, DevOps a cavall

Mirem i intentem entendre què va passar abans de començar totes aquestes intervencions.

Què va passar

TFS és un sistema bastant potent que no només lliura codi del desenvolupador a la màquina de producció final, sinó que també té un conjunt per a una integració molt flexible amb diversos serveis, per proporcionar CI a nivell multiplataforma.

.NET Core a Linux, DevOps a cavall
Anteriorment, eren ventilacions sòlides. TFS va utilitzar diversos agents de construcció que van crear molts projectes. Cada agent compta amb 3-4 treballadors per paral·lelitzar tasques i optimitzar el procés. A més, segons els plans de llançament, TFS va lliurar la compilació acabada de fer al servidor d'aplicacions de Windows.

On volíem anar

Utilitzem TFS per al lliurament i desenvolupament, i executem l'aplicació al servidor d'aplicacions Linux, i hi ha una mica de màgia entre ells. Això Caixa màgica i hi ha la sal de la feina per davant. Abans de desmuntar-lo, faré un pas al costat i diré unes paraules sobre l'aplicació.

Projecte

L'aplicació proporciona funcionalitat per gestionar targetes de prepagament.

.NET Core a Linux, DevOps a cavall

client

Hi havia dos tipus d'usuaris. Primer s'hi accedeix iniciant sessió amb un certificat SSL SHA-2. A les el segon s'ha accedit amb nom d'usuari i contrasenya.

HAProxy

A continuació, la sol·licitud del client va anar a HAProxy, que va resoldre les tasques següents:

  • autorització primària;
  • terminació de SSL;
  • ajustar les peticions HTTP;
  • demanar traducció.

La verificació del certificat del client va anar al llarg de la cadena. Nosaltres - autoritat i ens ho podem permetre, ja que nosaltres mateixos emetem certificats als clients del servei.

Fixeu-vos en el tercer punt, una mica més endavant hi tornarem.

Backend

El backend estava previst que es fes a Linux. El backend interactua amb la base de dades, carrega la llista de privilegis requerida i després, segons quins privilegis tingui l'usuari autoritzat, proporciona accés per signar documents financers i enviar-los per a la seva execució o generar algun tipus d'informe.

Estalvi amb HAProxy

A més dels dos contextos que caminava cadascun dels clients, també hi havia un context identitari. IdentityServer 4 només us permet iniciar sessió, aquest és un analògic gratuït i potent ADFS - Serveis de federació d’Active Directory.

La sol·licitud d'identitat es va processar en diversos passos. Primer pas - client va entrar al backend, que es va comunicar amb aquest servidor i va comprovar la presència d'un testimoni per al client. Si no la trobava, la sol·licitud tornava al context d'on provenia, però amb una redirecció, i amb una redirecció passava a la identitat.

El segon pas: la sol·licitud va rebre a la pàgina d'autorització a IdentityServer, on es va registrar el client i el testimoni tan esperat va aparèixer a la base de dades IdentityServer.

Tercer pas - client redirigit enrere al context d'on prové.

.NET Core a Linux, DevOps a cavall

IdentityServer4 té una característica: retorna la resposta a la sol·licitud de retorn mitjançant HTTP. No importa com ens havíem lluitat amb la configuració del servidor, per molt il·luminada que fos la documentació, cada vegada rebíem la sol·licitud inicial del client amb una URL que venia mitjançant HTTPS i IdentityServer retornava el mateix context, però amb HTTP. Ens vam sorprendre! I tot això ho vam transferir a través del context d'identitat a HAProxy, i a les capçaleres vam haver de modificar el protocol HTTP a HTTPS.

Quina és la millora i on us heu estalviat?

Hem estalviat diners utilitzant una solució gratuïta per autoritzar un grup d'usuaris, recursos, perquè no vam treure IdentityServer4 com a node separat en un segment separat, sinó que l'hem utilitzat juntament amb el backend del mateix servidor on s'executa el backend de l'aplicació. .

Com hauria de funcionar

Així que, com vaig prometre, la caixa màgica. Ja entenem que tenim la garantia d'avançar cap a Linux. Anem a formular les tasques específiques que calia resoldre.

.NET Core a Linux, DevOps a cavall

Manifest de titella. Per oferir i gestionar la configuració del servei i l'aplicació, calia escriure receptes interessants. El rotllo de llapis mostra eloqüentment amb quina rapidesa i eficàcia es va fer.

Mètode d'entrega. L'estàndard és RPM. Tothom entén que a Linux no hi ha manera sense això, però el projecte en si després del muntatge era un conjunt de fitxers DLL executables. Eren unes 150, el projecte és força pesat. L'única solució harmònica és empaquetar aquest binari a RPM i desplegar-ne l'aplicació.

Versioning. Vam haver de llançar molt sovint i vam haver de decidir com formar el nom del paquet. És una qüestió del nivell d'integració amb TFS. Teníem un agent de compilació a Linux. Quan TFS envia una tasca a un treballador -treballador- a l'agent de compilació, també li passa un munt de variables, que cauen a l'entorn del procés gestor. A aquestes variables d'entorn se'ls passa el nom de la compilació, el nom de la versió i altres variables. Llegiu més sobre això a la secció "creació d'un paquet RPM".

Configuració de TFS es va reduir a configurar Pipeline. Anteriorment, vam recopilar tots els projectes de Windows als agents de Windows i ara apareix un agent de Linux: un agent de compilació que s'ha d'incloure al grup de compilació, enriquit amb alguns artefactes, per dir quin tipus de projectes es crearan en aquest agent de compilació, i d'alguna manera modificar Pipeline.

IdentityServer. ADFS no és el nostre camí, ens ofeguem pel codi obert.

Passem pels components.

Caixa màgica

Consta de quatre parts.

.NET Core a Linux, DevOps a cavall

Agent de compilació de Linux. Linux, perquè construïm per a això, és lògic. Aquesta part es va fer en tres passos.

  • Establir treballadors i ni un, ja que es va assumir el treball distribuït del projecte.
  • Instal·leu .NET Core 1.x. Per què 1.x quan 2.0 ja està disponible al repositori estàndard? Perquè quan vam començar el desenvolupament, la versió estable era la 1.09, i es va decidir fer-ne el projecte.
  • Git 2.x.

Repositori RPM. Els paquets RPM s'havien d'emmagatzemar en algun lloc. Se suposa que havíem d'utilitzar el mateix dipòsit RPM corporatiu que està disponible per a tots els amfitrions Linux. I així ho van fer. El servidor del dipòsit està configurat webhook que va descarregar el paquet RPM requerit des de la ubicació especificada. L'agent de compilació va informar de la versió del paquet del webhook.

gitlab. Atenció! GitLab no és utilitzat aquí pels desenvolupadors, sinó pel departament d'operacions per controlar les versions d'aplicacions, versions de paquets, controlar l'estat de totes les màquines Linux i emmagatzemar la recepta: tots els manifestos de Puppet.

titella - resol tots els punts controvertits i ofereix exactament la configuració que volem de Gitlab.

Comencem a bussejar. Com es lliura la DLL a RPM?

Lliurament de DDL a RPM

Suposem que tenim una estrella de desenvolupament .NET. Utilitza Visual Studio i crea una branca de llançament. Després d'això, el carrega a Git, i Git aquí és una entitat TFS, és a dir, és el repositori d'aplicacions amb què treballa el desenvolupador.

.NET Core a Linux, DevOps a cavall

Aleshores, TFS veu que ha arribat un nou commit. Quina aplicació? A la configuració de TFS hi ha una etiqueta amb quins recursos té aquest o aquell agent de compilació. En aquest cas, veu que estem construint un projecte .NET Core i selecciona un agent Linux Build del grup.

Build-agent rep les fonts, descarrega el necessari dependències des del repositori .NET, npm, etc. i després de crear l'aplicació en si i el paquet posterior, envia el paquet RPM al repositori RPM.

D'altra banda, passa el següent. L'enginyer del departament d'operacions està directament implicat en el desplegament del projecte: canvia les versions dels paquets en Hiera al repositori on s'emmagatzema la recepta de l'aplicació, després de la qual s'activa Puppet yum, treu un paquet nou del repositori i la nova versió de l'aplicació està a punt per utilitzar-se.

.NET Core a Linux, DevOps a cavall

En paraules, tot és senzill, però què passa dins del propi agent Build?

Embalatge de RPM DLL

S'han rebut les fonts del projecte i la tasca de creació de TFS. Agent de construcció comença a construir el propi projecte a partir de fonts. El projecte muntat està disponible com a conjunt fitxers dll, que estan empaquetats en un arxiu zip per reduir la càrrega del sistema de fitxers.

S'ha llençat l'arxiu ZIP al directori de compilació del paquet RPM. A continuació, l'script Bash inicialitza les variables d'entorn, troba la versió de compilació, la versió del projecte, la ruta al directori de compilació i executa RPM-build. Quan s'ha completat la compilació, el paquet es publica a repositori local, que es troba a l'agent de compilació.

A més, des de l'agent de compilació fins al servidor del dipòsit RPM S'ha enviat la sol·licitud JSON amb el nom de la versió i la compilació. Webhook, que he esmentat anteriorment, baixa aquest mateix paquet del dipòsit local de l'agent de compilació i fa que la nova compilació estigui disponible per a la instal·lació.

.NET Core a Linux, DevOps a cavall

Per què aquest esquema per lliurar un paquet al repositori RPM? Per què no podeu enviar immediatament el paquet construït al repositori? El cas és que aquesta és una condició per garantir la seguretat. Aquest escenari limita la possibilitat que persones no autoritzades pugin paquets RPM a un servidor accessible per a totes les màquines Linux.

Versions de bases de dades

A la consulta de desenvolupament, va resultar que els nois estaven més a prop de MS SQL, però en la majoria de projectes que no són Windows ja vam fer servir PostgreSQL amb might i main. Com que ja hem decidit abandonar tot el que es paga, també hem començat a utilitzar PostgreSQL aquí.

.NET Core a Linux, DevOps a cavall

En aquesta part, vull explicar-vos com vam versionar la base de dades i com vam triar entre Flyway i Entity Framework Core. Considereu els seus pros i contres.

Contres

Flyway només va d'una manera, nosaltres no podem retrocedir és un desavantatge important. Podeu comparar amb Entity Framework Core d'altres maneres, en termes de comoditat per a desenvolupadors. Recordeu que això ho posem al capdavant, i el criteri principal era no canviar res pel desenvolupament de Windows.

Per a nosaltres cal algun tipus d'embolcallperquè els nois no escriguin Consultes SQL. Estan molt més a prop d'operar en termes de POO. Hem escrit instruccions per treballar amb objectes de base de dades, hem format una consulta SQL i hem executat. La nova versió de la base de dades està preparada, enrotllada: tot està bé, tot funciona.

Entity Framework Core té un inconvenient: sota càrregues pesades, això crea consultes SQL no òptimes, i la reducció de la base de dades pot ser important. Però com que no tenim un servei molt carregat, no calculem la càrrega en centenars de RPS, vam acceptar aquests riscos i vam delegar el problema al futur.

Pros

Entity Framework Core funciona fora de la caixa i és fàcil de desenvolupar, i Flyway s'integra fàcilment a CI existent. Però ho fem convenientment per als desenvolupadors :)

Procediment d'enrotllament

Puppet veu que ve un canvi en la versió dels paquets, entre els quals, el responsable de la migració. En primer lloc, instal·la un paquet que conté scripts de migració i funcionalitats relacionades amb la base de dades. Després d'això, es reinicia l'aplicació que funciona amb la base de dades. A continuació ve la instal·lació dels components restants. L'ordre en què s'instal·len els paquets i s'inicien les aplicacions es descriu al manifest de Puppet.

Les aplicacions utilitzen dades sensibles, com ara testimonis, contrasenyes de bases de dades, tot això s'inclou a la configuració des de Puppet Master, on s'emmagatzemen en forma xifrada.

Problemes de TFS

Després de decidir i adonar-nos que tot funciona realment per a nosaltres, vaig decidir veure què passava amb els muntatges a TFS en general per al departament de desenvolupament de Win en altres projectes, tant si anem / llançarem ràpidament com si no, i vaig trobar problemes significatius amb velocitat.

Un dels projectes principals serà de 12-15 minuts: és molt de temps, no es pot viure així. Una anàlisi ràpida va mostrar un terrible descens de l'E/S, i això és en matrius.

Després d'analitzar component per component, vaig identificar tres focus. Primer - antivirus kaspersky, que analitza les fonts a tots els agents de Windows Build. segon - Windows indexador. No es va desactivar i tot es va indexar als agents de compilació en temps real durant el procés de desplegament.

Tercer - instal·lació npm. Va resultar que a la majoria de pipelines vam utilitzar aquest escenari. Per què és dolent? El procediment d'instal·lació de Npm s'executa quan es construeix l'arbre de dependències package-lock.json, on es fixen les versions dels paquets que s'utilitzaran per construir el projecte. L'inconvenient és que Npm install treu les últimes versions de paquets d'Internet cada vegada, i això és molt de temps en el cas d'un projecte gran.

De vegades, els desenvolupadors experimenten en una màquina local per provar el rendiment d'una part concreta o d'un projecte sencer. De vegades va resultar que tot estava genial a nivell local, però ho van recollir, el van desplegar, res no va funcionar. Comencem a entendre quin és el problema: sí, diferents versions de paquets amb dependències.

decisió

  • Fonts en excepcions AV.
  • Desactiva la indexació.
  • Anar a npm ci.

L'avantatge de npm ci és que nosaltres recull l'arbre de dependències una vegada, i tenim l'oportunitat de proporcionar el desenvolupador llista actualitzada de paquets, amb la qual pot experimentar localment tant com vulgui. Això estalvia temps desenvolupadors que escriuen el codi.

Configuració

Ara una mica sobre la configuració del dipòsit. Històricament hem utilitzat Nexe per gestionar repositoris, inclòs REPO intern. Aquest repositori intern inclou tots els components que utilitzem amb finalitats internes, per exemple, el seguiment escrit per compte propi.

.NET Core a Linux, DevOps a cavall

També fem servir NuGet, ja que guarda a la memòria cau millor que altres gestors de paquets.

Resultat

Després d'optimitzar els agents de construcció, el temps mitjà de construcció es va reduir de 12 minuts a 7.

Si comptem totes les màquines que podríem utilitzar per a Windows, però canviem a Linux en aquest projecte, ens estalviem uns 10 dòlars, i això només és en llicències, i si inclou contingut, més.

Plans

Per al proper trimestre, teníem previst treballar per optimitzar el lliurament del codi.

Canvi a una imatge de Docker prèvia a la creació. TFS és una cosa fantàstica amb molts connectors que us permeten integrar-vos a Pipeline, inclosa la creació d'un activador, per exemple, una imatge de Docker. Volem fer aquest disparador al mateix package-lock.json. Si la composició dels components que s'utilitzen per construir el projecte canvia d'alguna manera, construïm una nova imatge de Docker. Més tard s'utilitza per desplegar el contenidor amb l'aplicació construïda. Ara no és així, però tenim previst canviar a una arquitectura de microservei a Kubernetes, que s'està desenvolupant activament a la nostra empresa i fa molt de temps que dóna servei a solucions de producció.

Resum

Demano a tothom que llenceu Windows, però no és perquè no el pugui cuinar. El motiu és que la majoria de solucions Opensource ho són pila de Linux. Ets bo estalviar recursos. Al meu entendre, el futur pertany a les solucions de codi obert a Linux amb una comunitat potent.

Perfil del ponent Alexander Sinchinov a GitHub.

DevOps Conf és una jornada sobre la integració de processos de desenvolupament, proves i operació per a professionals des de professionals. Per això el projecte del qual parlava Alexander? implementat i funcionant, i es van fer dos llançaments amb èxit el dia de l'actuació. Encès DevOps Conf a RIT++ Els dies 27 i 28 de maig encara hi haurà més casos d'aquest tipus per part dels practicants. Encara pots saltar a l'últim cotxe i Enviar un informe o no té pressa reservar bitllet. Ens veiem a Skolkovo!

Font: www.habr.com

Afegeix comentari