.NET Core en Linux, DevOps a caballo

Desarrollamos DevOps como pudimos. 脡ramos 8, y Vasya era la mejor de Windows. De repente, Vasya se fue, y tuve la tarea de presentar un nuevo proyecto que proporciona el desarrollo de Windows. Cuando vert铆 toda la pila de desarrollo de Windows sobre la mesa, me di cuenta de que la situaci贸n es una molestia ...

As铆 comienza la historia de Alexander Sinchinov en DevOpsConf . Cuando el especialista l铆der en Windows dej贸 la empresa, Alexander se pregunt贸 qu茅 hacer ahora. 隆Cambie a Linux, por supuesto! Alexander contar谩 c贸mo logr贸 establecer un precedente y transferir parte del desarrollo de Windows a Linux usando el ejemplo de un proyecto completado para 100,000 usuarios finales.



驴C贸mo entregar f谩cilmente y sin esfuerzo un proyecto a RPM usando TFS, Puppet, Linux .NET core? 驴C贸mo mantener el control de versiones de la base de datos del proyecto si el desarrollo primero escucha las palabras Postgres y Flyway, y la fecha l铆mite pasado ma帽ana? 驴C贸mo integrarse con Docker? 驴C贸mo motivar a los desarrolladores de .NET a abandonar Windows y los smoothies en favor de Puppet y Linux? 驴C贸mo resolver los conflictos ideol贸gicos, si no hay fuerzas, ni deseos, ni recursos para servir a Windows en la producci贸n? Sobre esto, as铆 como sobre Web Deploy, pruebas, CI, sobre las pr谩cticas de uso de TFS en proyectos existentes y, por supuesto, sobre muletas rotas y soluciones de trabajo, en la decodificaci贸n del informe de Alexander.


Entonces, Vasya se fue, la tarea es para m铆, los desarrolladores est谩n esperando con una horca . Cuando finalmente me di cuenta de que Vasya no pod铆a ser devuelta, me puse manos a la obra. Para empezar, calcul茅 el porcentaje de Win VM en nuestro parque. El puntaje no estaba a favor de Windows.



Dado que estamos desarrollando DevOps activamente, me di cuenta de que hay que cambiar algo en el enfoque de sacar una nueva aplicaci贸n. La soluci贸n fue una: si es posible, transfiera todo a Linux. Google me ayud贸: en ese momento .Net ya estaba portado a Linux, 隆y me di cuenta de que esta soluci贸n!

驴Por qu茅 se incluye .NET core con Linux?


Hubo varias razones para esto. Entre "pagar dinero" y "no pagar", la mayor铆a elegir谩 el segundo, como yo. Una licencia para MSDB cuesta alrededor de $ 1,000; el mantenimiento de una flota de m谩quinas virtuales de Windows cuesta cientos de d贸lares. Para una gran empresa, este es un gran gasto. Por lo tanto, el ahorro es la primera raz贸n . No es el m谩s importante, pero s铆 uno de los m谩s importantes.

Las m谩quinas virtuales de Windows ocupan m谩s recursos que sus hermanos Linux: son pesadas . Dada la escala de una gran empresa, elegimos Linux.

El sistema simplemente est谩 integrado en el CI existente . Nos consideramos DevOps progresivos, utilizamos Bamboo, Jenkins y GitLab CI, por lo que la mayor parte de nuestro trabajo est谩 en Linux.

La 煤ltima raz贸n es la escolta conveniente. Tuvimos que bajar el umbral de entrada para los "acompa帽antes", chicos que entienden la parte t茅cnica, aseguran una operaci贸n ininterrumpida y servicios de servicio desde la segunda l铆nea. Ya estaban familiarizados con la pila de Linux, por lo que les resulta mucho m谩s f谩cil comprender el nuevo producto, mantenerlo y mantenerlo, que gastar recursos adicionales para lidiar con la funcionalidad similar del software para la plataforma Windows.

Requisitos


