What is a Kubernetes Secret?
How does it work? Is it the same as AWS Secrets Manager?
A secret is a Kubernetes object used to store sensitive information such as passwords, API keys, tokens, and certificates. Instead of embedding these values directly in pod manifests (which would end up in version control), we store them in a secret and reference them from our pods.
Secrets are stored in base64-encoded format by default in etcd (the cluster’s backing store). It is worth noting that base64 is not encryption: it is simply an encoding. Anyone with access to the cluster can decode a secret. For proper security, we should enable encryption at rest or use an external secrets manager (such as HashiCorp Vault or AWS Secrets Manager).
There are a few ways to create a secret. One of them being from the command line:
kubectl create secret generic db-credentials \ --from-literal=username=admin \ --from-literal=password=s3cr3tThis creates a secret called db-credentials with two key-value pairs. We can also create secrets from a file (--from-file=credentials.yaml) or define them directly in a YAML manifest.
apiVersion: v1kind: Secretmetadata: name: db-credentialstype: Opaquedata: username: YWRtaW4= password:czNjcjN0Let’s have a closer look:
- type describes the kind of secret (Opaque is the generic type for arbitrary key-value pairs);
- data holds the actual secret values, base64-encoded (we can use
echo -n 'admin' | base64to encode a value).
There is also a stringData field that accepts plain text values (Kubernetes encodes them for us), which is more convenient for readability:
apiVersion: v1kind: Secretmetadata: name: db-credentialstype: OpaquestringData: username: admin password: s3cr3tWe can expose secrets to containers in two main ways:
- Environment variables: inject a secret value as an environment variable in the pod spec;
- Volume mounts: mount the secret as a file inside the container’s filesystem.
Here is an example using an environment variable:
apiVersion: v1kind: Podmetadata: name: my-appspec: containers: - name: my-app image: my-app:1.0 env: - name: DB_USERNAME valueFrom: secretKeyRef: name: db-credentials key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-credentials key: password