Actualizaci贸n del proceso de CI / CD: despliegue de pulpo

imagenLa tercera parte del art铆culo trata sobre la actualizaci贸n de los procesos de CI / CD. 

En esta etapa, tenemos (al menos deber铆amos tener) una comprensi贸n de c贸mo funcionar谩 CI, lo que tenemos en la entrada, c贸mo obtener el resultado y qu茅 se debe hacer para que la salida de la construcci贸n se convierta en un m贸dulo de proyecto completo y comience. Adem谩s de un pulpo establecido (preferiblemente LTS). En la 煤ltima parte, se consider贸 el proceso de configuraci贸n de teamcity: todo lo que sucede desde el momento en que el c贸digo ingresa al repositorio y hasta que se puede desempaquetar el archivo listo, y en teor铆a, deber铆a funcionar.

Recuerdo la tabla de contenido:

Parte 1: qu茅 es, por qu茅 no es as铆, planificaci贸n, una peque帽a fiesta. Yo llamar铆a a esta parte casi t茅cnica.
Parte 2: teamcity.
Parte 3: despliegue de pulpo.
Parte 4: detr谩s de escena. Momentos desagradables, planes para el futuro, posiblemente preguntas frecuentes. Lo m谩s probable es que tambi茅n se le pueda llamar casi t茅cnico.

Pulpo: general


En la entrada, tenemos el c贸digo, en la salida, los artefactos de ensamblaje, todo est谩 claro aqu铆. Pero el resultado para cada m贸dulo consta de dos partes: un paquete central (el resultado de la compilaci贸n misma) y un paquete individual (configuraciones y bibliotecas 煤nicas). Entonces, para que un m贸dulo en particular funcione, necesitamos algo como lo siguiente:

  1. Una instancia en IIS que tiene su propio grupo y que "se ve" en la ra铆z del documento. Se asigna un grupo separado para cada m贸dulo.
  2. Archivos del paquete principal en la ra铆z del documento.
  3. Archivos de paquetes individuales en la ra铆z del documento.
  4. Es aconsejable hacer una copia de seguridad del contenido anterior de la ra铆z del documento frente a todo esto. Nosotros, por supuesto, confiamos en nosotros mismos, pero las personas se dividen en dos tipos: los que no respaldan y los que ya lo hacen. 
  5. ( ) ( ). , , .
  6. , , .
  7. , .
  8. () .

No tanto, pero no lo suficiente. No hay problemas con el paso 1. Octopus tiene una plantilla Deploy to IIS, tiene todo lo que necesita. En los pasos 2 y 3 nos detendremos con m谩s detalle a continuaci贸n. Para el paso 4, una variable solicitada es suficiente, que pasaremos de teamcity. El paso 5 es un script de PowerShell. Tambi茅n rotar谩 las copias de seguridad. 驴Por qu茅 necesitamos almacenarlos todos? Los viejos se pueden eliminar. El paso 6 tambi茅n es PowerShell. Paso 7: la holgura finalizada: plantilla de notificaci贸n detallada. Paso 8: nuevamente PowerShell. Parece un plan, por lo que lo implementaremos.

Inquilinos


Un poco m谩s de detalles sobre los pasos 2 y 3. Supongo que el lector est谩 familiarizado con el despliegue de pulpo. Si no, hay maravillosos (y 煤nicos) art铆culos en el centro. Pueden dar una comprensi贸n b谩sica. Aqu铆 est谩n: uno y el segundo . Por lo tanto, tenemos pesta帽as de proyectos, infraestructura, inquilinos, bibliotecas, tareas y configuraciones actuales. Necesario - inquilinos. La traducci贸n literal de la palabra inquilino es inquilino. En este contexto, muy probablemente se refer铆a al cliente, el cliente. Oktopus nos dice que los inquilinos le permiten implementar diferentes instancias de un proyecto a la vez para muchos clientes (inquilinos). Esta es la p谩gina con su lista.

imagen