En primer lugar, la conveniencia de una nueva soluci贸n para desarrolladores . No todos estaban listos para el cambio, especialmente despu茅s de la palabra hablada Linux. Los desarrolladores quieren su querido Visual Studio, TFS con pruebas de compilaci贸n y batidos. C贸mo se realiza la entrega en la producci贸n: no les importa. Por lo tanto, decidimos no cambiar el proceso habitual y dejar todo sin cambios para el desarrollo de Windows.

El nuevo proyecto debe integrarse en el CI existente . Los rieles ya estaban all铆 y todo el trabajo deb铆a hacerse teniendo en cuenta los par谩metros del sistema de gesti贸n de la configuraci贸n, los est谩ndares de entrega aceptados y los sistemas de monitoreo.

Simplicidad en soporte y operaci贸n , como condici贸n para un umbral m铆nimo de entrada para todos los nuevos participantes de diferentes departamentos y departamento de soporte.

Plazo - ayer .

Gana el grupo de desarrollo


驴Con qu茅 trabaj贸 entonces el equipo de Windows?



Ahora puedo decir con confianza que IdentityServer4 es una excelente alternativa gratuita a ADFS con capacidades similares, o que Entity Framework Core es el para铆so de los desarrolladores donde no puede molestarse en escribir scripts SQL, sino describir consultas en la base de datos en t茅rminos OOP. Pero luego, cuando discut铆 el plan de acci贸n, vi esta pila como una escritura cuneiforme sumeria que reconoce solo PostgreSQL y Git.

En ese momento, utilizamos activamente Puppet como un sistema de gesti贸n de configuraci贸n. En la mayor铆a de nuestros proyectos, utilizamos GitLab CI , Elastic , servicios balanceados altamente cargados usando HAProxy, monitoreamos todo con Zabbix , un mont贸n de Grafana y Prometheus , Jaeger , y todo esto giraba en el hardware de HP con ESXi en VMware . Todos lo saben: un cl谩sico del g茅nero.



Miremos e intentemos comprender lo que sucedi贸 antes de comenzar todas estas intervenciones.

Que fue


TFS es un sistema bastante poderoso que no solo entrega c贸digo del desarrollador a la m谩quina de producci贸n final, sino que tambi茅n tiene un conjunto para una integraci贸n muy flexible con varios servicios, para proporcionar CI a nivel multiplataforma.


Anteriormente, se trataba de ventanas s贸lidas. TFS utiliz贸 varios agentes de Build, que reunieron muchos proyectos. Cada agente tiene de 3 a 4 trabajadores, uno para paralelizar tareas y optimizar el proceso. Adem谩s, de acuerdo con los planes de lanzamiento, TFS entreg贸 el Build reci茅n horneado al servidor de aplicaciones de Windows.

A lo que quer铆amos llegar


Para la entrega y el desarrollo, utilizamos TFS, y lanzamos la aplicaci贸n en el servidor de aplicaciones de Linux, y hay alg煤n tipo de magia entre ellos. Esta caja m谩gica es la sal del pr贸ximo trabajo. Antes de desarmarlo en partes, dar茅 un paso al costado y dir茅 dos palabras sobre la aplicaci贸n.

Proyecto


La aplicaci贸n proporciona funcionalidad para manejar tarjetas prepagas.



Cliente


Hab铆a dos tipos de usuarios. El primero obtuvo acceso iniciando sesi贸n con el certificado SSL SHA-2. El segundo tuvo acceso por usuario y contrase帽a.

HAProxy


Adem谩s, la solicitud del cliente cay贸 en HAProxy, que resolvi贸 las siguientes tareas:

  • autorizaci贸n primaria;
  • Terminaci贸n SSL
  • ajuste de solicitudes HTTP;
  • Difundir solicitudes.

La verificaci贸n del certificado del cliente pas贸 por la cadena. Somos autoridad y podemos pagarla, ya que nosotros mismos emitimos certificados para atender a los clientes.

Presta atenci贸n al tercer punto, un poco m谩s tarde volveremos a 茅l.

Backend


Planearon hacer un backend en Linux. El backend interact煤a con la base de datos, carga la lista necesaria de privilegios y luego, dependiendo de los privilegios que tenga el usuario autorizado, proporciona acceso para firmar documentos financieros y enviarlos para su ejecuci贸n, o generar alg煤n tipo de informe.

