What is a Secret in Kubernetes?
In Kubernetes, a Secret is an object used to store and manage sensitive information, such as passwords, OAuth tokens, and SSH keys, securely. It helps keep confidential data separate from application code and Pod definitions, improving security and manageability.
What is a Kubernetes Secret?
Kubernetes Secrets are designed to hold confidential data that applications need, but which should not be exposed in plain text within Pod definitions or application images. By externalizing sensitive data, Secrets improve security posture and simplify application deployment and management.
Why Use Secrets?
- Security: Prevents sensitive data from being hardcoded into application images or YAML files, reducing the risk of accidental exposure.
- Separation of Concerns: Decouples confidential configuration data from application code, making applications more portable and easier to manage.
- Flexibility: Allows sensitive data to be updated independently of the application Pods, enabling seamless rotation of credentials without application downtime.
- Auditability: Kubernetes provides mechanisms to audit access to Secrets.
How Secrets Work
A Kubernetes Secret object stores data as key-value pairs. Each value is typically base64 encoded. It's crucial to understand that base64 encoding is *not* encryption; it's a reversible transformation. Therefore, additional security measures like etcd encryption at rest and Role-Based Access Control (RBAC) are essential to protect the Secret data.
Types of Secrets
Kubernetes supports several types of Secrets, but the most common is Opaque (generic) for arbitrary key-value pairs. Other types include kubernetes.io/tls for TLS certificates, kubernetes.io/dockerconfigjson for Docker registry authentication, and kubernetes.io/service-account-token for Service Account tokens.
Creating a Secret
Using `kubectl` from literal values
kubectl create secret generic my-db-secret \
--from-literal=username=dbuser \
--from-literal=password='s3cr3tP@ssw0rd!'
Using YAML (with `data`)
When defining Secrets directly in YAML using the data field, values must be base64 encoded.
apiVersion: v1
kind: Secret
metadata:
name: my-api-secret
type: Opaque
data:
api_key: YXBpa2V5dmFsdWU= # 'apikeyvalue' base64 encoded
token: c2VjcmV0dG9rZW4= # 'secrettoken' base64 encoded
Using YAML (with `stringData`)
Alternatively, stringData can be used to provide unencoded strings, which Kubernetes will encode automatically. This is generally preferred for readability.
apiVersion: v1
kind: Secret
metadata:
name: my-api-secret-stringdata
type: Opaque
stringData:
api_key: apikeyvalue
token: secrettoken
Consuming a Secret in a Pod
As Environment Variables
Secrets can be injected into a Pod's containers as environment variables using valueFrom.secretKeyRef.
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-env
spec:
containers:
- name: my-app-container
image: my-app-image
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: my-db-secret # Name of the Secret
key: username # Key within the Secret
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-db-secret
key: password
As Mounted Files
Secrets can also be mounted into a Pod's filesystem as files, making them accessible at a specified path. Each key in the Secret becomes a file in the mounted directory.
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod-vol
spec:
containers:
- name: my-app-container
image: my-app-image
volumeMounts:
- name: db-secret-volume
mountPath: "/etc/secrets/db" # Path where secrets will be mounted
readOnly: true
volumes:
- name: db-secret-volume
secret:
secretName: my-db-secret # Name of the Secret
# Optional: specify items to select specific keys and customize file names
# items:
# - key: username
# path: db_username
# - key: password
# path: db_password
Security Best Practices
- Encrypt etcd: Ensure the Kubernetes etcd database, where Secrets are stored, is encrypted at rest to protect them from unauthorized access.
- RBAC: Use Role-Based Access Control (RBAC) to limit who can read, create, or update Secret objects within your cluster.
- Restrict Access: Only mount Secrets into Pods that absolutely require them. Avoid mounting an entire Secret if only specific keys are needed (use
itemsinvolumeMounts). - External Secret Management: For robust production environments, consider integrating with external secret management solutions (e.g., HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) via CSI drivers or operators, which provide stronger encryption, auditing, and rotation capabilities.
- Never Commit to Git: Do not store Kubernetes Secret YAML files containing sensitive data (even base64 encoded) directly in version control systems. Use tools like
git-secret, Sealed Secrets, or Helm Secrets plugins for managing encrypted secrets in Git. - Rotate Secrets: Implement a strategy for regular rotation of sensitive credentials to minimize the impact of a potential compromise.