All-Things-Docker-and-Kubernetes

ConfigMaps and Secrets


This page appears in both the Kubernetes section and Kubernetes Security section.


ConfigMaps

ConfigMaps are a type of Kubernetes Resource that is used to decouple configuration artifacts from container image content to keep containerized applications portable. The configuration data is stored as key-value pairs.

ConfigMaps can be created from:

Like most Kubernetes Resources, ConfigMaps are namespaced so only Pods in the same Namespace as a ConfigMap can use the ConfigMap.

Inject the ConfigMap

To see an example of a ConfigMap file, check out this lab. After the ConfigMap is created, the next step is to inject it to the Pod.

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    name: myapp
spec:
  containers:
  - name: myapp
    image: <Image>
    ports:
      - containerPort: <Port>
    envFrom:
      - configMapRef:
            name: USERNAME

Ways to inject the ConfigMap in Pods

As an environment variable:

    envFrom:
      - configMapRef:
            name: USERNAME

As a single environment variable:

    env:
      - name: DB_Username 
        valueFrom:
            configMapKeyRef:
                name: app_configMap
                key: DB_Username

Mount the configMap as a volume to the container

    volumes:
      - name: app-configMap-volumes 
        configMap:
            name: app-configMap

Secrets

Similar to ConfigMaps, Secrets are also custom resources which can be stored separately instead of including them in the specs file. The main difference between these two custom resources is that secrets are specifically used for storing sensitive information.

Secrets reduce the risk of accidental exposure compared to if they were stored in an image or put in a Pod specification.

In addition to this, secrets supports the following:

Base64 encoded

It is important to note that secrets are not encrypted at rest by default and are instead only base-64 encoded. Anyone with the base64 encoded secret can easily decode it. As such the secrets can be considered as not very safe.

The Kubernetes documentation page and a lot of blogs out there refer to secrets as a “safer option” to store sensitive data. They are safer than storing in plain text as they reduce the risk of accidentally exposing passwords and other sensitive data. In general, it’s not the secret itself that is safe, it is the practices around it.

Best Practices

Secrets are not encrypted, so it is not safer in that sense. However, some best practices around using secrets make it safer:

By following the pattern of storing sensitive data in Secrets, users of the cluster can be denied access to Secrets but granted access to ConfigMaps using Kubernetes access control mechanisms.

How Kubernetes handles secrets

Kubernetes also handles secrets in various ways:

Having said that, there are other better ways of handling sensitive data like passwords in Kubernetes, such as using tools like:

Ways to create a secret

Imperative approach, using the command below:

```bash
# Supply secrets directly on the command 
kubectl create secret generic  \
     <secret-name></secret-name>  \
     --from-literal=<key>=<value>

# Use secrets defined in a file
kubectl create secret generic  \
     <secret-name></secret-name>  \
     --from-file=<filename.json>
```

Declarative approach, using a spec file:

```yaml
apiVersion: v1
kind: Secret
metadata:
    name: mysecret  
type: Opaque
data:
    variable1: sdferr==
    variable1: vdsrfg==
    variable1: weri34rf

## Note that the value for the variable should be the 
## base64-encoded format of the original secret. 
## To encode the original secret:
#       echo -n 'original-password' | base64 
```

To retrieve the secrets:

kubectl get secrets 
kubectl describe secrets 

The next step is to inject the secret to the Pod or Deployment manifest.

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    name: myapp
spec:
  containers:
  - name: myapp
    image: <Image>
    ports:
      - containerPort: <Port>
    envFrom:
      - secretRef:
            name: USERNAME

Inject the Secrets

As an environment variable:

    envFrom:
      - secretRef:
            name: USERNAME

As a single environment variable :

    env:
      - name: DB_Username 
        valueFrom:
            secretKeyRef:
                name: app_secret
                key: DB_Username

Mount the secret as a volume to the container

    volumes:
      - name: app-secret-volumes 
        secret:
            secretName: app-secret

Notes on Secrets

Best practices around using secrets

Also the way kubernetes handles secrets. Such as:

ConfigMaps and Secrets in Action

To see ConfigMaps and Secrets in actions check out this lab.


Back to first page