Ahorro con HAProxy


Adem谩s de los dos contextos por los que sol铆a pasar cada cliente, tambi茅n hab铆a un contexto de identidad. IdentityServer4 simplemente le permite iniciar sesi贸n, es un an谩logo gratuito y potente para ADFS - Servicios de federaci贸n de Active Directory .

La solicitud de identidad se proces贸 en varios pasos. El primer paso: el cliente cay贸 en el backend , que intercambi贸 datos con este servidor y verific贸 la presencia de un token para el cliente. Si no lo encontraba, la solicitud regresaba al contexto del que proven铆a, pero con una redirecci贸n y con una redirecci贸n fue a identidad.

El segundo paso: la solicitud fue a la p谩gina de autenticaci贸n en IdentityServer, donde estaba registrado el cliente, y el token muy esperado apareci贸 en la base de datos de IdentityServer.

El tercer paso: el cliente redirigi贸 de nuevo al contexto del que vino.



IdentityServer4 tiene una peculiaridad: devuelve la respuesta a la solicitud de devoluci贸n a trav茅s de HTTP . No importa c贸mo tuvimos problemas con la configuraci贸n del servidor, no importa c贸mo nos iluminamos con la documentaci贸n, cada vez que recibimos una solicitud inicial del cliente con una URL que vino a trav茅s de HTTPS, e IdentityServer devolvi贸 el mismo contexto, pero con HTTP. Est谩bamos en estado de shock! Y todo esto se transfiri贸 a trav茅s del contexto de identidad a HAProxy, y en los encabezados tuvimos que modificar el protocolo HTTP a HTTPS.

驴Cu谩l es la mejora y d贸nde ahorraron?

Ahorramos dinero mediante el uso de una soluci贸n gratuita para autorizar a un grupo de usuarios, recursos, ya que no tomamos IdentityServer4 como una nota separada en un segmento separado, sino que lo usamos junto con un back-end en el mismo servidor donde est谩 girando el backend de la aplicaci贸n.

C贸mo deber铆a funcionar


Entonces, como promet铆, Magic Box. Ya entendemos que estamos garantizados para avanzar hacia Linux. Formulemos tareas espec铆ficas que requieran soluciones.



T铆teres se manifiesta. Para entregar y administrar la configuraci贸n del servicio y la aplicaci贸n, ten铆a que escribir recetas geniales. Un rollo de l谩piz muestra elocuentemente qu茅 tan r谩pido y eficientemente se hizo esto.

M茅todo de entrega El est谩ndar es RPM. Todos entienden que en Linux no hay forma de hacerlo sin 茅l, pero el proyecto en s铆 mismo despu茅s del ensamblaje era un conjunto de archivos DLL ejecutables. Hubo alrededor de 150 de ellos, el proyecto es bastante dif铆cil. La 煤nica soluci贸n armoniosa es empacar estos binarios en RPM e implementar la aplicaci贸n desde all铆.

Versionado Ten铆amos que lanzarlo muy a menudo y ten铆amos que decidir c贸mo formar el nombre del paquete. Esta es una cuesti贸n de nivel de integraci贸n TFS. Ten铆amos un agente de compilaci贸n en Linux. Cuando TFS env铆a la tarea al controlador - trabajador - al agente Build, tambi茅n le env铆a un grupo de variables que caen en el entorno del proceso del controlador. Estas variables de entorno reciben el nombre Build, el nombre de la versi贸n y otras variables. Lea m谩s sobre esto en la secci贸n "Ensamblar un paquete RPM".

La configuraci贸n de TFS se redujo a la configuraci贸n de Pipeline. Anteriormente, recopilamos todos los proyectos de Windows en los agentes de Windows, y ahora hay un agente de Linux: un agente de compilaci贸n que debe incluirse en el grupo de ensamblaje, enriquecido con algunos artefactos, indicar qu茅 tipo de proyectos se construir谩n en este agente de compilaci贸n, y de alguna manera modificar Pipeline.

