How to Create and Manage Kubernetes Secrets: A Tutorial
Tags: kubernetes, vcluster, devspace, loft
Published: 2022-09-30 19:53:37

By Mercy Kibet

When developing applications, it's common to have sensitive information you would not want exposed to unauthorized personnel. Unlike other objects in your cluster, such as those used in a Pod specification, a Secret can be created and stored independently of its associated Pods. This eliminates the risk of exposing the data to the public during the workflow of editing, creating, and viewing Pods. This post will show you how to create and manage Kubernetes Secrets. 

## What Are Kubernetes Secrets?

Kubernetes applications are often set up with Secrets. They're a way to insulate sensitive information from the rest of your environment, so it's harder for malicious actors to find and modify it. Secrets have different methods for controlling access, like having an administrator create them and then assign access via role-based access control (RBAC). It can also be done with a policy file, which we'll cover in this tutorial.

![alt_text](https://loft.sh/blog/images/content/secret2.jpg "image_tooltip")

## How to Define Kubernetes Secrets

Like any other object in Kubernetes, Secrets must be defined or created with a spec with a name, Secret, and other fields. Below is a short example of the required information for the spec. All you need to do is assign values for those three fields and you'll have a working Kubernetes Secret. 

```
apiVersion: v1

kind: Secret

metadata:

  name: my-secret

spec:

  selector: ingress.kubernetes.io/node-role.---/master, ingress.kubernetes.io/service-role.---/persistent-volume-controller, ingress.kubernetes.io/auth-provider, ingress.kubernetes.io/ingress-from, ingress.kubernetes.io/ingress-label, ingress.kubernetes....

  type: Opaque

  data: [base64 encoded value]
```

Let's break down this spec so you can see what's happening here. The metadata field is just a place to store your object's name, Secret, and other information. I chose:\
\

* **`ingress.kubernetes.io/node-role.---/master`**\
* **`ingress.kubernetes.io/service-role.---/persistent-volume-controller`** \
* and **`ingress.kubernetes.io/auth-provider`** 

because they're the service accounts I use across my Kubernetes environment for various components (names will vary based on your setup). 

**`data: [base64 encoded value]`** tells the object to be stored as an opaque binary. **`Opaque`** is one of the options for **`dataType`**, which determines how the data is versioned and stored. Here, we're using a **`base64 encoded value`**, which will be stored in the database as a byte array. 

**`selector`** is used to determine where to inject the Secret. Here, we're saying that the Secret should only exist on nodes with a role of **`master`** or nodes that are **`service controllers`** (those with instance roles). The label selector option allows you to select by multiple labels at a time, so I've chosen several from my cluster configuration. In this case, I chose **`ingress.kubernetes.io/ingress-from`** (name of the ingress), **`ingress.kubernetes.io/ingress-label`** (the label for the ingress), and **`ingress.kubernetes`.**

![alt_text](https://loft.sh/blog/images/content/secret3.png "image_tooltip")

You can see there are a lot of options for defining Secrets in Kubernetes, but that's not necessarily a bad thing. You should be able to get started with some defaults and extend it later throughout your cluster, as long as you keep the constructs as YAML and never write to raw database fields, which would be a really unfortunate mistake. 

### Defining a Secret Under the Namespace

Let's assume we have a Secret to store sensitive data and want to deploy it on our cluster nodes. We won't need the application, so we'll define the Secret under our Kubernetes cluster namespace (i.e., the default). First, we'll create a namespace. We can do that with the following command: 

```
$ kubectl create ns mysecret
```

Now that we have a namespace, we can proceed to define our Secret. We'll create a **.yaml** file with the content below: 

```
apiVersion : v1 
kind : Secret 
metadata : 
   name : mysecretns 
data :
   mysecret : YWRtaW4= 
type : Opaque
```

Then we can instruct **kubectl** to create the Secret file: 

```
$ kubectl apply -f mysecret.yaml
```

Verify that the Secret is in place using the below: 

```
$ kubectl get secrets NAME TYPE DATA AGE mysecretns Opaque 8 1s 
$ kubectl describe secrets/mysecretns Name: mysecretns Namespace: default Labels: <none> Annotations: <none> Data ==== mysecret: 8 byte string (binary)
```

And now we have successfully created a Secret file containing the information we need. We can use this information to set environment variables on instances in our cluster. We could also create a deployment and access the Secret values as environment variables with a container inside the deployment. 

As shown above, this is a straightforward example of deploying a Secret. Secrets can be used to store all sorts of information, from database passwords to private keys. 

## Managing Kubernetes Secrets

From your terminal, you can use the **`kubectl`** command and subcommands such as **create**, **delete**, **describe**, and **apply** to manage and view your Kubernetes Secrets. First, we'll look at examples of each type with their corresponding command-line interface (CLI) output. Then, we'll examine how to use them in more detail. 

### Viewing Kubernetes Secrets

To view Kubernetes Secrets, first use **`cat`** or **`id <name>`** to check if there are any Secrets in your cluster. Next, use **`describe <name>`** to get more information about a specific Secret. 

Use **`create -f file.yaml`** to add a new Secret and **`replace file.yaml`** with the name of your file that contains your Secret information. 

Use **`delete`** to remove a specific Secret. 

Finally, **`apply -f filename.yaml`** is used to apply changes that you have made locally without overwriting the Secret on the cluster (for example, if you want to test your changes). 

### Deleting a Kubernetes Secret Using kubectl delete

To delete a Secret, first, use **`cat`** or **`id <name>`** to check if there are any Secrets in your cluster. Next, use **`describe <name>`** to get more information about a specific Secret. 

You delete Kubernetes Secrets using the **`kubectl delete`** command. 

The following example deletes a Kubernetes Secret named **`my-secret-name-1`**: 

```
kubectl delete secret my-secret-name-1
```

### Modifying a Secret's Properties

To modify the properties of an existing Kubernetes Secret you can use **[``](https://kubernetes.io/docs/reference/kubectl/)`kubectl edit`.** 

The following command shows how you could modify a Kubernetes Secret named **production-secret**: 

kubectl edit secret production-secret 

To find the original Kubernetes Secret that your new one replaced, use **`kubectl get <name>`** to see if the key pair exists in the cluster. If it does, you can use** `kubectl get secrets <name>`** to see the original Secrets. 

## Encrypting Kubernetes Secrets

You can use Kubernetes to provide sensitive data only to people who require access to it. This can reduce your exposure to security problems, typically from storing sensitive data on a public server. To do this, you must generate an encryption key pair called a **kubecrypt key store** and keep it private. To encrypt Secrets with a **`kubecrypt key store`**, you'll first have to create the key pair. You can learn more with `kubecrypt`. 

To create a key pair, run the following: 

```
kubectl create -f kubernetes.yaml
```

This should generate your new key pair. You should see something like this after running the command:  

```
token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
```

![alt_text](https://loft.sh/blog/images/content/door.jpg "image_tooltip")

## Secrets Alternatives

Although Secrets allow you to store encrypted information, they only store the key and not the actual data. This limits security, as Kubernetes does not encrypt the actual data before storing it. There are two alternatives: 

1. **Sealed Secrets:** This is a special type of Kubernetes Secret that encrypts and stores your sensitive information in its database.
2. **HashiCorp Vault:** This digital vault supports multi-algorithm encryption for over 20 blockchain technologies, authentication providers, and storage methods while also being able to maintain user permissions and privilege escalation policies on Secrets decryption keys using RBAC.

![alt_text](https://loft.sh/blog/images/content/secrets5.png "image_tooltip")

## Conclusion

Kubernetes Secrets are a great way to manage sensitive information for your applications. They can be used to store things like database passwords, API keys, and other sensitive data. It's impossible to keep your most precious Secrets safe from prying eyes because of the sheer number of potential attack vectors available to hackers. Luckily, there are many better options for securing your Secrets (and backups), including Sealed Secrets and HashiCorp. If you're looking for an easy way to manage Kubernetes Secrets, check out [Loft](https://loft.sh/docs/secrets/#operation/readVirtualclusterLoftShV1NamespacedHelmRelease). Loft provides a simple and easy-to-use web interface for managing Kubernetes Secrets.    

*This post was written by Mercy Kibet. [Mercy](https://hashnode.com/@eiMJay) is a full-stack developer with a knack for learning and writing about new and intriguing tech stacks.*