Skip to main content
In this guide, you will learn how to encrypt secret data at rest in Kubernetes. Based on the official Kubernetes documentation, this tutorial walks you through the storage of secret objects, inspecting them in etcd, and configuring encryption at rest to secure sensitive data.
In the beginning, launch a Kubernetes playground running a single-node cluster based on Kubernetes and ContainerD.
The image shows a Kubernetes documentation table comparing encryption methods, detailing their strength, speed, key length, and considerations.
Once the playground is up, open the terminal.
The image shows a KodeKloud Kubernetes Playground interface with instructions and a terminal for practicing Kubernetes commands.

Creating a Secret Object

Kubernetes secrets help to store sensitive data such as passwords, tokens, or keys. There are multiple methods to create a secret object, including from files, literals, or environment variable files. Below are some examples:
Additional options include:
  • —allow-missing-template-keys=true: Ignores errors in templates if fields or keys are missing.
  • —append-hash=false: Appends a hash of the secret to its name.
  • —dry-run: Specify “none”, “server”, or “client” to perform a dry run or see what object would be sent.
For this demonstration, a secret is created with a literal value:
The output confirms the creation:
You can inspect the secret details with:
To view the secret in YAML format, use:
Example YAML output:
If you decode the base64-encoded value, you will obtain the cleartext secret:
Output:
Because secrets are stored as base64 encoded plaintext, anyone with access to etcd can decode and view them. Avoid storing secret definition files in public repositories without further protection.

Inspecting Secret Data in etcd

Next, examine how Kubernetes stores secrets in etcd, where the data is kept unencrypted by default. To inspect the stored secrets, use the etcdctl utility with API version 3.
  1. Start by verifying that etcd is running on your cluster:
    You should see an etcd pod (for example, “etcd-controlplane”).
  2. Confirm the existence of the certificate file:
  3. If etcdctl is not installed, install it using:
  4. Set the ETCDCTL_API to version 3 and check the etcdctl version:
  5. Retrieve and inspect your secret stored in etcd. Adjust the key path to match your secret (e.g., “my-secret”):
The output will display a hex dump showing the secret fields, including the cleartext value (“supersecret”), confirming that etcd stores the data unencrypted.

Configuring Encryption at Rest

To secure secret data, enable encryption at rest in etcd. Begin by verifying whether encryption is already configured in your cluster. Check the Kube API server for the “encryption-provider-config” flag:
If no output is returned, encryption is not yet enabled.
  1. Inspect the API server manifest, typically located in:
  2. Open the kube-apiserver manifest:
Since encryption is missing from the configuration, create an encryption configuration file and update the kube-apiserver manifest accordingly.

Encryption Configuration File

Create a YAML file (for example, enc.yaml) with the following content. This configuration specifies that secret objects will be encrypted using the AESCBC provider:
Generate a 32-byte random key and encode it in base64 using:
Replace INSERT_BASE64_ENCODED_32_BYTE_KEY_HERE with the generated key. Move the enc.yaml file to your control plane node:

Updating the Kube API Server Manifest

Edit the kube-apiserver manifest (/etc/kubernetes/manifests/kube-apiserver.yaml) to apply the encryption configuration:
  1. Append the following flag to reference the encryption configuration file:
  2. Under the volumeMounts section of the kube-apiserver container, add:
  3. Under the volumes section, add a hostPath volume:
A simplified excerpt of the manifest changes:
After saving your changes, the kube-apiserver will automatically restart and apply the new encryption settings.

Verifying Encryption

Once the API server has restarted with the new encryption configuration, create a new secret so it will be encrypted on write:
Verify that the secret is created:
Now, inspect the new secret in etcd:
The output will confirm that the secret value (“topsecret”) is no longer plainly visible because it is now encrypted.
Note that secrets created before enabling encryption remain unencrypted until updated. To re-encrypt these, fetch and replace them without modifying the data:

Summary

This article demonstrated how to:
  1. Create and inspect Kubernetes secrets.
  2. Verify that secrets are stored in etcd as base64-encoded plaintext.
  3. Enable encryption at rest by creating an encryption configuration file.
  4. Update the kube-apiserver manifest to integrate the encryption config.
  5. Confirm that new secrets are encrypted and secure in etcd.
Encrypting secret data at rest is essential for protecting sensitive information from unauthorized access. Remember that encryption applies only to future changes unless existing secrets are updated. Thank you for following this guide on encrypting Kubernetes secrets at rest!

Watch Video