IdentityServer. ADFS no es nuestro camino, nos ahogamos para Open Source.

Veamos los componentes.

Caja m谩gica


Consta de cuatro partes.



Agente de compilaci贸n de Linux. Linux, porque lo compilamos, es l贸gico. Esta parte se llev贸 a cabo en tres pasos.

  • Configurar trabajadores y m谩s de uno, ya que se asumi贸 el trabajo distribuido en el proyecto.
  • Instale .NET Core 1.x. 驴Por qu茅 1.x cuando 2.0 ya est谩 disponible en el repositorio est谩ndar? Porque cuando comenzamos el desarrollo, la versi贸n estable era 1.09, y se decidi贸 hacer el proyecto para ello.
  • Git 2.x.

Repositorio RPM. Los paquetes RPM deb铆an almacenarse en alg煤n lugar. Se asumi贸 que usar铆amos el mismo repositorio RPM corporativo que est谩 disponible para todos los hosts Linux. Y as铆 lo hicieron. Se configura un webhook en el servidor de repositorio que descarg贸 el paquete RPM requerido desde la ubicaci贸n especificada. El agente de Build inform贸 la versi贸n del paquete al webhook.

Gitlab Atencion GitLab es utilizado aqu铆 no por desarrolladores, sino por el departamento de operaciones para controlar versiones de aplicaciones, versiones de paquetes, monitorear el estado de todas las m谩quinas Linux y almacena la receta, todos los manifiestos de Puppet.

Puppet : resuelve todos los problemas controvertidos y ofrece exactamente la configuraci贸n que queremos de Gitlab.

Comenzamos a bucear. 驴C贸mo se entrega DLL en RPM?

Entrega DDL a RPM


Digamos que tenemos una estrella de rock para el desarrollo .NET. Utiliza Visual Studio y crea una rama de lanzamiento. Despu茅s de eso, lo carga en Git, y Git aqu铆 es una entidad TFS, es decir, es el repositorio de aplicaciones con el que trabaja el desarrollador.



Despu茅s de lo cual TFS ve que ha llegado una nueva confirmaci贸n. Cual aplicaci贸n? En la configuraci贸n de TFS hay una etiqueta sobre los recursos que tiene un agente de compilaci贸n en particular. En este caso, ve que estamos creando un proyecto .NET Core y seleccionando un agente de compilaci贸n de Linux del grupo.

El agente de compilaci贸n recibe las fuentes, descarga las dependencias necesarias de .NET, el repositorio npm, etc. y despu茅s de compilar la aplicaci贸n y el empaquetado posterior, env铆a el paquete RPM al repositorio RPM.

Por otro lado, ocurre lo siguiente. El ingeniero de mantenimiento participa directamente en la implementaci贸n del proyecto: cambia la versi贸n de los paquetes en Hiera en el repositorio donde se almacena la receta de la aplicaci贸n, despu茅s de lo cual Puppet activa Yum , recoge el nuevo paquete del repositorio y la nueva versi贸n de la aplicaci贸n est谩 lista para su uso.



En palabras, todo es simple, pero 驴qu茅 sucede dentro del propio agente de compilaci贸n?

Empaquetado RPM DLL


Se recibieron las fuentes del proyecto y la tarea de compilaci贸n de TFS. El agente de compilaci贸n comienza a compilar el proyecto desde el origen . El proyecto ensamblado est谩 disponible en forma de muchos archivos DLL que se empaquetan en un archivo zip para reducir la carga en el sistema de archivos.

El archivo ZIP se arroja al directorio de compilaci贸n del paquete RPM. A continuaci贸n, el script Bash inicializa las variables de entorno, encuentra la versi贸n de compilaci贸n, la versi贸n del proyecto, la ruta al directorio de compilaci贸n y lanza la compilaci贸n RPM. Al final del ensamblaje, el paquete se publica en el repositorio local , que se encuentra en el agente de compilaci贸n.

