Goglides Dev 🌱

Goglides Dev 🌱 is a community of amazing users

We are working on this space so that IT professionals can grow together.

Create account Log in
Balkrishna Pandey
Balkrishna Pandey

Posted on

What are Kubernetes secrets and why do you need them

Secrets are an important part of any Kubernetes deployment, as they allow you to protect sensitive information such as passwords, OAuth tokens, and SSH keys. Secrets are encrypted at rest and in transit, which helps to ensure that this sensitive information remains confidential. In addition, Secrets can be used to grant access to specific resources within a Kubernetes cluster. For example, you could use a Secret to grant a user access to a specific database or API. By using Secrets, you can help to ensure that your Kubernetes deployment is both secure and efficient.

Kubernetes Secrets are stored in etcd, the Kubernetes cluster’s primary data store. etcd is a highly available key-value store that is used to store the configuration of Kubernetes objects.

How to create a secret in Kubernetes

There are various ways you can create Kubernetes secrets.

Create k8s secrets using kubectl cli

To create a secret, you will need to first create a text file that will store the contents of your secret. In this example, the text files will store a username and password.

echo -n "admin"  > ./username.txt
echo -n "SecretPassword" > ./password.txt
Enter fullscreen mode Exit fullscreen mode

Then you'll want to use the kubectl create secret command to package these files into a Secret. The final command will look like this:

kubectl create secret generic mysecret \
 --from-file=./username.txt \
 --from-file=./password.txt
Enter fullscreen mode Exit fullscreen mode

You will see output

secret/mysecret created
Enter fullscreen mode Exit fullscreen mode
kubectl get secret/mysecret -o yaml
Enter fullscreen mode Exit fullscreen mode

Output:

apiVersion: v1
data:
 password.txt: c2VjcmV0UGFzc3dvcmQK
 username.txt: YWRtaW4K
kind: Secret
metadata:
 creationTimestamp: "2022-06-07T21:13:28Z"
 name: mysecret
 namespace: default
 resourceVersion: "21204"
 uid: 3be40a46-10a9-4bdd-94f3-3a33c2c727bc
type: Opaque
Enter fullscreen mode Exit fullscreen mode

If you want to change the keyvalue from username.txt to username and password.txt to password you can do so as follows,

 kubectl create secret generic mysecret \
 --from-file=username=./username.txt \
 --from-file=password=./password.txt
Enter fullscreen mode Exit fullscreen mode

The output looks like below with type as Opaque, which means data is base64 encoded.

kubectl get secret/mysecret -o yaml 
Enter fullscreen mode Exit fullscreen mode

Output:

apiVersion: v1
data:
 password: c2VjcmV0UGFzc3dvcmQK
 username: YWRtaW4K
kind: Secret
metadata:
 creationTimestamp: "2022-06-07T21:16:02Z"
 name: mysecret
 namespace: default
 resourceVersion: "21315"
 uid: 5466fcf8-1563-4893-8b61-0211755e6e7b
type: Opaque
Enter fullscreen mode Exit fullscreen mode

Instead of using content from a file, you can also directly pass the secret values as follows,

kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=SecretPassword
Enter fullscreen mode Exit fullscreen mode

The output should look like the below.

apiVersion: v1
data:
 password: U2VjcmV0UGFzc3dvcmQ=
 username: YWRtaW4=
kind: Secret
metadata:
 creationTimestamp: "2022-06-07T21:19:17Z"
 name: mysecret
 namespace: default
 resourceVersion: "21453"
 uid: 2bace04a-55a2-47c8-b26b-e62f683df72a
type: Opaque
Enter fullscreen mode Exit fullscreen mode

Create k8s secrets using the kubectl command-line tool and yaml file

To create a Secret using kubectl, you first need to create a file that contains the data you want to encrypt. This file should be in JSON or YAML format.

The Secret resource contains two distinct maps:

data: used to store arbitrary data, encoded using base64

stringData: allows you to provide Secret data as unencoded strings

The keys for data and stringData must include only letters, numbers, -, _ or ..

For example, if you want to store two strings in a Secret using the data field, you can convert the strings to base64 as follows:

For example, let’s say you want to create a Secret that contains a password. The file might look like this:

