Cuanto más conozco de Kubernetes, GCP y docker, más consciente soy de que es todo un universo paralelo en continuo cambio. Universo, porque a nivel de posibilidades, flexibilidad, configuraciones… las opciones son muy diversas pero no por ello excluyentes. La problemática que se me planteaba era la siguiente:
Tenía un despliegue (deployment), que generaba a partir de un yaml sencillo, el cual contenía básicamente un par de imágenes y los puertos expuestos. En una de esas imágenes, había que crear por seguridad un nuevo usuario con sus respectivos permisos y accesos.
En casos normales, hubiera bastado con levantar el deployment y asignarle almacenamiento persistente. El problema era que la configuración de este servicio se guardaba vinculada al nombre del pod. La situación era tal que así:
config@pod1
config@pod2
Mientras el pod estuviera vivo, no había problema, pero si el pod moría y se levantaba otro distinto, se perdía esa configuración. Y seamos realistas, Kubernetes está diseñado para que los pods se mueran en cuanto dejan de funcionar como se espera.
Solución: Crear ese usuario a la vez que el pod, ejecutando comandos de consola específicos. Así, cuando se levantase el pod con el nombre que se levantase, ese usuario existiría y funcionaría.
Ejemplo de lanzamiento de comando tras la creación del contenedor
apiVersion: v1
kind: Deployment
metadata:
...
spec:
replicas: 1
template:
metadata:
...
spec:
containers:
- name: auth
image: [imagen-del-servicio]
env:
ports:
- containerPort: 3000
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "[cmd]"]
Donde:
- [imagen-del-servicio] es el nombre de la imagen que estamos utilizando para crear el contenedor dentro del pod.
- [cmd] es el comando/s que queremos lanzar.
- command: Sus corchetes son obligatorios.
A grandes rasgos, la configuración para lanzar los comandos viene definida dentro de la etiqueta lifecycle. Para más info, podéis consultar la documentación oficial de Kubernetes sobre cómo adjuntar controladores a eventos de ciclo de vida del contenedor.
Ojo! Es posible que la imagen de aplicación que estáis desplegando tarde unos segundos antes de poder aceptar comandos. Recomiendo siempre usar un sleep antes de lanzar ningún otro comando, donde [TIEMPO] es el valor en segundos que queremos darle.
command: ["/bin/sh", "-c", "sleep [TIEMPO]"]
Los comandos se pueden concatenar de la misma manera que lo haríamos en consola. Por ejemplo:
command: ["/bin/sh", "-c", "sleep 60 && echo 'Hola Mundo'"]
Problema resuelto!