Saltar al contenido principal

Capítulo 5.2 - Secrets

Objetivos de Aprendizaje​

Al final de este capítulo, usted será capaz de:

  • Comprender qué es un Secret y por qué utilizarlo
  • Crear Secrets de diferentes maneras
  • Usar Secrets en sus Pods de forma segura
  • Comprender las limitaciones de seguridad de los Secrets
  • Aplicar buenas prácticas para la gestión de secrets

Introducción​

Los Secrets son similares a los ConfigMaps pero están diseñados para almacenar datos sensibles como contraseñas, tokens de API, claves privadas y certificados.

Importante: Los Secrets de Kubernetes no están cifrados por defecto. Solo están codificados en base64.


¿Qué es un Secret?​

Un Secret es un objeto de Kubernetes que almacena datos sensibles. Por defecto, los Secrets están codificados en base64 (no cifrados).

Tipos de Secrets​

Kubernetes soporta varios tipos de Secrets:

  • Opaque: Datos arbitrarios (por defecto)
  • kubernetes.io/dockerconfigjson: Credenciales para registros Docker
  • kubernetes.io/tls: Certificados TLS
  • kubernetes.io/service-account-token: Tokens de Service Account

¿Por qué Usar Secrets?​

Problemas Sin Secrets​

Problemas:

  • Contraseñas hardcodeadas en el código
  • Riesgo de exposición en Git
  • Difícil de rotar
  • Sin gestión centralizada

Ventajas Con Secrets​

Ventajas:

  • Separados del código de la aplicación
  • Gestión centralizada
  • Rotación facilitada
  • Integración con herramientas externas (Vault, etc.)

Creación de Secrets​

Método 1: Desde Literales​

kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=secretpassword123

Método 2: Desde un Archivo​

Crear un archivo password.txt:

mysecretpassword
kubectl create secret generic db-secret \
--from-file=password=password.txt

Método 3: Desde un Archivo YAML​

apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # base64 de "admin"
password: cGFzc3dvcmQxMjM= # base64 de "password123"

Importante: Los valores en data deben estar codificados en base64.

Para codificar:

echo -n "admin" | base64
# Resultado: YWRtaW4=

Tipos de Secrets Especializados​

Secret Docker Registry​

Para acceder a un registro Docker privado:

kubectl create secret docker-registry regcred \
--docker-server=docker.io \
--docker-username=myuser \
--docker-password=mypassword \
--docker-email=myuser@example.com

Uso en un Pod:

spec:
containers:
- name: app
image: private-registry.io/myapp:1.0
imagePullSecrets:
- name: regcred

Secret TLS​

Para certificados SSL/TLS:

kubectl create secret tls tls-secret \
--cert=tls.crt \
--key=tls.key

Uso en los Pods​

Método 1: Variables de Entorno (Una Clave)​

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: my-app:1.0
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password

Método 2: Todas las Claves (envFrom)​

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: my-app:1.0
envFrom:
- secretRef:
name: db-secret

Método 3: Como Volumen (Archivos)​

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: secrets
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secrets
secret:
secretName: db-secret
defaultMode: 0400 # Permisos: solo lectura

Resultado: Cada clave se convierte en un archivo en /etc/secrets/ con el valor decodificado.


Seguridad de los Secrets​

Limitaciones Importantes​

Importante:

  • Los Secrets están codificados en base64, no cifrados
  • Accesibles para cualquiera que tenga acceso a etcd
  • Visibles con kubectl get secret -o yaml
  • Los logs pueden exponer los secrets

Buenas Prácticas de Seguridad​

  1. Activar el Cifrado en Reposo

Crear un archivo encryption-config.yaml:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-secret>
- identity: {} # Permite el descifrado
  1. Usar External Secrets Operator

Para integrar con Vault, AWS Secrets Manager, etc.

  1. RBAC Restringido

Limitar el acceso a los Secrets con RBAC:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["db-secret"]
verbs: ["get"]
  1. Nunca Comitear los Secrets
  • Usar .gitignore para los archivos de secrets
  • Usar herramientas de gestión de secrets
  • Rotación regular

Ejemplo Completo​

Paso 1: Crear el Secret​

apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
database_url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc0BkYjoxMjM0L215ZGI=
api_key: c2VjcmV0X2FwaV9rZXlfMTIzNDU2
jwt_secret: bXlfanN0X3NlY3JldF9rZXlfZm9yX3NpZ25pbmc=

Paso 2: Usar en un Deployment​

apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: my-app:1.0
envFrom:
- secretRef:
name: app-secrets
volumeMounts:
- name: certs
mountPath: /etc/ssl/certs
readOnly: true
volumes:
- name: certs
secret:
secretName: tls-secret
defaultMode: 0400

Comandos Útiles​

Ver un Secret (Codificado)​

kubectl get secret db-secret
kubectl describe secret db-secret
kubectl get secret db-secret -o yaml

Decodificar un Secret​

# Ver el valor decodificado
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d

Modificar un Secret​

kubectl edit secret db-secret

Nota: Los valores deben estar en base64 en el editor.

Eliminar un Secret​

kubectl delete secret db-secret

Rotación de Secrets​

Proceso de Rotación​

Pasos:

  1. Crear un nuevo Secret con un nombre diferente
  2. Actualizar el Deployment para referenciar el nuevo Secret
  3. Esperar a que los Pods se reinicien
  4. Eliminar el Secret antiguo

External Secrets Operator​

Para una gestión avanzada con herramientas externas:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-secret
spec:
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: db-secret
data:
- secretKey: password
remoteRef:
key: production/database/password

Resumen​

En este capítulo, usted ha aprendido:

Secret: Objeto de Kubernetes para datos sensibles (base64, no cifrado por defecto)
Tipos: Opaque, docker-registry, TLS, service-account-token
Creación: kubectl create, YAML con valores base64
Uso: Variables de entorno o volúmenes
Seguridad: Activar cifrado en reposo, RBAC, External Secrets
Limitaciones: Solo base64, visible en etcd, logs
Rotación: Crear nuevo secret, actualizar, eliminar el antiguo


Próximos Pasos​

Capítulo 5.3: Inyección en los Pods
Capítulo 5.4: Buenas Prácticas
Lab 5.2: Gestión de Secrets


Capítulo creado el: Diciembre 2024