☸️ Kubernetes Q13 / 20

What is a Secret in Kubernetes?

AI-Powered Answer ✓ Answered

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

bash
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.

yaml
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.

yaml
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.

yaml
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.

yaml
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 items in volumeMounts).
  • 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.