Introduction to Kubernetes Secrets
In Kubernetes, Pods need to communicate to produce the desired results and process the data generated from each other. For this, obviously, they need to store some sensitive information like usernames, passwords, SSH keys, OAuth Tokens, API keys and whatever you consider as secret and not to be openly visible.
You must know that pods and the Kubernetes system itself also use Secrets; for example, Kubelet uses it when it needs to pull an image from an image repository that requires authentication when Pods communicates with an API server component.
What is Kubernetes Secret?
Kubernetes Secret lets you store sensitive and confidential information in a Kubernetes object in such a way that is more secure and more flexible rather than putting this information in Pod’s definition or in Kubernetes ConfigMap or in the container image.
Kubernetes is designed to use files in YAML (JSON) format, so object definitions are stored in the YAML(JSON) format only. In the same way, Kubernetes Secret is treated as a Kubernetes Object that stores sensitive data so that the content is not revealed.
You must note below points while working with Kubernetes Secrets: –
- The name of a Kubernetes Secret object must be a valid DNS subdomain
- Within Kubernetes System, service accounts automatically create, attach Secrets with API credentials.
- Special characters like $, \, *, ) and ! will be interpreted by your working shell, so it must require escaping. The simplest way to escape such characters is to surround them using single.
How to Create Kubernetes Secrets?
There are various ways to create and use a Kubernetes Secret object. We can explore some of those here if not all. If you are familiar with Kubernetes ConfiMap objects, then you will understand that Secrets are also created and used in the same way. So first, we will get to know what possible ways to create a Secret and then how to use it in a Pod.
Below are the major two methods and their sub-methods to create Secrets:
On the command line, you can use kubectl to create secrets in below
File: On the kubectl command line, you can refer to the files which have your confidential information like below. You should note that if you provide that content in files as plain strings, then when you read the object like below, you will see that those values will appear under the data
map and be encoded like below. Also, note that you don’t need to escape special characters in the files.
echo -n ‘admin’ > ./username.txt
echo -n ‘pAss)1’ > ./password.txt
kubectl create secret generic get-cred --from-file=./username.txt --form-file=./password.txt
kubectl get secrets get-cred -0 yaml
Environment Variable File: When we have a variable file that has data in a key-pair format, we want to use it as Secret; then we can do the below:
cat << EOF > credential.txt
Below you can see the description of the same Secret.
Literal: On the kubectl command line, you can directly give the confidential data like below, and it will be encoded using base64 when it is converted to a Secret object like
kubectl create secret generic dev-secret --from-literal=username=admin --from-literal=password=’passw0rdo1’
kubectl get secret dev-secret -o yaml
Manually: You can write a YAML file, in which you can map sensitive data in two ways,
- Data: This supports strings encoded with base64. So, you must encode your sensitive data with base64 encoding before putting in a Secret definition
- stringData: This supports plain strings directly, and you don’t need to encode them. Also, when you see this information in the Kubernetes Secret object, you will see it encoded, so you need not worry.
An example of a Secret definition YAML file named Kube-secret.yaml: –
Deploy this file like below:
kubectl apply -f ./kube-secret.yaml
You will see this object is created.
kubectl get secrets my-secret –o yaml
Since version v1.14, you can also use Kustomize for resource generator to create Secrets and ConfigMaps. The generator should be specified in yaml, which should reside under a directory. After generating the Secret, you can use kubctl apply to generate Secret in the API server.
There are several ways to create Secrets using Kustomize. Few are described below: –
File: You can specify the files containing your sensitive data under field secretGenerator like below:
Then deploy this file.
kubectl apply -k .
Then you can check that the secret is created. Also, note the name of the secret which got created; it has a suffix to make it distinct if you are modifying the same object.
kubectl describe secrets user-pass-dht85d7kff
Literals: You can directly use literally key pair values while creating a Secret using a resource generator in yaml.
Take this example:
Create kustomization.yaml with contents like below: –
cat << EOF >./kustomization.yaml
Then deploy this file and get its output like below: –
kubectl apply -k .
Example of Kubernetes Secrets
Now we explore some ways to use the like-above created secrets in pods definition. But first, we must note the below points:
- Multiple Pods can refer to the same.
- Secret data will appear as files inside a container. After that, it is up to the container to how to use it.
- Secrets and referring pods should be in the same.
- Secrets must be created before using in.
We can use Secret in a pod by using the following ways:
- As files under volumes mounted inside a container and to use a Secret in a volume inside a pod, we must remember the below points:
- When defining a pod, we should add a volume under .spec.volumes and name the volume as per your ease.
- Also, we have fields .spec.volumes.secret.secretName which are representing secret objects.
- Each container which needs secret, you shall define .spec.containers.volumeMounts and specify .spec.containers.volumeMounts.readOnly = true and.spec.containers.volumeMounts.mountPath to an unused folder name where your secrets will be mounted.
- Then, modify your image or use the command line so that the application programs will find files.
cat << EOF > testsecret
kubectl apply -f secretfile.yaml
kubectl exec testpod -- cat /etc/foo/testsecret.txt
- As environment variables, First, you create a Secret object with –from-env-file= Like below.
kubectl create secret generic credentials --form-env-file=testsecret.txt
Then use this secret like below with field env.valueFrom.secretKeyRef in which name and Key represent the Secret name and key’s name from key-value pair inside the secret object.
kubectl apply -f ./newpod.yaml
When you check the environment variable inside that container like below, you can see the environment variables which you defined in Secret.
kubectl exec env-pod -- env | grep ENV
Kubernetes Secrets are also not full proof like other security tools and methods. But it’s a good practice using Secret to encode the sensitive information rather than putting sensitive information in plain text somewhere. Also, including Secrets in your Kubernetes security strategy of infrastructure environment adds a layer of security on the system level.
This is a guide to Kubernetes Secrets. Here we also discuss the Introduction and how to create Kubernetes secrets along with different examples and its code implementation. You may also have a look at the following articles to learn more –