Init Containers y Multi Containers
Multi Containers
Como sabemos un pod puede tener más de un contenedor.
Los contenedores en un pod comparten la misma red, los mismos volúmenes declarados, y todas las cosas que están definidas en spec.
Ellos nacen juntos y mueren juntos. Los contenedores en un pod son escalados juntos y el service apunta para el pod, siendo que cada contenedor escucha en un puerto específico del pod. Siendo así un service puede apuntar para los puertos de ambos contenedores.
Como mencionado anteriormente, un pod debe ejecutar su aplicación principal en un contenedor, pero muchas veces necesitan de otros contenedores al lado para ayudar en algunas cosas y no mezclar las funcionalidades de las aplicaciones.
Esos contenedores son llamados sidecars.
Es muy usado por ejemplo para enviar log de la aplicación para algún lugar específico, pero poseen otras funcionalidades que son mejor definidas en el curso de CKAD.
Es esperado que estos contenedores estén siempre vivos para que el pod se mantenga vivo.
Si cualquiera de los contenedores falla el pod se reiniciará.
Init Containers
Algunas veces necesitamos solamente ejecutar un proceso que debe ser completado en un contenedor como por ejemplo hacer un pull de un código o de un binario para ser usado por la aplicación principal. Después de terminar el pull el contenedor se detendrá y no se mantendrá vivo y el pod se quedará reiniciando.
En ese caso usamos los init containers.
Los init containers ejecutan procesos antes de que los contenedores inicien y solamente ejecutan una vez durante la creación del pod. Los contenedores de los init containers deben haber completado su tarea para que los contenedores puedan iniciar.
En caso de que algún contenedor de los init containers falle su tarea, el Kubernetes se quedará reiniciando el pod repetidamente hasta que todos los contenedores de los init containers sean iniciados con éxito.
De esa forma, los procesos de los init containers necesitan terminar al contrario de tener un proceso que los mantiene vivos como en los contenedores estándar.
Eso es muy usado para hacer bootstrap de aplicaciones.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
# Este es el contenedor de la aplicación
containers:
- name: myapp-container
image: alpine
command: ['echo', 'The app is running', '&&','sleep 3600']
# Estos son los contenedores que necesitan iniciar antes de la aplicación.
initContainers:
- name: init-myservice
image: busybox
command: ['sleep', "30"]
# Simulación de un segundo proceso
- name: init-mydb
image: busybox
command: ['sleep', '60']
No tendría sentido levantar la aplicación si ella es dependiente de otra y necesitamos garantizar que el servicio esté disponible y usamos en ese caso dos contenedores para hacer las verificaciones.
Los contenedores de los init-containers NO EJECUTAN EN PARALELO, sino SECUENCIALMENTE. Primero uno termina para después comenzar el otro.
Si tenemos una secuencia de dos contenedores, uno con sleep 30 y otro con sleep 60, primero esperaríamos los 30 y después los 60, dando un total de 90 segundos.
Otra curiosidad es que cuando los pods muestran 2/2 o 3/3, significan contenedores y no init containers. Ellos no son sumados a los contenedores.