Chapter 5.2 - Secrets
Learning Objectives
By the end of this chapter, you will be able to:
- Understand what a Secret is and why to use it
- Create Secrets in different ways
- Use Secrets in your Pods securely
- Understand the security limitations of Secrets
- Apply best practices for secret management
Introduction
Secrets are similar to ConfigMaps but are designed to store sensitive data such as passwords, API tokens, private keys, and certificates.
Important: Kubernetes Secrets are not encrypted by default. They are only base64-encoded.
What is a Secret?
A Secret is a Kubernetes object that stores sensitive data. By default, Secrets are base64-encoded (not encrypted).
Secret Types
Kubernetes supports several types of Secrets:
- Opaque: Arbitrary data (default)
- kubernetes.io/dockerconfigjson: Credentials for Docker registries
- kubernetes.io/tls: TLS certificates
- kubernetes.io/service-account-token: Service Account tokens
Why Use Secrets?
Problems Without Secrets
Problems:
- Passwords hardcoded in the code
- Risk of exposure in Git
- Difficult to rotate
- No centralized management
Advantages With Secrets
Advantages:
- Separated from application code
- Centralized management
- Easier rotation
- Integration with external tools (Vault, etc.)
Creating Secrets
Method 1: From Literals
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=secretpassword123
Method 2: From a File
Create a password.txt file:
mysecretpassword
kubectl create secret generic db-secret \
--from-file=password=password.txt
Method 3: From a YAML File
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # base64 of "admin"
password: cGFzc3dvcmQxMjM= # base64 of "password123"
Important: Values in data must be base64-encoded.
To encode:
echo -n "admin" | base64
# Result: YWRtaW4=
Specialized Secret Types
Docker Registry Secret
To access a private Docker registry:
kubectl create secret docker-registry regcred \
--docker-server=docker.io \
--docker-username=myuser \
--docker-password=mypassword \
--docker-email=myuser@example.com
Usage in a Pod:
spec:
containers:
- name: app
image: private-registry.io/myapp:1.0
imagePullSecrets:
- name: regcred
TLS Secret
For SSL/TLS certificates:
kubectl create secret tls tls-secret \
--cert=tls.crt \
--key=tls.key
Usage in Pods
Method 1: Environment Variables (Single Key)
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
Method 2: All Keys (envFrom)
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: my-app:1.0
envFrom:
- secretRef:
name: db-secret
Method 3: As a Volume (Files)
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 # Permissions: read-only
Result: Each key becomes a file in /etc/secrets/ with the decoded value.
Secret Security
Important Limitations
Important:
- Secrets are base64-encoded, not encrypted
- Accessible to anyone with access to etcd
- Visible with
kubectl get secret -o yaml - Logs can expose secrets
Security Best Practices
- Enable Encryption at Rest
Create an encryption-config.yaml file:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-secret>
- identity: {} # Allows decryption
- Use External Secrets Operator
To integrate with Vault, AWS Secrets Manager, etc.
- Restrictive RBAC
Limit access to Secrets with RBAC:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["db-secret"]
verbs: ["get"]
- Never Commit Secrets
- Use
.gitignorefor secret files - Use secret management tools
- Regular rotation
Complete Example
Step 1: Create the Secret
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
database_url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc0BkYjoxMjM0L215ZGI=
api_key: c2VjcmV0X2FwaV9rZXlfMTIzNDU2
jwt_secret: bXlfanN0X3NlY3JldF9rZXlfZm9yX3NpZ25pbmc=
Step 2: Use in a 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
Useful Commands
View a Secret (Encoded)
kubectl get secret db-secret
kubectl describe secret db-secret
kubectl get secret db-secret -o yaml
Decode a Secret
# View the decoded value
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
Modify a Secret
kubectl edit secret db-secret
Note: Values must be in base64 in the editor.
Delete a Secret
kubectl delete secret db-secret
Secret Rotation
Rotation Process
Steps:
- Create a new Secret with a different name
- Update the Deployment to reference the new Secret
- Wait for Pods to restart
- Delete the old Secret
External Secrets Operator
For advanced management with external tools:
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
Summary
In this chapter, you learned:
Secret: Kubernetes object for sensitive data (base64, not encrypted by default)
Types: Opaque, docker-registry, TLS, service-account-token
Creation: kubectl create, YAML with base64 values
Usage: Environment variables or volumes
Security: Enable encryption at rest, RBAC, External Secrets
Limitations: Base64 only, visible in etcd, logs
Rotation: Create new secret, update, delete old one
Next Steps
Chapter 5.3: Injection into Pods
Chapter 5.4: Best Practices
Lab 5.2: Managing Secrets
Chapter created: December 2024