La mayoría de las aplicaciones implementadas a través de Kubernetes requieren acceso a bases de datos, servicios y otros recursos ubicados externamente. La forma más fácil de administrar la información de inicio de sesión necesaria para acceder a esos recursos es usar los secretos de Kubernetes. Los secretos ayudan a organizar y distribuir información confidencial en un clúster.
Un secreto de Kubernetes es un objeto que almacena datos confidenciales, como nombres de usuario, contraseñas, tokens y claves. El sistema crea secretos durante la instalación de una aplicación o los usuarios cuando necesitan almacenar información confidencial y ponerla a disposición de un pod.
Si las contraseñas, los tokens o las claves fueran simplemente parte de una definición de pod o una imagen de contenedor, podrían quedar expuestos accidentalmente durante las operaciones de Kubernetes. Por lo tanto, la función más importante del secreto es evitar la exposición accidental de la información almacenada en él y, al mismo tiempo, hacerla disponible donde el usuario la necesite.
Los secretos incorporados vienen en varios tipos, correspondientes a escenarios de uso populares:
Tipo incorporado | Descripción |
Opaque | Este es el tipo predeterminado de secreto. Los secretos cuyo archivo de configuración no contiene la declaración de tipo se consideran todos de este tipo. Los secretos opacos están diseñados para almacenar datos de usuarios arbitrarios. |
kubernetes.io/service-account-token | Los secretos de token de cuenta de servicio almacenan tokens que identifican cuentas de servicio. Tras la creación de un pod, Kubernetes crea automáticamente este secreto y lo asocia con el pod, lo que permite un acceso seguro a la API. Este comportamiento se puede desactivar. |
kubernetes.io/dockercfg | El acceso a un registro de Docker para imágenes requiere credenciales de Docker válidas. Este tipo de secreto se utiliza para almacenar un ~/.dockercfg serializado formato heredado para la configuración de la línea de comandos de Docker. Contiene el .dockercfg codificado en base64 clave. |
kubernetes.io/dockerconfigjson | Este tipo de secreto presenta un .dockerconfigjson key, que es una versión codificada en base64 de ~/.docker/config.json archivo, una nueva versión del obsoleto .dockercfg . |
kubernetes.io/basic-auth | El secreto para almacenar datos básicos de autenticación. Debe contener dos claves:username y password . |
kubernetes.io/ssh-auth | Para almacenar los datos necesarios para establecer una conexión SSH, use ssh-auth tipo. El campo de datos de este tipo debe contener una ssh-privatekey par clave-valor. |
kubernetes.io/tls | Este tipo se utiliza para almacenar claves y certificados TLS. El escenario de uso más común es la terminación de recursos de Ingress, pero tls El tipo también se usa a veces con otros recursos. |
bootstrap.kubernetes.io/token | Los tokens utilizados durante el proceso de arranque del nodo se almacenan utilizando el tipo secreto de token. Este tipo generalmente se crea en el kube-system espacio de nombres. |
Para definir un tipo de secreto personalizado, asigne una cadena no vacía como valor en el type
campo del archivo secreto. Si deja el campo vacío, le indicará a Kubernetes que asuma el Opaque
tipo. El tipo personalizado libera el secreto de las restricciones que plantean los tipos integrados.
Uso de los secretos de Kubernetes
Cuando crea un secreto, el pod que lo usará debe hacer referencia a él. Para hacer que un secreto esté disponible para un pod:
1. Monte el secreto como un archivo en un volumen disponible para cualquier cantidad de contenedores en un pod.
2. Importe el secreto como una variable de entorno a un contenedor.
3. Usa kubelet y imagePullSecrets
campo.
Las siguientes secciones explican cómo crear secretos de Kubernetes, así como también cómo decodificarlos y acceder a ellos.
Crear secretos de Kubernetes
Para crear un secreto de Kubernetes, aplique uno de los siguientes métodos:
- Usar
kubectl
para un enfoque basado en la línea de comandos.
- Cree un archivo de configuración para el secreto.
- Utilice un generador, como Kustomize, para generar el secreto.
Crear secretos usando kubectl
1. Para comenzar a crear un secreto con kubectl
, primero cree los archivos para almacenar la información confidencial:
echo -n '[username]' > [file1]
echo -n '[password]' > [file2]
El -n
opción le dice a echo
no agregar una nueva línea al final de la cadena. La nueva línea también se trata como un carácter, por lo que se codificaría junto con el resto de los caracteres, produciendo un valor codificado diferente.
2. Ahora, usa kubectl
para crear un secreto utilizando los archivos del paso anterior. Use el subcomando genérico para crear un Opaque
secreto. Además, agregue el --from-file
opción para cada uno de los archivos que desea incluir:
kubectl create secret generic [secret-name] \
--from-file=[file1] \
--from-file=[file2]
El resultado confirma la creación del secreto:
3. Para proporcionar claves para los valores almacenados en el secreto, use la siguiente sintaxis:
kubectl create secret generic [secret-name] \
--from-file=[key1]=[file1] \
--from-file=[key2]=[file2]
4. Verifique que el secreto se haya creado correctamente escribiendo:
kubectl get secrets
El comando muestra la lista de secretos disponibles:sus nombres, tipos, número de valores de datos que contienen y su antigüedad:
Crear secretos en un archivo de configuración
1. Para crear un secreto especificando la información necesaria en un archivo de configuración, comience codificando los valores que desea almacenar:
echo -n '[value1]' | base64
echo -n '[value2]' | base64
2. Ahora crea un archivo yaml usando un editor de texto. El archivo debería verse así:
apiVersion: v1
kind: Secret
metadata:
name: newsecret
type: Opaque
data:
username: dXNlcg==
password: NTRmNDFkMTJlOGZh
3. Guarde el archivo y use kubectl apply
comando para crear el secreto:
kubectl apply -f [file]
Crear secreto de Kubernetes con generadores
Los generadores como Kustomize ayudan a generar secretos rápidamente.
1. Para crear un secreto con Kustomize, cree un archivo llamado kustomization.yaml
y formatéalo de la siguiente manera:
secretGenerator:
- name: db-credentials
files:
- username.txt
- password.txt
El ejemplo anterior indica db-credentials
como el nombre del secreto y usa dos archivos creados previamente, username.txt
y password.txt
, como valores de datos.
2. Alternativamente, para proporcionar la versión literal sin cifrar de los valores de datos, incluya los literals
sección con pares clave-valor que desea almacenar:
secretGenerator:
- name: db-credentials
literals:
- username=user
- password=54f41d12e8fa
3. Guarde el archivo y use el siguiente comando en la carpeta donde kustomization.yaml
se encuentra:
kubectl apply -k .
El resultado confirma la creación del secreto:
Use kubectl describe para ver los secretos creados
El kubectl describe
El comando muestra información básica sobre los objetos de Kubernetes. Úselo para ver la descripción de un secreto.
kubectl describe secrets/[secret]
El primer ejemplo muestra el secreto creado al proporcionar archivos como valores de datos:
El segundo ejemplo describe el secreto creado usando literales de cadena. Observe el cambio en los Data
sección, que ahora muestra los nombres de las claves en lugar de los nombres de los archivos:
Descifrar secretos
1. Para decodificar los valores de un secreto, acceda a ellos escribiendo el siguiente comando:
kubectl get secret [secret] -o jsonpath='{.data}'
El resultado muestra los pares clave-valor codificados almacenados en la sección de datos:
2. Utilice el comando echo para escribir la cadena codificada y canalizar la salida a base64
comando:
echo '[encoded-value]' | base64 --decode
Las cadenas decodificadas aparecen como salida:
Secretos de acceso cargados en un volumen
1. Para acceder a secretos montados en un pod en un volumen separado, modifique la definición del pod para incluir un nuevo volumen. Elija cualquier nombre de volumen que desee, pero asegúrese de que sea el mismo que el nombre del objeto secreto.
2. Asegúrese de especificar readOnly
como verdadero Por ejemplo, la definición del pod puede verse así:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: redis
volumeMounts:
- name: newsecret
mountPath: “/etc/newsecret”
readOnly: true
volumes:
- name: newsecret
secret:
secretName: newsecret
2. Abra otra instancia de terminal y use kubectl exec
Comando para acceder al shell bash del pod:
kubectl exec -it [pod] -- /bin/bash
3. cd
en /etc/newsecret
y busque los archivos contenidos en el secreto:
cd /etc/newsecret
Proyectar secretos en un contenedor utilizando variables de entorno
1. Otra forma de acceder a secretos en un pod de Kubernetes es importarlos como variables de entorno modificando la definición del pod para incluir referencias a ellos. Por ejemplo:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: secret-env-pod
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: newsecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: newsecret
key: password
restartPolicy: Never
2. Utilice kubectl exec
de nuevo para chocar contra una vaina.
3. Pruebe la variable de entorno usando echo
comando:
echo $[VARIABLE]
La salida del comando muestra el valor asignado a la variable:
Usar secretos para extraer imágenes de Docker de registros privados de Docker
1. Para utilizar los registros privados de Docker, primero debe iniciar sesión en Docker:
docker login
2. Cuando se le solicite, proporcione sus credenciales de inicio de sesión:
3. Si el inicio de sesión es exitoso, Docker actualiza el config.json
archivo con sus datos. Use el comando cat para ver el archivo:
cat ~/.docker/config.json
Las auths
contiene el auth
clave, que es una versión codificada de las credenciales de Docker.
4. Usa kubectl
para crear un secreto, proporcionando la ubicación de config.json
archivo y el tipo de secreto:
kubectl create secret generic [secret] \
--from-file=.dockerconfigjson=./.docker/config.json \
--type=kubernetes.io/dockerconfigjson
Alternativamente, realice todos los pasos anteriores, incluido el inicio de sesión en Docker, en la misma línea:
kubectl create secret docker-registry [secret] --docker-server:[address] --docker-username=[username] --docker-password=[password] --docker-email=[email]
5. Para crear un pod que tenga acceso a este secreto, cree un yaml
archivo que lo define. El archivo debería verse así:
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image:
imagePullSecrets:
- name: regcred
6. Termine de crear el pod activándolo con kubectl apply
:
kubectl apply -f [file]
Consideraciones sobre los secretos de Kubernetes
Secretos de Kubernetes son una forma segura de almacenar información confidencial. Sin embargo, antes de decidir cuál es el mejor método para su escenario de uso, debe considerar los siguientes puntos:
- Los nombres de usuario y las contraseñas en Secrets están codificados con base-64. Esta técnica de codificación de texto oculta los datos y evita la exposición accidental, pero no es segura contra ataques cibernéticos maliciosos.
- Los secretos solo están disponibles en el clúster en el que se encuentran.
- Los secretos generalmente se basan en una llave maestra que se usa para desbloquearlos a todos. Si bien existen métodos para asegurar la clave maestra, usarlos solo crea otro escenario de clave maestra.
Para mitigar estos problemas, aplique algunas de las siguientes soluciones:
- Integre una herramienta de administración de secretos que use la cuenta del servicio Kubernetes para autenticar a los usuarios que necesitan acceso a la bóveda secreta.
- Integre una herramienta IAM (Administración de identidad y acceso) para permitir que el sistema use tokens de un Servicio de token seguro.
- Integre un administrador de secretos de terceros en los pods.