Adem谩s, se env铆a una solicitud JSON desde el agente de compilaci贸n al servidor en el repositorio RPM con el nombre de la versi贸n y la compilaci贸n. Webhook, sobre el que habl茅 antes, descarga este mismo paquete desde el repositorio local en el agente de compilaci贸n y hace que el nuevo ensamblaje est茅 disponible para la instalaci贸n.



驴Por qu茅 tal esquema para entregar un paquete a un repositorio RPM? 驴Por qu茅 no puedo enviar inmediatamente el paquete ensamblado al repositorio? El hecho es que esta es una condici贸n para la seguridad. Este escenario restringe la posibilidad de descargas no autorizadas de paquetes RPM por parte de personas externas a un servidor que sea accesible para todas las m谩quinas Linux.

Control de versiones de DB


En la consulta con el desarrollo, result贸 que los chicos est谩n m谩s cerca de MS SQL, pero en la mayor铆a de los proyectos que no son de Windows ya usamos PostgreSQL con might y main. Como ya decidimos abandonar todo lo pagado, comenzamos a usar PostgreSQL aqu铆.



En esta parte, quiero hablar sobre c贸mo implementamos el control de versiones de la base de datos y c贸mo elegir entre Flyway y Entity Framework Core. Considere sus pros y sus contras.

Contras


Flyway va solo en un sentido, no podemos retroceder , este es un significativo menos. La comparaci贸n con Entity Framework Core se puede realizar de acuerdo con otros par谩metros, desde el punto de vista de la conveniencia del desarrollador. Recuerda que pusimos esto a la vanguardia, y el criterio principal era no cambiar nada para el desarrollo de Windows.

Para Flyway, necesit谩bamos alg煤n tipo de contenedor para que los chicos no escribieran consultas SQL . Est谩n mucho m谩s cerca de operar en t茅rminos de POO. Escribimos instrucciones para trabajar con objetos de base de datos, formamos una consulta SQL y la ejecutamos. La nueva versi贸n de la base de datos est谩 lista, enrollada: todo est谩 bien, todo funciona.

Entity Framework Core tiene un signo negativo: bajo cargas pesadas, no genera consultas SQL 贸ptimas , y la reducci贸n de la base de datos puede ser significativa. Pero como no tenemos un servicio de alta carga, no calculamos la carga en cientos de RPS, tomamos estos riesgos y delegamos el problema en el futuro.

Pros


Entity Framework Core funciona de forma inmediata y es f谩cil de desarrollar , y Flyway se integra a la perfecci贸n en los CI existentes . Pero lo hacemos convenientemente para desarrolladores :)

Procedimiento de enrollado


Puppet ve que hay un cambio en la versi贸n de los paquetes, entre los cuales se encuentra el responsable de la migraci贸n. Primero, instala un paquete que contiene scripts de migraci贸n y funcionalidad vinculada a la base de datos. Despu茅s de eso, se reinicia la aplicaci贸n que funciona con la base de datos. Lo siguiente es la instalaci贸n de los componentes restantes. El orden en que se instalan los paquetes y se inician las aplicaciones se describe en el manifiesto de Puppet.

Las aplicaciones usan datos confidenciales, como tokens, contrase帽as para la base de datos, todo esto se incorpora a la configuraci贸n con el Puppet master, donde se almacenan en forma cifrada.

Problemas de TFS


Despu茅s de decidir y darnos cuenta de que todo realmente funciona para nosotros, decid铆 ver qu茅 suced铆a con los ensamblajes en TFS en su conjunto para el departamento de desarrollo de Win para otros proyectos: r谩pidamente o no, 铆bamos a / lanzamiento, y encontramos problemas significativos con la velocidad .

Uno de los principales proyectos tomar谩 entre 12 y 15 minutos: es mucho tiempo, no puedes vivir as铆. Un an谩lisis r谩pido mostr贸 una reducci贸n terrible en E / S, y esto est谩 en los arreglos.

Habiendo analizado componentes, identifiqu茅 tres focos. El primero es el antivirus Kaspersky , que escanea el c贸digo fuente en todos los agentes de Windows Build. El segundo es el indexador de Windows . No se desconect贸, y en los agentes de Build en tiempo real todo se index贸 durante el proceso de implementaci贸n.

