En estos días de fiesta, sin prisa pero sin pausa, me he montado una pequeña demo para contarte lo que es Kustomize, una herramienta que forma parte de kubectl desde la versión 1.14, que nos permite personalizar nuestros despliegues, pensando en diferentes entornos/aplicaciones, sin la necesidad de utilizar plantillas. Me han dicho que «se me da muy mal no hacer nada», así que en este artículo te cuento cómo usarlo 😃
Aplicación de ejemplo: un WordPress
Vamos a imaginar que tenemos el siguiente escenario, donde queremos desplegar un WordPress, el cual consta de un MySQL:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: wp_password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
emptyDir: {}y su servicio:
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: Noney un WordPress:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
replicas: 2
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
value: wp_password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-storage
mountPath: /var/www/html
volumes:
- name: wordpress-storage
emptyDir: {}y su servicio:
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancerAhora bien, lo que me gustaría hacer es que, sin tocar estos archivos pudiera personalizarlos, para adecuarlos al entorno donde los quiera desplegar, ya sea desarrollo, qa, producción, etcétera. De esta forma siempre tendría unos manifiestos base y otros que complementan o reemplazan de estos lo que consideremos, y justamente para eso es para lo que queremos Kustomize.
Estructura del repositorio
Para que quede lo más ordenado posible, la estructura que va a tener mi repositorio es la siguiente:
Como ves, tenemos una carpeta base donde están los archivos que te acabo de mostrar, y dos carpetas, dev y prod, con las diferencias sobre la base para estos entornos.
En el directorio base, además de los despliegues y los servicios mostrados, hay un archivo adicional dentro de este llamado kustomization.yaml el cual únicamente contiene un listado de todos los recursos que debería de tener en cuenta esta herramienta:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- mysql-deployment.yaml
- mysql-service.yaml
- wordpress-deployment.yaml
- wordpress-service.yamlLa forma en la que organices tu proyecto es indiferente, ya que haces mención siempre a los archivos que están involucrados, pero a nivel visual es más sencillo tener algo de este estilo.
Personalización para dev
Ahora vamos a fijarnos en la carpeta dev donde vamos a tener, de nuevo, un archivo kustomization.yaml que en este caso tendrá lo siguiente:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: dev
commonLabels:
env: dev
namePrefix: dev-
bases:
- ../base
secretGenerator:
- name: dbpassword
literals:
- "password=Passw0rd"
resources:
- namespace.yaml
patchesStrategicMerge:
- mysql-deployment-patch.yaml
- wordpress-deployment-patch.yamlEste se encarga de recoger todos los cambios para el entorno, que para este caso son los siguientes:
- Gracias a la propiedad namespace estoy diciendo que, sin tocar ningún archivo base, todos los elementos que se vayan a generar estén dentro de dev. Como este es posible que no exista, en el apartado resources he añadido un YAML que lo genera.
- También he utilizado commonLabels para añadir etiquetas comunes a todos los objetos del entorno.
- namePrefix me permite utilizar un prefijo para todo lo que cree en este entorno (también existe nameSufix)
- bases: se utiliza para indicar dónde están los manifiestos de partida, que son los que vamos a alterar. También se pueden utilizar URLs de repositorios git.
- secretGenerator: me permite generar los secretos que necesito para este entorno. Aquí estoy utilizando literals pero puedes también indicar un archivo con texto plano o .env, como puedes ver en el kustomization de prod.
- Por último, el apartado patchesStrategicMerge son el nombre de los archivos que contienen mis cambios respecto a los objetos base.
Para que este ejemplo no se haga eterno, los cambios en mysql-deployment-patch.yaml y wordpress-deployment-patch.yaml son los mismos, y es el cambio del valor de la contraseña de la base de datos por la que he generado aquí:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
spec:
template:
spec:
containers:
- name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: dev-wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
value: ""
valueFrom:
secretKeyRef:
name: dbpassword
key: passwordComo ves, la forma de definir los cambios es usando simplemente la misma estructura que ya conocemos, en este caso de un Deployment, pero sin que tengas que incluir aquellas propiedades que no quieres que cambien.
Para ver el resultado sin tener ejecutarlo sobre tu clúster puedes utilizar el siguiente comando:
kustomize build devPor ejemplo, en el despliegue del MySQL puedes ver todos estos cambios:
Si estás conforme con lo que has visto, para aplicarlos, en lugar de usar kubectl apply -f, utilizamos el siguiente comando:
kubectl apply -k dev Básicamente una k en lugar de una f 😊 Si ahora te fijas en el namespace dev verás que todo lo que has personalizado, incluido el propio namespace, está en su sitio:
El código del ejemplo lo tienes en mi GitHub.
¡Saludos!
Si quieres seguir aprendiendo sobre contenedores, tienes una lista de vídeos en mi canal de YouTube 👇🏻
Docker CLI: Comandos esenciales que todo developer debe conocer
Domina los Dockerfiles: De lo básico a multi-stage
4 formas de crear un Dockerfile sin empezar desde cero
¿No entiendes las redes en Docker? Mira este vídeo
Cómo NO perder tus datos en Docker: Guía definitiva
Deja de configurar contenedores a mano: Aprende Docker Compose 🐙
Cómo subir tus imágenes a Docker Hub (Guía paso a paso)
Publica y automatiza tus imágenes de Docker con GitHub





¿Qué son los contenedores? Docker desde cero para principiantes
return(GiS); julio 10, 2024 10:00 am