echo -n "admin" | base64
Enter fullscreen mode Exit fullscreen mode

Output:

YWRtaW4=
Enter fullscreen mode Exit fullscreen mode
echo -n 'SecretPassword' | base64
Enter fullscreen mode Exit fullscreen mode

Output:

U2VjcmV0UGFzc3dvcmQ=
Enter fullscreen mode Exit fullscreen mode

Now you can write this data to a file, for example secret.yaml:

apiVersion: v1
kind: Secret
metadata:
 name: mysecret
type: Opaque
data:
 username: YWRtaW4=
 password: U2VjcmV0UGFzc3dvcmQ=
Enter fullscreen mode Exit fullscreen mode

To create the Secret, run the following command:

kubectl create -f secret.yaml 
Enter fullscreen mode Exit fullscreen mode

Output:

secret/mysecret created
Enter fullscreen mode Exit fullscreen mode

Creating a secret using kustomize

Kustomize is a tool that can be used to customize Kubernetes resources. For example, you can use kustomize to patch a Secret or to add labels to all of the resources in a deployment.

To create a Secret using kustomize, you first need to create a file that contains the data you want to encrypt. This file should be in JSON or YAML format.

You can also create a secret object by referencing other files in a kustomization.yaml file. For example, the following kustomization file references the ./username.txt and ./password.txt files:

secretGenerator:
- name: mysecret
 files:
 - username.txt
 - password.txt
Enter fullscreen mode Exit fullscreen mode

Then, use the directory that contains the kustomization.yaml file to create the Secret:

kubectl apply -k .
Enter fullscreen mode Exit fullscreen mode

The output should look similar to this:

secret/mysecret-mt8fg76mc6 created
Enter fullscreen mode Exit fullscreen mode

You can use the secrets as follows

kubectl get secret
Enter fullscreen mode Exit fullscreen mode

Output:

NAME     TYPE         DATA AGE
default-token-7bnbj kubernetes.io/service-account-token 3  31h
mysecret-mt8fg76mc6 Opaque        2  13s
Enter fullscreen mode Exit fullscreen mode

And if you check the content of the secrets

kubectl get secret mysecret-mt8fg76mc6 -o yaml
Enter fullscreen mode Exit fullscreen mode

Output:

apiVersion: v1
data:
 password.txt: c2VjcmV0UGFzc3dvcmQK
 username.txt: YWRtaW4K
