DEV Community

Cover image for Kubernetes Secrets: How to Create, Use, and Manage Secrets
Avesh
Avesh

Posted on

Kubernetes Secrets: How to Create, Use, and Manage Secrets

Introduction

Sensitive information like API keys, database credentials, or SSH keys must be handled securely to protect your systems and data. Kubernetes Secrets provide a mechanism to manage such information effectively by decoupling sensitive data from application logic.

This article covers the fundamentals of Kubernetes Secrets, how to create and use them, and best practices for secure management. By the end, you'll be able to integrate Secrets into your applications securely and efficiently.


What Are Kubernetes Secrets?

A Kubernetes Secret is an object that stores sensitive data in key-value pairs. Unlike ConfigMaps, Secrets are designed specifically for confidential data, and their content is base64-encoded.

Why Use Secrets?

  • Security: Secrets are not visible in plaintext in configurations or logs.
  • Decoupling: Sensitive data is kept separate from application code and images.
  • Dynamic Updates: Secrets can be updated without requiring a container image rebuild.

Types of Data Managed by Secrets

Common examples of data stored in Kubernetes Secrets:

  • Database Credentials: Username and password for database access.
  • API Keys: Access keys for third-party services.
  • SSH Keys: Secure Shell keys for remote server access.
  • TLS Certificates: Certificates and private keys for HTTPS communication.
  • OAuth Tokens: Authentication tokens for services like GitHub or Google.

Creating a Secret in Kubernetes

1. Using the kubectl Command

Create a secret using literal values:

kubectl create secret generic my-secret \
  --from-literal=username=myuser \
  --from-literal=password=mypassword
Enter fullscreen mode Exit fullscreen mode

Verify the secret:

kubectl get secret my-secret -o yaml
Enter fullscreen mode Exit fullscreen mode

2. Defining Secrets in a YAML File

Define a Secret in secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  username: bXl1c2Vy  # Base64 encoded value of 'myuser'
  password: bXlwYXNzd29yZA==  # Base64 encoded value of 'mypassword'
Enter fullscreen mode Exit fullscreen mode

Create the Secret:

kubectl apply -f secret.yaml
Enter fullscreen mode Exit fullscreen mode

3. From a File

Create a file username.txt with the content myuser:

kubectl create secret generic file-secret --from-file=username=username.txt
Enter fullscreen mode Exit fullscreen mode

Using a Secret in Pods and Deployments

1. Accessing Secrets as Environment Variables

Define a Pod using the Secret:

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: app-container
    image: busybox
    command: ["sh", "-c", "echo $DB_USERNAME && echo $DB_PASSWORD && sleep 3600"]
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: username
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: password
  restartPolicy: Never
Enter fullscreen mode Exit fullscreen mode

Apply the Pod and view the output:

kubectl apply -f pod-env.yaml
kubectl logs secret-env-pod
Enter fullscreen mode Exit fullscreen mode

2. Mounting Secrets as Volumes

Define a Pod that mounts the Secret as a volume:

apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-pod
spec:
  containers:
  - name: app-container
    image: busybox
    command: ["sh", "-c", "cat /etc/secret-volume/username && cat /etc/secret-volume/password && sleep 3600"]
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secret-volume
  volumes:
  - name: secret-volume
    secret:
      secretName: my-secret
Enter fullscreen mode Exit fullscreen mode

Apply the Pod and inspect the mounted files:

kubectl apply -f pod-volume.yaml
kubectl exec -it secret-volume-pod -- ls /etc/secret-volume
kubectl exec -it secret-volume-pod -- cat /etc/secret-volume/username
Enter fullscreen mode Exit fullscreen mode

Managing Existing Secrets

Updating a Secret

To update a Secret, recreate it:

kubectl delete secret my-secret
kubectl create secret generic my-secret --from-literal=username=newuser --from-literal=password=newpassword
Enter fullscreen mode Exit fullscreen mode

Rolling Updates

If a Deployment uses Secrets, updating the Secret will not trigger a Pod restart. To ensure changes take effect, manually restart the Pods:

kubectl rollout restart deployment my-deployment
Enter fullscreen mode Exit fullscreen mode

Accessing Secrets in Applications

Secrets can be accessed programmatically using environment variables or mounted files. Here's an example in Python:

import os

username = os.getenv("DB_USERNAME")
password = os.getenv("DB_PASSWORD")

print(f"Username: {username}, Password: {password}")
Enter fullscreen mode Exit fullscreen mode

Best Practices for Managing Secrets

  1. Encrypt Secrets at Rest: Use encryption mechanisms like Kubernetes Encryption at Rest.
  2. Use RBAC: Restrict access to Secrets using Role-Based Access Control (RBAC).
  3. Avoid Hardcoding: Never hardcode sensitive data in application code.
  4. Automate Secret Rotation: Use tools like HashiCorp Vault or AWS Secrets Manager for automatic rotation.
  5. Audit Access: Regularly audit access logs for Secrets.
  6. Namespace Isolation: Create Secrets in the same namespace as their consumers.

Hands-On Tutorial: Deploying a Sample Application

Step 1: Create a Secret

kubectl create secret generic sample-secret --from-literal=username=appuser --from-literal=password=apppassword
Enter fullscreen mode Exit fullscreen mode

Step 2: Deploy a Sample App

Create a deployment.yaml file:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: app-container
        image: nginx
        env:
        - name: APP_USERNAME
          valueFrom:
            secretKeyRef:
              name: sample-secret
              key: username
Enter fullscreen mode Exit fullscreen mode

Apply the Deployment:

kubectl apply -f deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Step 3: Verify the Secret

Access the Pod:

kubectl exec -it <pod-name> -- printenv | grep APP_USERNAME
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Common Issues

  1. Base64 Encoding Errors: Ensure all values in YAML files are base64-encoded.
  2. Access Denied: Check RBAC policies to ensure the Pod has access to the Secret.
  3. Missing Keys: Verify the key names in the Secret definition match those used in Pod specifications.

Conclusion

Kubernetes Secrets provide a secure and efficient way to manage sensitive information in containerized applications. By following the practices outlined in this guide, you can ensure the security and integrity of your applications while simplifying configuration management. Start incorporating Secrets into your Kubernetes projects today!

For further learning, refer to the official Kubernetes Secrets documentation.

Top comments (0)