El tercero es la instalaci贸n de Npm. Result贸 que en la mayor铆a de las tuber铆as usamos este escenario particular. 驴Por qu茅 es malo? El procedimiento de instalaci贸n de Npm comienza cuando el 谩rbol de dependencias se forma en package-lock.json , donde se arreglan las versiones de los paquetes que se utilizar谩n para construir el proyecto. La desventaja es que la instalaci贸n de Npm saca las 煤ltimas versiones de paquetes de Internet cada vez, y este es un tiempo considerable en el caso de un proyecto grande.

Los desarrolladores a veces experimentan en la m谩quina local para probar el funcionamiento de una parte individual o proyecto en su conjunto. A veces result贸 que a nivel local todo era genial, pero montado, desplegado, nada funcionaba. Comenzamos a entender cu谩l es el problema: s铆, diferentes versiones de paquetes de dependencia.

Soluci贸n


  • Fuentes de excepciones AV.
  • Deshabilitar la indexaci贸n.
  • Cambiar a npm ci .

La ventaja de npm ci es que recopilamos el 谩rbol de dependencias una vez y tenemos la oportunidad de proporcionar al desarrollador una lista actualizada de paquetes con los que puede experimentar localmente tanto como sea necesario. Esto ahorra tiempo a los desarrolladores que escriben c贸digo.

Configuracion


Ahora un poco sobre la configuraci贸n del repositorio. Hist贸ricamente, hemos estado utilizando Nexus para administrar repositorios, incluido REPO interno . Todos los componentes que utilizamos para fines internos, por ejemplo, la supervisi贸n autoescrita, se entregan a este repositorio interno.



Tambi茅n usamos NuGet , ya que almacena mejor en cach茅 que otros administradores de paquetes.

Resultado


Despu茅s de optimizar los agentes de compilaci贸n, el tiempo de compilaci贸n promedio se redujo de 12 minutos a 7.

Si contamos todas las m谩quinas que podr铆amos usar para Windows, pero transferidas a Linux en este proyecto, ahorramos alrededor de $ 10,000. Y esto es solo en licencias, y considerando el contenido, m谩s.

Planes


El pr贸ximo trimestre, el plan estableci贸 el trabajo para optimizar la entrega del c贸digo.

Transici贸n a la imagen de Docker precompilada . TFS es algo genial con muchos complementos que le permiten integrarse en la canalizaci贸n, incluido el ensamblaje de acuerdo con el disparador, por ejemplo, una imagen de Docker. Queremos hacer que este disparador est茅 en el mismo paquete-lock.json . Si de alguna manera cambia la composici贸n de los componentes que se utilizan para construir el proyecto, tendremos una nueva imagen de Docker. M谩s tarde se utiliza para implementar el contenedor con la aplicaci贸n compilada. Ahora bien, esto no es as铆, pero planeamos cambiar a una arquitectura de microservicios en Kubernetes, que se est谩 desarrollando activamente en nuestra empresa y ha estado sirviendo soluciones de producci贸n.

Resumen


Insto a todos a lanzar Windows, pero esto no se debe a que no s茅 c贸mo cocinarlo. La raz贸n es que la mayor铆a de las soluciones de Opensource son la pila de Linux . Ahorrar谩 bien en recursos . En mi opini贸n, el futuro est谩 en las soluciones Open Source Linux con una comunidad poderosa.

Perfil del orador Alexander Sinchinov en GitHub .

DevOps Conf es una conferencia sobre la integraci贸n de procesos de desarrollo, prueba y operaci贸n para profesionales de profesionales. 驴Por eso el proyecto del que habl贸 Alexander? implementado y funcionando, y el d铆a de la presentaci贸n se realizaron dos lanzamientos exitosos. En DevOps Conf en RIT ++ el 27 y 28 de mayo habr谩 incluso m谩s casos de este tipo por parte de los profesionales. Todav铆a puede saltar al 煤ltimo carro y enviar un informe, o tomarse su tiempo para reservar un boleto. Nos vemos en Skolkovo!

Source: https://habr.com/ru/post/448496/


All Articles