Quantcast
Channel: Planeta Código
Viewing all articles
Browse latest Browse all 2699

Blog Bitix: Estrategias de despliegue para microservicios con Nomad

$
0
0
Nomad
Consul
HashiCorp

El ciclo de vida de una aplicación no consiste solo en desarrollarla, incluye también su puesta en producción o despliegue en un entorno de pruebas, pero también una vez la aplicación está desplegada en algún momento será necesario actualizarla con una nueva versión.

Las aplicaciones monolíticas tienen otros problemas pero en el aspecto de despliegue es sencillo ya que solo hay una aplicación, basta con desplegar la nueva versión. En una aplicación con arquitectura de microservicios es un reto mayor debido a que hay múltiples aplicaciones.

En cualquiera de ellas puede darse el caso de que para ganar en escalabilidad o para aumentar la disponibilidad o tolerancia a fallos es posible que haya varias instancias, las cuales han de ser actualizadas con el requisito si es necesario de que el servicio no deje de prestar su servicio, es decir que el despliegue no suponga una caída del servicio.

Hay varias estrategias para desplegar una nueva versión de una aplicación:

  • Rolling update: actualizar todas las instancias de forma progresiva. Una vez se termina de actualizar una se espera un tiempo y se actualiza la siguiente hasta que todas estén actualizadas.
  • Blue/Green: manteniendo en funcionamiento las instancias con la versión antigua se crea el mismo número de instancias con la nueva versión y se redirige tráfico hacia ellas. Una vez se ha comprobado que la nueva versión funciona correctamente se promociona la nueva versión y se eliminan las instancias de con la versión antigua. Esta estrategia permite volver a la versión anterior rápidamente si se detecta algún problema.
  • Canary: se siguen manteniendo las instancias con la versión antigua, a diferencia de la estrategia blue/green se crea un número menor de instancias con la versión nueva que el número de instancias con la versión antigua. Una vez comprobado que la nueva versión es correcta se promociona la nueva versión y se actualizan todas las instancias restantes mediante rolling update a la nueva versión. También permite volver a la versión antigua si se detecta algún problema.

Docker Swarm permite la estrategia de despliegue rolling update sin embargo las estrategias blue/green y canary son interesante para tratar de que un error en una versión nueva no afecte al funcionamiento de la aplicación y obligue hacer un rollback que posiblemente tarde más tiempo durante el cual el servicio funcionará con el defecto descubierto. Nomad permite despliegues con las estrategias blue/gree y canary.

Para actualizar un servicio en Nomad basta con modificar la definición del job y enviarlo a Nomad, y este se encarga de orquestar la actualización en las instancias según la estrategia de despliegue configurada. En este caso se actualiza la versión de nginx de la versión nginx:stable-alpine a nginx:alpine usando una estrategia rolling update para las cinco instancias del servicio.

La estrategia de despliegue en Nomad se define en la sección de configuración update. El parámetro min_healthy_time es el tiempo que se espera cuando se hace un rolling update para considerar una instancia como sana y continuar la actualización con la siguiente, max_parallel indica el número de instancias que se migran al mismo tiempo. El parámetro canary indica el número de instancias que se crean en las estrategias blue/green y canary, en la primera el número de instancias coincidirá con el parámetro canary que indica el número de instancias de un servicio. Nomad con los parámetros health_check, min_healthy_time, healthy_deadline, progress_deadline, stagger y auto_revert se puede poner unos límites para considerar válido un despliegue y en caso de no serlo realizar un rollback de forma autmática.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
job "nginx" {
datacenters = ["localhost"]
type = "service"
update {
stagger = "30s"
max_parallel = 1
}
group "services" {
count = 5
task "nginx" {
driver = "docker"
config {
image = "nginx:stable-alpine"
port_map {
http = 80
}
}
resources {
memory = 1024 # MB
network {
port "http" {}
}
}
}
}
}
1
2
$ nomad job run nginx.nomad

En el caso de los despliegues blue/green y canary una vez comprobado que la versión de los nuevos servicios funcionan correctamente se promocionan y actualizan el resto de instancias en el caso de canary o se detienen las instancias antiguas en el caso de blue/green.

