What are Kubernetes Secrets?
Secrets Purpose
- Store and manage sensitive information securely
- Keep passwords, OAuth tokens, SSH keys, and other credentials safe
- Decouple sensitive data from application code
- Can be mounted as files or exposed as environment variables
- Provide better security than ConfigMaps for sensitive data
Important Security Note
Secrets are stored as base64 encoded strings in etcd
Base64 encoding is NOT encryption - secrets are not secure by default
Base64 encoding is easily reversible - anyone with access to the Secret can decode it
Built-in Secret Types
Opaque
Arbitrary user-defined data (default type)
kubernetes.io/service-account-token
Service account token
kubernetes.io/dockercfg
Serialized ~/.dockercfg file
kubernetes.io/dockerconfigjson
Serialized ~/.docker/config.json file
kubernetes.io/basic-auth
Credentials for basic authentication
kubernetes.io/ssh-auth
Credentials for SSH authentication
kubernetes.io/tls
Data for a TLS client or server
bootstrap.kubernetes.io/token
Bootstrap token data
Opaque Secrets - Most Common Use Case
Opaque is the default Secret type when no type is specified. Use it for custom application secrets like database passwords, API keys, and other sensitive configuration data.
Security Considerations
Should You Use Kubernetes Secrets?
Consider your security requirements: Native Kubernetes Secrets provide basic security but have limitations. Evaluate if they meet your organization's security standards.
Protection Measures
- Enable Encryption at Rest: Encrypt Secret data in etcd
- Use RBAC Authorization Policies: Restrict access to Secrets
- Limit Secret Access: Only necessary users and service accounts
- Enable Audit Logging: Monitor Secret access and modifications
- Use Network Policies: Restrict pod-to-pod communication
External Secret Management
For enhanced security, consider storing secrets in dedicated external systems:
vaultproject.io
Benefits of External Secrets
- Proper encryption and key management
- Fine-grained access controls
- Audit trails and compliance
- Secret rotation capabilities
- Centralized management
kubectl Secrets Commands
Imperative Creation
--from-literal=STATE=Michigan
Create Secret directly from command line literals
Declarative Creation
Create Secret from YAML manifest file
List Secrets
List all Secrets in the current namespace
Save as YAML
Export Secret configuration to YAML file
Delete Secret (YAML)
Delete Secret using YAML file
Delete Secret (Name)
Delete Secret using resource name
Complete Secrets Example
Secret Definition
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
namespace: production
labels:
app: webapp
env: production
type: Opaque
data:
# Base64 encoded values
database-password: cGFzc3dvcmQxMjM=
api-key: YXBpLWtleS1zZWNyZXQ=
jwt-secret: anN0LXNlY3JldC1rZXk=
# Config file with sensitive data
config.properties: |
ZGF0YWJhc2UudXJsPWpkYmM6cG9zdGdyZXNxbDovL2RiOjU0MzIvYXBw
ZGF0YWJhc2UudXNlcm5hbWU9YXBwX3VzZXI=
Deployment Using Secret
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: myapp:latest
ports:
- containerPort: 8080
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: database-password
- name: API_KEY
valueFrom:
secretKeyRef:
name: app-secrets
key: api-key
volumeMounts:
- name: secret-volume
mountPath: /app/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: app-secrets
items:
- key: config.properties
path: application.properties
Creating the Secret (Step by Step)
1. Encode Values
# Output: cGFzc3dvcmQxMjM=
2. Create Secret
3. Verify Secret
kubectl describe secret app-secrets
TLS Secret Example
Creating TLS Secret
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi...
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS...
TLS secrets require the certificate and private key in base64 format
Imperative TLS Secret Creation
--cert=path/to/cert.pem \
--key=path/to/key.pem
kubectl automatically handles base64 encoding for TLS secrets
Using TLS Secret in Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts:
- myapp.example.com
secretName: tls-secret
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp-service
port:
number: 80
Secrets Best Practices
Security & Access Control
- Enable etcd encryption for Secrets at rest
- Use RBAC policies to restrict Secret access
- Limit Secret exposure to necessary namespaces only
- Regularly rotate Secrets especially credentials and keys
- Use external secret management for high-security environments
- Avoid logging Secret values in application logs
Operations & Management
- Use specific Secret types (TLS, dockerconfigjson, etc.) when applicable
- Store Secret manifests securely or use tools like Sealed Secrets
- Implement Secret rotation procedures without downtime
- Monitor Secret access through audit logs
- Use dedicated ServiceAccounts for applications needing Secrets
- Consider using CSI Secret Store driver for external secrets
When to Use Native Secrets vs External Solutions
Use Native Secrets For:
- Development and testing environments
- Non-critical applications
- When etcd encryption is enabled
- Simple credential management
- TLS certificates for Ingress
Use External Solutions For:
- Production environments with compliance requirements
- Applications requiring secret rotation
- Centralized secret management across clusters
- Fine-grained access control needs
- Audit and compliance requirements