Guest post originally published on Medium by Saurabh Gupta, Sr. Developer Advocate at DigitalOcean
Introduction:
Kubernetes is currently the de-facto standard for container orchestration. As organizations globally are adopting a Container first development approach, a large part of existing workloads is still running on virtual machines, be in the public cloud or a private data center. Hence a lot of companies are now facing severe challenges in migrating from their old methods to Kubernetes.
However, there are times when you want bake-in sensitive secret information into your Kubernetes cluster and share it across when needed. You do not want to put this information into a Pod definition YAML or a docker image. This is where Kubernetes Secret comes to your rescue.
In this post, we will try to gain more insight into how we can manage secrets effectively in Kubernetes.
Why use a Secret?
Not all configuration information is safe to keep out in the “public”. Also, it is a bad practice to store sensitive data, like passwords, SSH keys, and authentication tokens, in plaintext on a container. However, containers do need this data to perform basic operations like integrating with other systems.
To solve this challenge, Kubernetes provides an object called Secret, which we can use to store sensitive data. Secrets management also enables better management of microservices-based software architecture.
What is the Kubernetes Secret?
As per the Kubernetes documentation notes: “Kubernetes Secrets let you store and manage sensitive information, such as passwords, OAuth tokens, and ssh keys. Storing confidential information in a Secret is safer and more flexible than putting it verbatim in a Pod definition or in a container image “.
Kubernetes Secret can be injected into a Pod container either as an environment variable or mounted as a file.
Difference between a ConfigMap and Secrets in Kubernetes?
Both ConfigMaps and Secrets store data as a key-value pair. However, the major difference is Secrets store data in base64 format meanwhile ConfigMaps store data in plain text.
So use Secrets for storing critical data like API keys, passwords, service-account credentials, etc and use Configmaps for not-secret configuration data like app theme, base platform URL, etc
How does Kubernetes Secrets work?
There are two types of secrets in Kubernetes:
- Built-in secrets – Kubernetes Service Accounts automatically create secrets and attach them to containers with API Credentials. The automatic creation and use of API credentials can be disabled or overridden if desired.
- Custom secrets – you can define your own sensitive data and create a custom secret to store it.
Built-in Kubernetes Secrets
Kubernetes provides a built-in mechanism for storing configuration values that you would prefer to keep private. They can be access-controlled to specific namespaces, and their contents are not shown by default in kubectl get
or describe output
. They are base64 encoded, so the contents are not immediately apparent even when you pull them directly from kubectl. Of course, base64 decoding is trivial.
These secrets are stored in plaintext format on the cluster’s etcd server, and unless, etc is configured to encrypt communication using TLS, are visible on the wire as the etcd cluster is synchronized. Furthermore, anyone who has, or can gain root access to any node in the cluster can read all secret data by impersonating the kubelet.
Creating your own custom Secrets:
- Creating a Secret Using kubectl: this is the simple and easy method to generate your secrets. You can use the
kubectl create
command to create secrets.
$ kubectl create secret <secret-name>
If you want this secret to be added to a specific namespace or context add the – namespace or use-context arguments to this command. (Otherwise, it will be added to the default namespace).
You can use $ kubectl describe secret <secret-name> to view a summary of your secret. Using $ kubectl get secret or $ kubectl describe secret will not reveal the information in the secret.
- Creating a Secret manually: you can also create a Secret in a file first, in JSON or YAML format, and then create that object. The name of a Secret object must be a valid DNS subdomain name. The Secret contains two maps: data and stringData. The data field is used to store arbitrary data, encoded using base64. The stringData field is provided for convenience and allows you to provide secret data as unencoded strings.
Secret management in cloud:
In case you are using one of the cloud vendors, you can try using one of their secret management services, as part of their cloud platform offerings. Using a secret management service gives you the power to control access to secrets using fine-grained permissions and auditing.
Some of the popular secret management solutions from different cloud vendors are shared below:
- Secrets Manager from AWS
- Key Vault from Azure Cloud
- Cloud Key Management Service from Google cloud