1
2
$ nomad job promote nginx

Desde la línea de comandos se puede observar el estado del servicio y el proceso de actualización, el primero es el estado previo a realizar el despliegue, el segundo durante el proceso de actualización con rolling update y el tercero una vez finalizado el proceso de despliegue y marcado como exitoso en el que todas las instancias han pasado de la versión 0 a la 1.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
$ nomad job status nginx
ID= nginx
Name= nginx
Submit Date=2019-04-18T10:50:11+02:00
Type= service
Priority=50Datacenters= localhost
Status= running
Periodic=falseParameterized=false
Summary
Task Group Queued Starting Running Failed Complete Lost
services 005000
Latest Deployment
ID= 67d4497a
Status= successful
Description= Deployment completed successfully
Deployed
Task Group Desired Placed Healthy Unhealthy Progress Deadline
services 55502019-04-18T11:00:22+02:00
Allocations
ID Node ID Task Group Version Desired Status Created Modified
0bee3ae1 1806498b services 0 run running 25s ago 14s ago
295f72ec 1806498b services 0 run running 25s ago 14s ago
6b2dcff1 1806498b services 0 run running 25s ago 14s ago
94a1a79b 1806498b services 0 run running 25s ago 14s ago
f163316f 1806498b services 0 run running 25s ago 14s ago
$ nomad alloc status 0bee3ae1
ID= 0bee3ae1
Eval ID= 2c63f7a1
Name= nginx.services[0]
Node ID= 1806498b
Job ID= nginx
Job Version=0
Client Status= running
Client Description= Tasks are running
Desired Status= run
Desired Description=<none>
Created= 39s ago
Modified= 28s ago
Deployment ID= 67d4497a
Deployment Health= healthy
Task "nginx" is "running"
Task Resources
CPU Memory Disk Addresses
0/100 MHz 1004 KiB/1.0 GiB 300 MiB http: 127.0.0.1:27902
Task Events:
Started At=2019-04-18T08:50:12Z
Finished At= N/A
Total Restarts=0
Last Restart= N/A
Recent Events:
Time Type Description
2019-04-18T10:50:12+02:00 Started Task started by client
2019-04-18T10:50:11+02:00 Task Setup Building Task Directory
2019-04-18T10:50:11+02:00 Received Task received by client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ nomad job status nginx
ID= nginx
Name= nginx
Submit Date=2019-04-18T10:55:59+02:00
Type= service
Priority=50Datacenters= localhost
Status= running
Periodic=falseParameterized=false
Summary
Task Group Queued Starting Running Failed Complete Lost
services 005010
Latest Deployment
ID= 8b96049d
Status= running
Description= Deployment is running
Deployed
Task Group Desired Placed Healthy Unhealthy Progress Deadline
services 51002019-04-18T11:05:59+02:00
Allocations
ID Node ID Task Group Version Desired Status Created Modified
d9e3a0c9 1806498b services 1 run running 4s ago 4s ago
0bee3ae1 1806498b services 0 stop complete 5m53s ago 4s ago
295f72ec 1806498b services 0 run running 5m53s ago 5m42s ago
6b2dcff1 1806498b services 0 run running 5m53s ago 5m42s ago
94a1a79b 1806498b services 0 run running 5m53s ago 5m42s ago
f163316f 1806498b services 0 run running 5m53s ago 5m42s ago
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ nomad job status nginx
ID= nginx
Name= nginx
Submit Date=2019-04-18T10:55:59+02:00
Type= service
Priority=50Datacenters= localhost
Status= running
Periodic=falseParameterized=false
Summary
Task Group Queued Starting Running Failed Complete Lost
services 005050
Latest Deployment
ID= 8b96049d
Status= successful
Description= Deployment completed successfully
Deployed
Task Group Desired Placed Healthy Unhealthy Progress Deadline
services 55502019-04-18T11:06:59+02:00
Allocations
ID Node ID Task Group Version Desired Status Created Modified
a6a1423a 1806498b services 1 run running 33s ago 22s ago
c529ec57 1806498b services 1 run running 45s ago 34s ago
1cda0083 1806498b services 1 run running 57s ago 46s ago
aff0eaf9 1806498b services 1 run running 1m9s ago 58s ago
d9e3a0c9 1806498b services 1 run running 1m21s ago 1m11s ago
6b2dcff1 1806498b services 0 stop complete 7m10s ago 1m9s ago
94a1a79b 1806498b services 0 stop complete 7m10s ago 44s ago
0bee3ae1 1806498b services 0 stop complete 7m10s ago 1m21s ago
295f72ec 1806498b services 0 stop complete 7m10s ago 32s ago
f163316f 1806498b services 0 stop complete 7m10s ago 57s ago

