Contenedores simples de CI / CD en AWS


14

Estoy usando AWS Code Pipeline, Code Build para crear un nuevo contenedor Docker y llevarlo a ECR.

Mi aplicación es un simple contenedor sencillo basado en un contenedor. Lo que sería un enfoque de menor fricción para extraer el Contenedor actual y relanzar un nuevo Contenedor desde el registro ECS (salida de Code Build a través de Code Pipeline).

Probé CloudFormation con datos de usuario EC2, scripts personalizados en un lado y CloudFormation con ECS con definición de tareas en el otro lado (aún no fue exitoso). Creo firmemente que debe haber un enfoque más obvio y más simple.

Respuestas:


16

Mantendría las instancias del contenedor ECS (estoy hablando de los hosts Docker , no me gusta la terminología de AWS aquí) y la implementación como dos cosas separadas.

Obtenga su pila de ECS en funcionamiento. Puede administrarlo a través de grupos de CloudFormation y Auto-scaling, está bien. Basta pensar en el clúster como una plataforma donde se desplegará a , no es algo que necesita para redeploy .

Luego, para CD, el método más fácil es actualizar la definición del servicio para usar una nueva definición de tarea y dejar que ECS actualice los contenedores por usted.

Cada vez que inicia una tarea, ECS ejecutará docker pull image: tag incluso si tiene la imagen localmente para asegurarse de que tiene la última versión de esa imagen: tag. Por lo tanto, la etiqueta de imagen que usa realmente no importa (no hay necesidad de cambiar la etiqueta en cada compilación).

Eso significa que puede construir myimage: lo último una y otra vez para implementarlo fácilmente.

Lo que necesita es una definición de tarea donde la imagen = myimage: latest. Cree un servicio con esa definición de tarea y cada vez que ECS inicie una tarea (una instancia de su servicio) será el "myimage: latest" más reciente que haya creado.

A partir de ahí, solo falta una pieza en el rompecabezas, desde CodeDeploy, puede llamar a algo, tal vez una función lambda, para crear una nueva revisión de la definición de su tarea y actualizar su servicio y ECS creará automáticamente nuevas tareas para esa revisión y eliminar las viejas tareas

Un ejemplo:

Supongamos que ha creado un servicio llamado MyService. Que ha configurado ese servicio para ejecutar 2 tareas para la definición de tarea MyTaskDefinition: 1 (revisión 1). En esa definición de tarea, tiene una definición de contenedor cuya imagen se establece en "myimage: latest".

  1. Ayer has compilado myimage: último que tenía la ID (SHA) 365d8f7bf565.
  2. Su instancia de contenedor ABC está ejecutando una tarea llamada MyTaskDefinition- 1 -containerName-someLongId. cuando inspeccionas ese contenedor, está ejecutando la imagen "sha256: 365d8f7bf565 .........."
  3. Su otra instancia de contenedor DEF está ejecutando otra tarea. Tiene un nombre similar (solo la ID difiere), pero está ejecutando la misma imagen.
  4. Empujas un cambio a tu repositorio.
  5. CodePipeline recoge ese cambio, crea y publica la imagen en ECR.
  6. Esa nueva imagen de Docker también es myimage: la última, pero su ID (SHA) es f7ec5e54ac96
  7. Ahora necesita agregar un paso a su canal para usar las funciones de Lambda y el SDK de AWS NodeJS para hacer algunas llamadas a su clúster:
    1. Cree una nueva definición de tarea (que será exactamente la misma que antes). Esa será MyTaskDefinition: 2
    2. Actualice su MyService para usar MyTaskDefinition: 2 (en lugar de 1)
  8. ECS creará nuevas tareas. Los nombres del contenedor serán MyTaskDefinition- 2 -containerName-someLongId. Cuando inspeccione esos contenedores, verá que se ejecutarán "sha256: f7ec5e54ac96 .......". Tal vez tenga 2 tareas en la instancia de contenedor ABC, tal vez se pulverizarán (eso depende de la configuración de su servicio)
  9. Después de un tiempo, ECS eliminará la tarea anterior MyTaskDefinition-1-containerName-someLongId de ABC y DEF.

Nota: en realidad no necesita crear una nueva definición de tarea. Si lo desea, puede recuperar la lista de tareas del servicio y detenerlas manualmente una por una. Debe esperar a que ECS reinicie una tarea antes de detener una nueva (es decir: detener el primer contenedor, esperar a que ECS lo reemplace, detener el segundo contenedor). Cuando ECS reinicie el contenedor, tomará la imagen más reciente: la última versión, como se explicó anteriormente. Simplemente creo que crear una nueva definición de tarea es más fácil y menos propenso a errores (no se requiere lógica para esperar y verificar, ECS se encargará de la actualización progresiva si tiene una nueva definición de tarea).


Asombroso: llamaría a su respuesta como el manual que falta para el CI / CD para Docker. Gracias.
Naveen Vijay

3

Para un caso de uso simple descrito, sugeriría que compruebe Elastic Beanstalk para Docker, no es la solución mínima, como el uso simple de ECS, pero puede beneficiarse de servicios autogestionados y configurados como ELB, EC2 AutoScale, monitoreo de salud y mucho más.

Resumen de alto nivel:

  1. Configure Elastic Beanstalk para usar una etiqueta específica myimage: probado
  2. Use Code Pipeline / Build para construir, probar y promover la etiqueta "probada"
  3. Despliegue la implementación Elastic Beanstalk, que extraerá la imagen de imagen promovida: probado en todas las instancias, diferentes estrategias de implementación disponibles.

Este enfoque basado en la reutilización de la misma etiqueta, enfoque alternativo sería generar etiqueta con ID de compilación, por ejemplo myimage: probado-42, esto requerirá actualizar Elastic Beanstalk cada vez con una nueva etiqueta, pero brinda un control más granular en la revisión implementada.


0

En segundo lugar elástico beantalk por su simplicidad; Es muy fácil de configurar e implementar.

Si está familiarizado con docker-compose, otro enfoque sería definir docker-compose.yml e implementarlo directamente en ECS con ecs-cli.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.