Kubernetes is a powerful open-source container orchestration system that has been growing in popularity in recent years. It allows for the automation of container deployments, making it an attractive option for organizations looking to scale their applications. However, Kubernetes also has a number of secrets and configurations that are specific to its operation. This can make it difficult for third-party developers and administrators to understand and use Kubernetes effectively. In this article, we’ll take a look at some of the secrets in Kubernetes and how they can help you manage your containers more effectively. What are secrets in Kubernetes? Secrets are important components of any container orchestration system, as they allow administrators to control which containers can access which resources. In Kubernetes, secrets are stored in the kube-system namespace and can be accessed using the kubeconfig file format. Some common uses for secrets in Kubernetes include controlling access to nodes within a cluster or managing authentication credentials for users accessing the system. Secrets can also be used to configure specific aspects of the system, such as setting up load balancers or deploying applications into specific nodes within a cluster. How do I create secrets in Kubernetes? To create a secret in Kubernetes, you first need to create a namespace containing the secret objects you want to store. You then use the kubeconfig file format to specify which nodes should have access to the secret objects and what permissions they should have. For example, you might use a secret namespace to store authentication credentials for users accessing your application servers: # Create an authentication credential secret namespace named “mysecrets” $ kubectl create -f mysecrets .kubeconfig –namespace mysecrets Creating ‘mysecrets’ ..
Kubernetes Secrets let you store confidential information safely. Using a Secret removes the need to bake sensitive data into manifest definitions or plain container images.
Secrets are a first-class resource type which exist independently of any Pod. You provide Pods with references to your Secrets. The architecture lets you confine secrets access to only those Pods that actually need the data.
You generally use Secrets for any sensitive constants which your Pods may need. They’re ideal for storing authentication keys, database credentials and API tokens.
Creating a Secret
Secrets are created in the same way as any other Kubernetes API resource. You can use Kubectl commands or a YAML manifest which you then apply to your cluster. We’ll provide example YAML files in this tutorial.
Heres’s how to define a user-created secret:
Secrets consist of a kind and a simple object of data. The example secret defines two separate data fields, SECRET_USERNAME and SECRET_PASSWORD. Values must be Base64-encoded – the values shown above were originally username and password.
If you’re working with a Helm template, you can define your secret values in a values.yaml file. Pipe them through b64enc in your manifest to have Helm encode them as Base64.
If you’d rather not Base64-encode your values, you can use the stringData field instead. Like data, stringData is a map of key-value pairs but the values will be processed verbatim, without any encoding.
Secret Types
The Opaque secret type should be used for arbitrary data that you define yourself. Kubernetes defines a few other built-in secret types intended for specific usage scenarios.
Available types include service-account-token (a Kubernetes service token), dockerconfigjson (a serialised Docker config.json file, to provide Docker credentials) and ssh-auth (provide SSH credentials). In addition to these types, there are solutions for HTTP Basic Authentiation and TLS certificate data.
Each secret type is able to define its own extra fields and validation constraints. You’ll typically need to set additional annotations on your secret to provide the data needed by the secret type.
You can create your own secret type identifiers by supplying your own string to the type field. The resulting secret will be functionally equivalent to the Opaque type.
Providing Secrets to Pods
Once you’ve created a Secret, you need to make it available to your Pods. You can inject secret data as environment variables or as a file mounted into a volume.
Here’s a Pod manifest that pulls a secret’s data into environment variables:
By using envFrom, all the key-value pairs defined in the secret’s data will be converted to container environment variables. With the example secret from earlier, your container would have SECRET_USERNAME and SECRET_PASSWORD environment variables injected. Values will be automatically Base64-decoded.
Sometimes you’ll want to work with files instead of environment variables. Here’s how to mount a secret into a Kubernetes volume.
Access the /secrets directory within the container to view the secret data. Each data key will have its own file. The contents of the file will be the Base64-decoded value of that key. Our example secret would write /secrets/SECRET_USERNAME and /secrets/SECRET_PASSWORD files.
The approach works by creating a Kubernetes volume using the secret source. This source populates the volume with the data from a named secret. The volume then gets mounted into the container at the path defined under volumeMounts.
Security Considerations
Putting data into a secret does not automatically make it secure. The Base64-encoding provides superficial obscurity but make no mistake: this is encoding and not encryption. Anything with access to your cluster, whether a human user or a suitably permissioned application, can retrieve plain-text secret values.
The point of secrets is to reduce the risk of accidental data exposure when creating and viewing Pods. Secrets are only provided to Pods – and to Nodes – which actually require them. Node will destroy their local copies of secrets when the Pod that used them terminates.
The Kubernetes control plane stores secret values within its etcd instance. This is a key-value store which backs the Kubernetes cluster data. If you want to maximise security, you should configure encryption at rest for your etcd store. This will encrypt your secrets within etcd.
You should also assess how your application layer handles secrets. Even with encryption at rest enabled, your containers could inadvertently leak secrets by emitting them to job logs or sending them to external services. Using Kubernetes secrets doesn’t obviate the need to carefully handle sensitive data within your container.
Summary
Kubernetes secrets let you store and access confidential data within your Kubernetes cluster. Using secrets gives you more control over information exposure. It also makes it explicit that you’re handling potentially sensitive values. This can act as a warning to cluster users and administrators.
Pods consume secrets as either environment variables or volume-mounted files. Kubernetes handles the injection of secrets into containers. Your workloads can access the data using their existing configuration mechanisms. Secrets aren’t fully secure by default but you can increase their protection by activating cluster-level encryption.