Secrets y ConfigMaps en Kubernetes
Kubernetes nos permite compartir información y configuraciones entre el cluster y los distintos objetos de kubernetes.
Por ejemplo, la configuración de arranque de una aplicación, los secretos de acceso a bases de datos o las variables de entorno necesarias para su funcionamiento.
Para ellos cuenta con los objetos secrets
para la información sensible y configmaps
para la información menos sensible.
Secrets
Los secretos en kubernetes son una forma de almacenar información sensible. Estos se almacenan en una base de datos de forma privada y pueden consumir por otros recursos de kubernetes.
Listar secretos:
kubectl get secrets
Crear secretos:
# Create a new secret named my-secret with keys for each file in folder bar
kubectl create secret generic my-secret --from-file=path/to/bar
# Create a new secret named my-secret with specified keys instead of names on disk
kubectl create secret generic my-secret --from-file=ssh-privatekey=path/to/id_rsa --from-file=ssh-publickey=path/to/id_rsa.pub
# Create a new secret named my-secret with key1=supersecret and key2=topsecret
kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret
# Create a new secret named my-secret using a combination of a file and a literal
kubectl create secret generic my-secret --from-file=ssh-privatekey=path/to/id_rsa --from-literal=passphrase=topsecret
# Create a new secret named my-secret from an env file
kubectl create secret generic my-secret --from-env-file=path/to/bar.env
Tambiém podríamos crear un secreto a partir de un yaml, por ejemplo:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
key1: c3VwZXJzZWNyZXQ=
key2: dG9wc2VjcmV0
Borrar un secreto:
kubectl delete secret <nombre>
Podemos crearlos de múltiples formas y tenemos opciones de guardar distintos formatos de secretos. Los genéricos son información en texto plano, más adelante, veremos como crear secretos de registry de imágenes, tls y otros.
Podemos listar los secretos creados con el siguiente comando:
kubectl get secrets
Usando secretos en un pod
Un secreto se puede usar en la definicióbn de un container, ya sea en un pod, un deployment, statefulset... etc.
Las dos formas de consumirlos normalmente son, cargarlos como variables de entorno o montarlas como un volumen en un contenedor. Veamos esos ejemplos:
Podríamos pasarlo como una variable de entorno como en el siguiente ejemplo:
...
spec:
containers:
- image: mysql:5.5
name: dbpod
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
También podríamos montarlo como un volumen en un contenedor. Este Requeriría el path donde estamos montando un fichero con el contenido del secreto. Por ejemplo:
...
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
volumeMounts:
- mountPath: /mysqlsecret
name: mysqlsecret
name: busy
volumes:
- name: mysqlsecret
secret:
secretName: mmysql
Secretos de tipo docker-registry
Los secretos de tipo docker-registry
se utilizan para almacenar credenciales de acceso a un registro de imágenes de Docker. Estos secretos permiten a Kubernetes autenticar y descargar imágenes privadas desde un registro.
Para crear un secreto de tipo docker-registry
, puedes usar el siguiente comando:
kubectl create secret docker-registry <nombre-secreto> \
--docker-username=<usuario> \
--docker-password=<contraseña> \
--docker-email=<email>
Secretos de tipo tls
Los secretos de tipo tls
se utilizan para almacenar certificados TLS y claves privadas. Estos secretos son esenciales para habilitar conexiones seguras (HTTPS) en aplicaciones desplegadas en Kubernetes.
Para crear un secreto de tipo tls
, puedes usar el siguiente comando:
kubectl create secret tls <nombre-secreto> \
--cert=<ruta-al-certificado> \
--key=<ruta-a-la-clave-privada>
Configmaps
Dado el caracter efímero de un pod en kubernetes necesitamos algún método para compartir ficheros o información entre los contenedores dentro de un pod. Además, es muy habitual que crear contenedores agnósticos del entorno y luego pasarse su configuración de arranque en variables de entorno.
Ya sea por un caso, el otro, o ambos, los configmaps son la solución.
Crear un configmap con comandos
Para crear un config map usamos el siguiente comando:
kubectl create configmap <nombre> \
--from-literal=text=<texto> \
--from-file=<fichero> \
--from-file=<directorio>
Este nos permite importar información ya sea text en plano que introduzcamos en el comando (--from-literal=text=
), el contenido de un fichero (--from-file=
) o el contenido de un directorio completo (--from-file=
).
Podemos consultar el contenido de un configmap con el siguiente comando:
kubectl get configmap <nombre>
Aunque este solo nos mostrará el total de datos y su edad. Podemos obtener el contenido completo especificando la salida en formato yaml:
kubectl get configmap <nombre> -o yaml
Crear un configmap con yaml
Podríamos declararlo como un yaml para facilitar el almacenamiento de la configuración como código.
apiVersion: v1
kind: ConfigMap
metadata:
name: cars
namespace: default
data:
car.make: Opel
car.model: Astra
car.trim: OPC
Para guardar el configmap en el cluster podemos usar el comando:
kubectl create -f <configmap>.yaml
Usar configmap en un pod
Utilizar en el entorno de un pod
Podemos configurar el contenido de un configmap en un pod como variable de entorno así:
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name: nginx
image: nginx
env:
- name: <nombre de la variable de entorno>
valueFrom:
configMapKeyRef:
name: <nombre_configmap>
key: <clave a usar>
Esto nos permitiría importar una única clave del configmap.
También podríamos importar todo el contenido del configmap así:
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name: nginx
image: nginx
envFrom:
- configMapRef:
name: <nombre_configmap>
Cambiaríamos el configMapKeyRef
por configMapRef
y env
por envFrom
. Por último, borraríamos key
y valueFrom
datos que ya no tendríamos que especificar.
Montar como volumen en un pod
Podemos montar un configmap como un volumen en un pod. Esta sería una configuración de ejemplO:
apiVersion: v1
kind: Pod
metadata:
name: shell-demo
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: car-vol
mountPath: /etc/cars
volumes:
- name: car-vol
configMap:
name: cars
Borrar un configmap
Podemos elimitar este objeto de kubernetes con el comando:
kubectl delete
- Lista de vídeos en Youtube: Curso Kubernetes