kind: Secret
metadata:
 annotations:
 kubectl.kubernetes.io/last-applied-configuration: |
  {"apiVersion":"v1","data":{"password.txt":"c2VjcmV0UGFzc3dvcmQK","username.txt":"YWRtaW4K"},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret-mt8fg76mc6","namespace":"default"},"type":"Opaque"}
 creationTimestamp: "2022-06-07T21:05:02Z"
 name: mysecret-mt8fg76mc6
 namespace: default
 resourceVersion: "20847"
 uid: c777c293-4591-4bfb-b3c2-d017a9d8a196
type: Opaque
Enter fullscreen mode Exit fullscreen mode

Where user echo -n "YWRtaW4K" |base64 --decode is equal to admin and password, echo -n "c2VjcmV0UGFzc3dvcmQK" |base64 --decode is equal to secretPassword

How to use secrets in Kubernetes

Secrets can be used in a number of ways in Kubernetes. The most common use case is to mount a Secret as a file inside of a Pod. This allows you to access the data in the Secret from within your application. For example, let’s say you have a Secret that contains a password. You could mount this Secret as a file inside of a Pod, and then your application could read the password from the file.

To mount a Secret as a file inside of a Pod, you first need to create a Secret object. This object can be created using the kubectl command-line tool or through the Kubernetes API. Once you have created the Secret, you need to edit the Pod’s manifest file to add a volumes and volumeMounts section. The volumes section should specify the name of the Secret and the path at which it will be mounted. The volumeMounts section should specify the path where the Secret will be mounted and the name of the Secret. For example, to mount the mysecret Secret at the /etc/secret path, you would add the following to your Pod’s manifest file:

apiVersion: v1
kind: Pod
metadata:
 name: mypod
spec:
 containers:
 - name: mycontainer
  image: busybox
  command: ["sh", "-c", "while true; do echo Hello World; sleep 1; done"]
  volumeMounts:
  - name: mysecret
   mountPath: "/etc/secret"
 volumes:
 - name: mysecret
  secret:
   secretName: mysecret
Enter fullscreen mode Exit fullscreen mode

You can also use Secrets to pull images from a private Docker registry. To do this, you first need to create a Secret that contains your Docker username and password. This Secret can be created using the kubectl command-line tool or through the Kubernetes API. Once you have created the Secret, you need to edit your Pod’s manifest file to add a imagePullSecrets section. This section should specify the name of the Secret. For example, to use the mysecret Secret to pull images from a private Docker registry, you would add the following to your Pod’s manifest file:

apiVersion: v1
kind: Pod
metadata:
 name: mypod
spec:
 containers:
 - name: mycontainer
   image: busybox
   command: ["sh", "-c", "while true; do echo Hello World; sleep 1; done"]
   volumeMounts:
   - name: mysecret
     mountPath: "/etc/secret"
 volumes:
 - name: mysecret
   secret:
    secretName: mysecret
Enter fullscreen mode Exit fullscreen mode

Using Secrets as environment variables

Another way to use Secrets is to set them as environment variables inside of a Pod. To do this, you first need to create a Secret that contains the data you want to encrypt. This Secret can be created using the kubectl command-line tool or through the Kubernetes API. Once you have created the Secret, you need to edit your Pod’s manifest file to add a env and envFrom sections. The env section should specify the name of the environment variable and the value of the Secret. The envFrom section should specify the name of the Secret. For example, to set the mysecret Secret as an environment variable inside of a Pod, you would add the following to your Pod’s manifest file:

apiVersion: v1
kind: Pod
metadata:
 name: mypod
spec:
 containers:
 - name: mycontainer
   image: busybox
   command: ["sh", "-c", "while true; do echo Hello World; sleep 1; done"]
   env:
   - name: USERNAME
     valueFrom:
      secretKeyRef:
       name: mysecret
       key: username
   - name: PASSWORD
     valueFrom:
      secretKeyRef:
       name: mysecret
       key: password
 volumes:
 - name: mysecret
   secret:
    secretName: mysecret   
Enter fullscreen mode Exit fullscreen mode

Types of Kubernetes secrets

There are various types of Secrets in Kubernetes:

  • Opaque Secrets: These are Secrets that are encrypted and base64-encoded. They cannot be viewed or edited once they are created.

  • Service Accounts Secrets: These are Secrets that are used to authenticate to Kubernetes services. This Secret type is used to store a token that identifies a service account. Make sure you set the kubernetes.io/service-account.name annotation to an existing service account name when using it.

  • Docker config Secrets: These are Secrets that are used to authenticate to Docker registries. This Secret type is used to store a username and password for a Docker registry.

  • TLS Secrets: These are Secrets that are used to store TLS certificates and keys. They can be used to authenticate to Kubernetes services or to encrypt communication between pods. This data is used to secure communications with TLS. You will need to provide the tls.key and tls.crt key in the data (or stringData) field of the Secret configuration in order to use it.

  • Basic authentication Secret: This Secret type is used to store a username and password for HTTP basic authentication. This data is used to authenticate to Kubernetes services over HTTP. You will need to provide the username and password key in the data (or stringData) field of the Secret configuration in order to use it.

  • SSH authentication secrets: These are Secrets that are used to store SSH keys. They can be used to authenticate to Kubernetes services or to encrypt communication between pods. This data is used to secure communications with SSH. You will need to provide the ssh-privatekey key in the data (or stringData) field of the Secret configuration in

  • Bootstrap token Secrets: These are Secrets that are used to store bootstrap tokens. Bootstrap tokens are used to authenticate nodes when they join a cluster. This data is used to authenticate nodes when they bootstrap themselves into a Kubernetes cluster. You will need to provide the token-id, token-secret, and usage-bootstrap-authentication keys in the data (or stringData) field of the Secret configuration in order to use it.

Conclusion

In this article, you’ve learned about Kubernetes Secrets and how to use them. Secrets are a valuable tool for protecting sensitive data in your Kubernetes cluster. By encrypting your data and storing it in Secrets, you can be sure that only authorized users will be able to access it.

Discussion (0)