21 ‐ Kubernetes Secrets - CloudScope/DevOpsWithCloudScope GitHub Wiki
Kubernetes Secrets: Overview
In Kubernetes, Secrets are used to store and manage sensitive information, such as passwords, OAuth tokens, SSH keys, and API keys. Secrets are similar to ConfigMaps but with additional security features, such as the ability to encrypt data at rest. Unlike ConfigMaps, which are used for non-sensitive configuration, Secrets provide a more secure way to store and access sensitive data within Kubernetes clusters.
Key Features of Kubernetes Secrets
-
Sensitive Data Storage:
- Secrets allow you to store sensitive data like database credentials, application keys, private certificates, and other secrets that should not be exposed directly in code, configuration files, or container images.
-
Base64 Encoding:
- Kubernetes stores secret data in base64-encoded form. This encoding is not encryption, but simply an encoding format to make the data easier to store as text. The data is still considered sensitive, so Kubernetes provides features like encryption at rest to protect it.
-
Encryption at Rest:
- Kubernetes supports encryption at rest for secrets, which ensures that sensitive data is encrypted when stored in etcd, the key-value store used by Kubernetes. This encryption is enabled by configuring the
EncryptionConfiguration
on the Kubernetes API server.
- Kubernetes supports encryption at rest for secrets, which ensures that sensitive data is encrypted when stored in etcd, the key-value store used by Kubernetes. This encryption is enabled by configuring the
-
Access Control:
- Kubernetes uses RBAC (Role-Based Access Control) to restrict who can access or modify Secrets. By applying appropriate permissions, you can ensure that only authorized users or Pods can access the secret data.
-
Automatic Mounting:
- Secrets can be mounted into Pods as environment variables or files, which allows the application running in the Pod to access them easily without storing them in the image or configuration files.
When to Use Kubernetes Secrets
- Storing sensitive information: For credentials such as database passwords, API tokens, private keys, and certificates.
- Environment-specific secrets: When managing different secrets for different environments (e.g., development, production).
- Secure storage of sensitive configuration data: For example, SSH keys or cloud provider access keys.
- Secure handling of application secrets: For services or applications that require a secure means of accessing credentials or tokens.
Creating a Secret
-
Using
kubectl
(Literal Values): You can create a secret from literal key-value pairs directly using thekubectl
command:kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=secretpassword
-
Using a File: You can create a secret from a file, where the file's contents will be stored as the value of a key.
kubectl create secret generic my-secret --from-file=ssh-privatekey=/path/to/ssh/key
-
Using a Directory: You can create a secret from a directory where each file in the directory will be treated as a key, and its content will be the value.
kubectl create secret generic my-secret --from-file=/path/to/config-dir/
-
Using a YAML Definition: You can define a Secret in a YAML file, which is especially useful for more complex scenarios.
Example:
apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque data: username: YWRtaW4= # base64-encoded value of 'admin' password: c2VjcmV0cGFzc3dvcmQ= # base64-encoded value of 'secretpassword'
Apply the YAML to create the Secret:
kubectl apply -f secret.yaml
Note: In the YAML definition, sensitive data like
username
andpassword
should be base64-encoded.
Consuming Secrets
You can consume Kubernetes Secrets in Pods in several ways:
-
As Environment Variables: You can reference a Secret and expose its keys as environment variables inside your container.
Example:
apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image: myapp:latest envFrom: - secretRef: name: my-secret
In this example, the keys in the
my-secret
Secret will be exposed as environment variables within the container. -
As Volume Mounts: You can mount a Secret as a volume, where each key in the Secret becomes a file and the file's content is the corresponding value.
Example:
apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image: myapp:latest volumeMounts: - name: secret-volume mountPath: /etc/secrets volumes: - name: secret-volume secret: secretName: my-secret
In this example, the keys from
my-secret
will be mounted as files in the/etc/secrets
directory inside the container. Each key will become a file, and the value will be the file's content. -
As Command-Line Arguments: Secrets can also be passed as command-line arguments to containers by referencing the Secret's data in the command line.
Example:
apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image: myapp:latest args: - "--username=$(USERNAME)" - "--password=$(PASSWORD)" env: - name: USERNAME valueFrom: secretKeyRef: name: my-secret key: username - name: PASSWORD valueFrom: secretKeyRef: name: my-secret key: password
Updating a Secret
Updating a Secret in Kubernetes is straightforward. You can edit the Secret by modifying its values, either using kubectl
or by updating the YAML file.
-
Using
kubectl
: You can update a Secret using thekubectl create secret
command with the--dry-run
and-o yaml
flags to generate the updated Secret definition, and then apply it:kubectl create secret generic my-secret --from-literal=username=newuser --from-literal=password=newpassword --dry-run=client -o yaml | kubectl apply -f -
-
Direct Editing: You can also directly edit a Secret using
kubectl edit
:kubectl edit secret my-secret
This will open the Secret in your default text editor, where you can make changes and save.
Note: After updating a Secret, Pods that consume it will not automatically reload the updated values. You may need to restart the Pods to pick up the new Secret values.
Best Practices for Kubernetes Secrets
-
Enable Encryption at Rest: Ensure that Secrets are encrypted at rest by configuring the
EncryptionConfiguration
on your Kubernetes API server. This ensures that even if someone gains access to etcd, they cannot easily view the secret data. -
Access Control: Use Role-Based Access Control (RBAC) to restrict access to Secrets. Only authorized users, service accounts, or Pods should have access to sensitive data.
-
Avoid Exposing Secrets in Logs or UI: Be mindful of where you expose Secrets. Avoid printing them in logs, UI, or other locations where they might be accidentally leaked.
-
Use Secrets for Sensitive Information Only: Use Secrets for truly sensitive information (e.g., passwords, tokens), and use ConfigMaps for non-sensitive data.
-
Rotate Secrets Regularly: Regularly rotate Secrets to minimize the risk of them being compromised. Implement automation for rotating credentials and secrets.
-
Limit the Size of Secrets: Kubernetes imposes limits on the size of objects stored in etcd. If you store large amounts of data in a Secret, it might impact Kubernetes performance or stability.