Skip to main content
Welcome to this comprehensive guide on securing your applications with Kubernetes Secrets. In this lesson, you’ll learn how to replace hardcoded sensitive data in your applications with a more secure approach using Kubernetes Secrets. We will walk through a Python web application example, demonstrate both imperative and declarative methods for creating Secrets, and explain how to inject these Secrets into your Pods securely.

Example Application Overview

In our example, a simple Python web application connects to a MySQL database. On a successful connection, the application displays a success message. However, the code currently hardcodes the database hostname, username, and password. Although non-sensitive data such as hostnames or usernames can be stored in a ConfigMap, using the same approach for sensitive information like passwords is not recommended. Below is an excerpt of the Python application code:
Hardcoding credentials in your application code is insecure. Use Kubernetes Secrets to manage sensitive configuration data securely.
A sample ConfigMap for non-sensitive configurations might look like this:
While a ConfigMap can hold non-sensitive values safely, passwords require an extra layer of security. This is where Kubernetes Secrets become essential—they store sensitive information in an encoded format rather than plain text.

Steps to Work with Kubernetes Secrets

Creating and using Secrets generally involves two main steps:
  1. Create the Secret.
  2. Inject the Secret into a Pod.

Mapping Plain Text to Base64 Encoded Values

Consider the following mapping between plain text values and their corresponding base64-encoded values: Plain text:
Encoded format:
Always encode your sensitive data using base64 when creating a declarative Secret. Avoid using plain text values.

Creating a Secret

There are two primary methods to create a Kubernetes Secret: the imperative and declarative approaches.

Imperative Approach

With the imperative approach, you can directly add key-value pairs from the command line. For example, to create a secret named “app-secret” with values for DB_Host, DB_User, and DB_Password, use:
Alternatively, if you have your data stored in a file, you can create the secret with:

Declarative Approach

For a more controlled process, create a YAML definition for the Secret. Note that all values must be base64 encoded. Here is an example:
Create the Secret by applying the YAML file:
Note: When specifying data values in plain text, the information is not secure. Ensure that the secret values are base64 encoded using one of the available encoding methods.

Encoding Secret Data

On a Linux system, you can generate the base64-encoded version of your secret by running:

Viewing and Decoding Secrets

To list all Secrets, execute:
Sample output:
To view detailed information about a specific Secret without revealing its actual values, use:
For example:
To display the Secret in YAML format (this shows the encoded values), run:
To decode an encoded value, execute:

Injecting Secrets into a Pod

After creating a Secret, you can inject it into a Pod in two ways: as environment variables or as files via a mounted volume.

Injecting as Environment Variables

Use the envFrom property in your container specification to inject the Secret data as environment variables. For example:
All key-value pairs in the “app-secret” will be available as environment variables in your container.

Injecting as Files in a Volume

Alternatively, mount the Secret as a volume so that each key is written into a separate file. Example configuration:
Mount the volume into your container (for instance, at /opt/app-secret-volumes) and inspect the files:

Security Considerations

When managing Secrets in Kubernetes, keep the following security best practices in mind:
  • Kubernetes Secrets are encoded but not encrypted, meaning anyone with access can decode them using base64.
  • Avoid checking in secret definition files to version control systems, such as GitHub.
  • By default, Secrets stored in etcd are not encrypted. Consider enabling encryption at rest for enhanced security.

Enabling Encryption at Rest

To enhance security, enable encryption at rest by configuring an encryption file similar to the snippet below:
Then, pass the configuration to the kube-apiserver. Modify your API server Pod specification as follows:
Keep in mind that anyone who can create Pods or Deployments in the same namespace could potentially access these Secrets. Use role-based access control (RBAC) to limit access effectively. For additional protection, consider integrating third-party secret providers such as the AWS Provider, Azure Provider, GCP Provider, or Vault Provider. These external solutions store Secrets outside etcd and provide advanced security controls.
The image provides guidelines on handling secrets, emphasizing encryption, access control, and considering third-party providers for secure storage.

Conclusion

In this lesson, we covered the importance of managing sensitive data in Kubernetes using Secrets. We discussed both imperative and declarative methods to create Secrets, learned how to inject them into your Pods as environment variables or as files in a volume, and reviewed critical best practices along with encryption strategies. Practice these techniques to improve the security of your Kubernetes deployments and safeguard your sensitive data. For more detailed information, explore the official Kubernetes Documentation.

Watch Video

Practice Lab