Table of Contents
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.
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
.
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.
Advanced Guide to Kubernetes Ingress Controllers: Kubernetes ingress controller best practices and examples.
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 ``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
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:
- Sealed Secrets: This is a special type of Kubernetes Secret that encrypts and stores your sensitive information in its database.
- 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.
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. Loft provides a simple and easy-to-use web interface for managing Kubernetes Secrets.
This post was written by Mercy Kibet. Mercy is a full-stack developer with a knack for learning and writing about new and intriguing tech stacks.
Additional Articles You May Like:
- How to Build an Internal Kubernetes Platform
- Docker Compose to Kubernetes: Step-by-Step Migration
- How to Create and Manage Kubernetes Secrets: A Tutorial
- Kubernetes Virtual Clusters
- A Hands-on Tutorial - Kubernetes Virtual Clusters
- Kubernetes Multi-Tenancy – A Best Practices Guide
- Kubernetes Cost Optimization with Virtual Clusters
- Kubernetes Namespaces vs. Virtual Clusters
- 10 Essentials For Kubernetes Multi-Tenancy
- Kubernetes: Virtual Clusters For CI/CD & Testing
- Virtual Clusters For Kubernetes - Benefits & Use Cases
- Kubernetes Multitenancy: Why Namespaces aren’t Good Enough
- Kubernetes Multi-Tenancy with Argo CD And Loft
- Kubernetes Multi-Tenancy: Why Virtual Clusters Are The Best Solution
- [Video] Beyond Namespaces: Virtual Clusters are the Future of Multi-Tenancy