En este caso, los inquilinos se usan de manera un poco diferente. Cada inquilino representa a un cliente individual. Para el inquilino existe la oportunidad de agregar proyectos que se lanzar谩n cuando se implemente. En consecuencia, habr谩 un proyecto central y un proyecto individual.
Hay dos etiquetas para cada inquilino: TenantRole: com煤n para todos, lo que indica que un m贸dulo de un tipo espec铆fico (n煤cleo) se implementa en todos los inquilinos con esta etiqueta, y ModName es una etiqueta que coincide con el nombre del m贸dulo (individual). 

imagen

El 煤ltimo pulpo se recibe de timcity como par谩metro, identificando as铆 el m贸dulo que se implementa actualmente ( Deploy.Env y Deploy.2 ).

Como puede ver en la pantalla, al implementar un m贸dulo para una organizaci贸n espec铆fica, el proyecto central comenzar谩 primero ( despliegue.2 paso de teamcity), luego un proyecto individual ( pasos deploy.3 y deploy.4 teamcity ). Cada inquilino tiene acceso a las variables de todos los proyectos que est谩n incluidos en 茅l, as铆 como a las variables del inquilino en s铆 (recopiladas en un conjunto de variables y que contienen la etiqueta ModName).

imagen

 El inquilino para la implementaci贸n se selecciona en el equipo de la siguiente manera: 

  • variable env.tenantRoleTag: contiene TenantRole (nombre de etiqueta de inquilino en pulpo) y su valor real;
  • env.modName: el valor de la etiqueta ModName en octopus.

Variables


Las variables son una parte importante del proyecto y deben estructurarse correctamente. En este proyecto, las variables de pulpo se dividen en tres tipos: comunes para todos los proyectos (recopilados en el conjunto de la Biblioteca "Entorno"), individuales para cada proyecto (configurados directamente en el proyecto) y variables directamente de los inquilinos (tambi茅n un conjunto de biblioteca). En el Medio Ambiente, como ya se mencion贸, todo lo com煤n para todos los proyectos, en particular: 

  • rutas base a la ra铆z del documento (por ejemplo, C: \ inetpub \);
  • URL base (por ejemplo, para todos los m贸dulos, el dominio com煤n es organization.com);
  • acceso a bases de datos (necesarias para organizar copias de seguridad);
  • etc.

Una gran ventaja es que en el pulpo para cada entorno puede haber un valor variable. La separaci贸n puede ser cualquier cosa.

imagen

Por ejemplo, las l铆neas 3, 6 y 7 en la pantalla. La l铆nea 3 es un caso com煤n. Todo lo que debe implementarse en el entorno de producci贸n llega aqu铆. Las l铆neas 6 y 7 describen casos bastante espec铆ficos, por ejemplo: el entorno de producci贸n con el rol "Sitio web de la empresa" (l铆nea 6) y el entorno de producci贸n con la etiqueta de inquilino "orgznizationX". Esto es necesario para identificar los servidores en los que se obtendr谩 el paquete, porque para la organizaci贸n X, por ejemplo, se asigna un servidor separado.

Las variables para el proyecto incluyen todo lo dem谩s. Algo que no es com煤n y difiere para diferentes entornos, por ejemplo, el nombre de dominio completo del m贸dulo. En general, se compila como # {Tenant.ModName}. # {BaseModuleDomain}, sin embargo, puede ser diferente en algunos casos.

imagen

 Tal caso se presenta en la imagen.

Canales


Todav铆a vale la pena hablar sobre los canales. Breve y r谩pidamente: los canales le permiten configurar la l贸gica de implementaci贸n. Muy sencillo, esto se describe en la documentaci贸n oficial, en particular aqu铆 y aqu铆 . Por ejemplo, un lanzamiento con solo la etiqueta estable puede ingresar al canal de producci贸n, etc. Hay 4 canales en el proyecto que coinciden con los entornos (desarrollo, prueba, puesta en escena, producci贸n). Los lanzamientos caen en ellos de acuerdo con las etiquetas de prelanzamiento. Se indica en el formato de n煤mero de compilaci贸n teamcity ( Build.Configuraci贸n general de la parte sobre teamcity). Desde teamcity, el canal se transfiere en el paso Deploy.2 al campo adicional de argumentos de la l铆nea de comando (par谩metro --channel).

Patrones