El proceso de despliegue también se puede monitorizar desde la interfaz web que ofrece Nomad.

Proceso de despliegue rolling update en Nomad

En este ejemplo los servicios están en contenedores docker, también se observa que la versión de los contenedores en ejecución pasan de la versión stable-alpine a alpine.

1
2
3
4
5
6
7
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d09e91f7306 nginx:stable-alpine "nginx -g 'daemon of…"53 seconds ago Up 52 seconds 127.0.0.1:20093->80/tcp, 127.0.0.1:20093->80/udp nginx-e974a9c1-0d6b-4d4b-59e7-c86570260509
fa53aa43eccc nginx:stable-alpine "nginx -g 'daemon of…" About a minute ago Up About a minute 127.0.0.1:31503->80/tcp, 127.0.0.1:31503->80/udp nginx-3014056a-a8a5-e63c-c6e6-e9c2e9cafde1
12f482b6fe67 nginx:stable-alpine "nginx -g 'daemon of…" About a minute ago Up About a minute 127.0.0.1:22122->80/tcp, 127.0.0.1:22122->80/udp nginx-a55d7647-a48e-eace-c40f-b2a9abd0ad17
3d09a4329279 nginx:stable-alpine "nginx -g 'daemon of…" About a minute ago Up About a minute 127.0.0.1:24899->80/tcp, 127.0.0.1:24899->80/udp nginx-d682548a-d3d3-bddb-2cd8-cfe489a492b3
24e70fe9443a nginx:stable-alpine "nginx -g 'daemon of…" About a minute ago Up About a minute 127.0.0.1:20772->80/tcp, 127.0.0.1:20772->80/udp nginx-99dab397-69fd-97b0-6507-39195931031c
1
2
3
4
5
6
7
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0495fd1b6261 nginx:alpine "nginx -g 'daemon of…"6 minutes ago Up 6 minutes 127.0.0.1:27703->80/tcp, 127.0.0.1:27703->80/udp nginx-a6a1423a-896d-5716-34bc-533630f45c93
ecb361f99b57 nginx:alpine "nginx -g 'daemon of…"6 minutes ago Up 6 minutes 127.0.0.1:23859->80/tcp, 127.0.0.1:23859->80/udp nginx-c529ec57-ff92-73ae-6e68-46a2d5c55bed
82429bac4974 nginx:alpine "nginx -g 'daemon of…"6 minutes ago Up 6 minutes 127.0.0.1:27878->80/tcp, 127.0.0.1:27878->80/udp nginx-1cda0083-9fa0-6e6d-5276-ab0bd1de8762
69cbf7fd37d8 nginx:alpine "nginx -g 'daemon of…"7 minutes ago Up 7 minutes 127.0.0.1:24634->80/tcp, 127.0.0.1:24634->80/udp nginx-aff0eaf9-a099-42fd-58ea-4603f96ccd3f
4935502d58ce nginx:alpine "nginx -g 'daemon of…"7 minutes ago Up 7 minutes 127.0.0.1:22657->80/tcp, 127.0.0.1:22657->80/udp nginx-d9e3a0c9-82bd-8b19-14a7-0a663f539c00

Nomad y Consul se inician con los siguientes comandos en modo desarrollo comentados en el artículo Introducción a Nomad para gestionar aplicaciones y microservicios.

1
2
$ consul agent -dev -datacenter localhost
$ sudo nomad agent -dev -dc localhost

Viewing all articles
Browse latest Browse all 2699