Most
applications deployed through Kubernetes require access to externally located databases, services, and other resources. The easiest way to manage the login information needed to access those resources is to use Kubernetes secrets. Secrets help organize and distribute sensitive information in a cluster.
In this tutorial, you’ll learn what Kubernetes secrets are and how to create and use them in your cluster.
prerequisites
A Kubernetes cluster
- (for testing purposes, you can create it with minikube)
- The Kubernetes kubectl command-line tool
What are Kubernetes
secrets?
A Kubernetes secret is an object that stores sensitive data, such as usernames, passwords, tokens, and keys. Secrets are created by the system during the installation of an application or by users whenever they need to store confidential information and make it available to a pod.
If passwords, tokens, or keys were simply part of a pod or container image definition, they could be accidentally exposed during Kubernetes operations. Therefore, the most important function of secrecy is to prevent accidental exposure of the information stored in it and, at the same time, to make it available where the user needs it.
Types of Kubernetes secrets
Kubernetes
has two categories of
secrets:
- System service accounts automatically create built-in secrets and associate them with containers along with API credentials
- You can also create custom secrets for the credentials you need to make available to pods.
.
Built-in secrets come in several types, corresponding to popular usage scenarios:
kubernetes.io/service-account-token opaque kubernetes.io/dockercfg~/.dockercfg.dockercfg
To define a custom secret type, assign a non-empty string as the value in the secret file type field. Leaving the field empty tells Kubernetes to assume the Opaque type. The custom type releases the secret from the constraints posed by the built-in types.
Using Kubernetes secrets
When you create a secret, the pod that will use it must reference it. To make a secret available for a capsule:
1. Mount the secret as a file on a volume available to any number of containers in a pod.
2. Import the secret as an environment variable into a container.
3. Use kubelet and imagePullSecrets field.
The following sections explain how to create, decode, and access Kubernetes secrets.
Create Kubernetes secrets
To create a Kubernetes secret, use one of the following methods:
Use kubectl for a
- command-line approach. Create a
- configuration file for the
- Use a generator, such as Kustomize to generate the secret
- secrets using kubectl
secret.
. Create
1. To start creating a secret with kubectl, first create the files to store the sensitive information:
echo -n ‘[username]’ > [file1] echo -n ‘[password]’ > [file2]
The -n option tells echo not to add a new line at the end of the string. The new line is also treated as a character, so it would be encoded along with the rest of the characters, producing a different encoded value.
2. Now, use kubectl to create a secret using the files from the previous step. Use the generic subcommand to create an opaque secret. Also, add the –from-file option for each of the files you want to include
: kubectl create secret generic [secret-name] -from-file=[file1] -from-file=[file2]
The output confirms the creation of the secret:
3. To provide keys for the values stored in the secret, use the following syntax:
kubectl create secret generic [secret-name] -from-file=[key1]=[file1] -from-file=[key2]=[file2]
4. Verify that the secret was created correctly by typing
: kubectl get secrets
The command displays the list of available secrets: their names, types, number of data values they contain, and their age:
Create secrets in a configuration file
1. To create a secret by specifying the required information in a configuration file, start by encoding the values you want to store:
echo -n ‘[value1]’ | base64 echo -n ‘[value2]’ | base64
2. Now create a yaml file using a text editor. The file should look like this
: apiVersion: v1 kind: Secret metadata: name: newsecret type: Opaque data: username: dXNlcg== password: NTRmNDFkMTJlOGZh
3. Save the file and use the kubectl apply command to create the secret: kubectl apply
-f [file]
Create Kubernetes secret with
generators Generators like Kustomize help generate secrets quickly
. 1. To create a secret
with Kustomize, create a file named kustomization.yaml and format it as follows
: secretGenerator: – name: db-credentials files: – username.txt – password.txt
The example above indicates db-credentials as the name of the secret and uses two previously created files, username.txt and password.txt, as data values.
2. Alternatively, to provide the unencrypted literal version of the data values, include the literals section with the key-value pairs you want to store
: secretGenerator: – name: db-credentials literals: – username=user – password=54f41d12e8fa
3. Save the file and use the following command in the folder where kustomization.yaml is located: kubectl
apply -k . The
output confirms the creation of the secret:
Use kubectl describes
to view created secrets
The kubectl describes command displays basic information about Kubernetes objects. Use it to see the description of a secret.
kubectl describes secrets/[secret] The first example shows the secret created
by providing files as data values: The
second example describes the secret created with string literals. Notice the change in the Data section, which now displays key names instead of file names:
Decode Secrets
1. To decode the values of a secret, access them by typing the following command
: kubectl get secret [secret] -o jsonpath='{.data}’
The output shows the encoded key-value pairs stored in the data section:
2. Use the echo command to write the encoded string and pipe the output to the base64 command: echo
‘[encoded-value]’ | base64 -decode
Decoded strings appear as the output:
Access secrets loaded on volume
1. To access secrets mounted on a pod on a separate volume, modify the pod definition to include a new volume. Choose the volume name you want, but make sure it is the same as the name of the secret object.
2. Make sure to specify readOnly as true. For example, the pod definition might look like this
: apiVersion: v1 kind: Pod metadata: name: test-pod spec: containers: – name: test-pod image: redis volumeMounts: – name: newsecret mountPath: “/etc/newsecret” readOnly: true volumes: – name: newsecret secret: secretName: newsecret
2. Open another terminal instance and use the kubectl exec command to access the bash shell of the pod: kubectl exec
-it [pod] – /bin/bash
3. cd in /etc/newsecret, and find the files contained in the secret: cd /etc/newsecret
Project secrets in a container using environment variables
1. Another way to access secrets in a Kubernetes pod is to import them as environment variables by modifying the pod definition to include references to them. For example
: apiVersion: v1 kind: Pod metadata: name: secret-env-pod spec: containers: – name: secret-env-pod image: redis env: – name: SECRET_USERNAME valueFrom: secretKeyRef: name: newsecret key: username – name: SECRET_PASSWORD valueFrom: secretKeyRef: name: newsecret key: password restartPolicy: Never
2. Use kubectl exec again to strike on a pod.
3. Test the
environment variable using
the command echo: echo $[VARIABLE]
The output of the command shows the value assigned to the variable:
Use Secrets to Pull Docker Images from Private Docker Registries
1. To use Docker private logs, first, you need to log in to Docker:
docker login
2. When prompted, provide your login credentials:
3. If the login is successful, Docker updates the config.json file with your data. Use the cat command to view the file: cat
~/.docker/config.json
The auths section contains the authentication key, which is an encoded version of the Docker credentials
. 4. Use kubectl to create a secret, providing the location of the config.json
file and the type of the secret: kubectl create secret generic [secret] -from-file=.dockerconfigjson=./.docker/config.json -type=kubernetes.io/dockerconfigjson
Alternatively,
perform all of the above steps, including logging into Docker, on the same line:
kubectl create secret docker-registry [secret] -docker-server:[address] -docker-username=[username] -docker-password=[password] -docker-email=[email]
5. To create a pod that has access to this secret, create a yaml file that defines it. The file should look like this
: apiVersion: v1 kind: Pod metadata: name: private-reg spec: containers: – name: private-reg-container image: imagePullSecrets: – name: regcred
6. Finish creating the pod by activating it with kubectl apply: kubectl apply
-f [file] Kubernetes secrets considerations
Kubernetes secrets
are a secure way to store sensitive information. However, before deciding which is the best method for your usage scenario, you should consider the following points:
- Secrets usernames and passwords are base-64 encoded. This text encoding technique hides data and prevents accidental exposure, but is not secure against malicious cyber attacks.
- Secrets are available only in the cluster in which they are located.
- Secrets are usually based on a master key that is used to unlock them all. While there are methods to protect the master key, using them only creates another master key scenario.
To mitigate these issues, apply some of the following solutions:
Integrate a secrets
- management tool that uses the Kubernetes Service account to authenticate users who need access to the secret vault
- an Identity and Access Management (IAM) tool to enable the system to use tokens from a secure token service. Integrate a
- third-party secrets manager into pods.
. Integrate
Conclusion
After reading this tutorial, you should know what Kubernetes secrets are, what types exist, and how to create a Kubernetes secret. The tutorial also introduced ways in which secrets are accessed.
To learn more about Kubernetes security, read Kubernetes security best practices.