Si a煤n no ha apreciado todas las ventajas de usar plantillas al leer un art铆culo sobre teamcity, ahora es el momento. Es aconsejable crear plantillas de pasos personalizados que sean lo suficientemente comunes, ya que si es necesario realizar ediciones, tendr谩 que recordar en qu茅 lugares se aplica este paso, haga clic en cada lugar similar y realice las ediciones tantas veces como los use para este paso. En este proyecto, se crearon plantillas para verificar el estado del sitio y enviar una lista de dominios a teamcity. Considere brevemente el proceso de creaci贸n de una plantilla.

Hay un script de PowerShell que debe ejecutarse cada vez que se despliega cualquier m贸dulo.

$url = "$scheme" + "://" + "$domain"
Write-Host "Requesting '$url'"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$request = [System.Net.WebRequest]::Create($url)
$request.Timeout = $timeout
$response = $request.GetResponse()
$response.Close()

El script acepta el esquema de entrada, el dominio y el tiempo de espera despu茅s del cual creemos que el sitio no est谩 operativo. Puede crear una plantilla en Biblioteca - Plantillas de pasos.

Ingrese un nombre, elija un logotipo. A continuaci贸n, configure los par谩metros de entrada y sus valores predeterminados. El valor predeterminado tambi茅n puede ser el valor de la variable especificada (el valor de la variable # {HostName} es el valor predeterminado del par谩metro de entrada # {Domain}).

imagen

A continuaci贸n, modificamos un poco el script y lo agregamos como un paso para la ejecuci贸n:

imagen

Listo. En la salida, obtenemos una plantilla de pasos con la que es agradable trabajar, y tambi茅n, en ausencia de nuestro trabajo, los colegas podr谩n descubrir los valores de campo sin leer los scripts oscuros.

imagen

Pulpo: detalles del proceso


Todos los proyectos se dividen en grupos, la descripci贸n se llevar谩 a cabo en el ejemplo del grupo M贸dulos. Contiene los siguientes proyectos: 

  • n煤cleo;
  • proyectos de m贸dulos individuales.

Comencemos con el proyecto central.

Aqu铆 est谩 la p谩gina de resumen:

imagen

Aqu铆 puede ver claramente qu茅 versiones del kernel obtuvieron. Pido disculpas por la confusi贸n en los n煤meros de versi贸n, ahora estamos cambiando a versiones vinculadas a la etiqueta git, y en todas partes, excepto en producci贸n, ya se utilizan nuevas versiones.

Como puede ver, para algunos inquilinos no hay entornos definidos. O a煤n no se han creado o no se han previsto. 

Proceso de implementaci贸n central


En la etapa de entrega del kernel, tambi茅n se realizan parte de las operaciones de servicio, a saber, la copia de seguridad de la base de datos (si es necesario), la copia de seguridad de la versi贸n anterior de los archivos, la rotaci贸n de copias de seguridad y la implementaci贸n del kernel. 

imagen

Paso 1: copia de seguridad de la base de datos. Es opcional y se basa en el valor del par谩metro variable que se pasa de teamcity en el paso Implementar.2 al campo adicional de argumentos de la l铆nea de comando. De forma predeterminada, esta variable se establece en falso, ya que la copia de seguridad de la base de datos debe hacerse solo a pedido, y no constantemente. En la ciudad del equipo, comenzar cambiando este par谩metro se ve as铆 (debe hacer clic en los puntos suspensivos al lado del bot贸n de ejecuci贸n):

imagen

en Octopus, se ve as铆: a 

imagen

continuaci贸n, no hay nada inusual. Una copia de respaldo de los archivos en zip (por plantilla), rotaci贸n de respaldo (el script ser谩 un poco m谩s bajo) y una implementaci贸n del n煤cleo por plantilla. 

A qu茅 debe prestar atenci贸n: 

  • todos los par谩metros importantes est谩n establecidos por variables, esto le permite cambiar r谩pidamente su valor en un lugar sin profundizar en la configuraci贸n del proceso;
  • el nombre del grupo de IIS coincide con el nombre de la instancia y el nombre del dominio del servicio (por conveniencia);
  • en el paso de despliegue IIS, se instala Fusionar con enlaces existentes, en lugar de reemplazar. Dado que, adem谩s del servicio, todav铆a tenemos un mont贸n de dominios de clientes en cada instancia;
  • La limpieza de la ra铆z del documento (marca de verificaci贸n purgar este directorio antes de la instalaci贸n) falla. Los archivos nuevos reemplazan a los viejos a medida que los copia. Esto se hace para que el sitio no se "bloquee" durante la implementaci贸n. La demora en cargar la p谩gina es mucho mejor que la pantalla de la muerte.

Script de rotaci贸n de respaldo:

$days = $OctopusParameters["DaysStoreBackups"]
$limit = (Get-Date).AddDays(-$days)
$pathDb = $OctopusParameters["DbBackupDir"]
$pathFiles = $OctopusParameters["FilesBackupDir"] + '\' + $OctopusParameters["HostName"]

# Delete files older than the $limit.
Get-ChildItem -Path $pathDb -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $pathDb -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

# Delete files older than the $limit.
Get-ChildItem -Path $pathFiles -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $pathFiles -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

El proceso de implementaci贸n de un paquete individual


En la etapa de entrega de un paquete de m贸dulo individual, se despliegan las configuraciones y las bibliotecas 煤nicas, se localizan y / o renombran los archivos, se solicita el sitio (primero, los sitios en .net se cargan por primera vez durante mucho tiempo, este paso le permite realizar este procedimiento de inmediato, y en segundo lugar, le permite comprender si hay alg煤n error al cargar el sitio). Tambi茅n se env铆a una notificaci贸n a slack, y una lista real de todos los dominios que pertenecen a este m贸dulo se transfiere a teamcity. 

imagen

De lo importante:

  • En el paso de implementaci贸n, la ra铆z del documento no se limpia (el nuevo paquete principal ya est谩 all铆);

Paso 3, el gui贸n. Fue un poco m谩s alto en la descripci贸n de las plantillas.

Paso 5. Tambi茅n se asocia con el deploy.4 paso en TeamCity.

En pulpo, se ve as铆:

$baseDomain = $OctopusParameters["HostName"]
$domains = (Get-WebBinding $baseDomain).bindingInformation | %{ $_.Split(':')[2] } | Sort-Object | Get-Unique
Write-Host "##teamcity[setParameter name='AllInstanceDomains' value='$domains']"
Write-Host "##teamcity[setParameter name='ServiceDomain' value='$baseDomain']"

La sintaxis ## teamcity ... le permite establecer el par谩metro de compilaci贸n en teamcity. En realidad, en este, este paso se ve as铆:

Write-Host "All domains on instance %ServiceDomain% :"
$domains = "%AllInstanceDomains%"
$domains = $($domains.Split(" ") | ForEach-Object {"http://$_"} | Out-String)
Write-Host $domains
Write-Host "Service domain: http://%ServiceDomain%"

Pulpo: resultados


Todo el proceso de construcci贸n es el siguiente:

  • el c贸digo se recopila de una rama espec铆fica (correspondiente al entorno);
  • El resultado del ensamblaje (artefactos) se entrega al pulpo y consta de dos partes: el n煤cleo y un paquete de m贸dulo individual. Esto permite un uso eficiente del espacio en disco y ahorra tiempo de entrega general de actualizaciones. 
  • Cada paquete tiene una versi贸n que consta de un n煤mero y una etiqueta de prelanzamiento que define el canal y el entorno en el que se realizar谩 este lanzamiento.
  • Octopus, por entrada, crea una versi贸n y entrega paquetes a los servidores apropiados, guiados por los datos de la organizaci贸n (etiquetas de inquilino), canales (etiqueta de prelanzamiento) e instrucciones adicionales (copia de seguridad opcional de la base de datos), y tambi茅n realiza una verificaci贸n elemental del rendimiento del m贸dulo.

Eso es algo as铆. Lo m谩s probable es que haya otro art铆culo casi t茅cnico, por as铆 decirlo, detr谩s de escena. Incluir谩 todo lo que no ingres贸 aqu铆: algunos detalles, lo que se convirti贸 en nuevo en el proceso de trabajo y lo que puede tener que enfrentar para aquellos que deciden sobre esto, correcciones y actualizaciones en el proyecto, tal vez preguntas / respuestas frecuentes. Gracias por la atenci贸n.

All Articles