Kubernetes Configuration: configMaps, secrets, volumes
[!NOTE] Visit Kubernetes documentation if you need a refresher about Configuration
Basic definitions are provided on diagrams below
How does it work?
Kubernetes natively supports 2 resources geared towards storing configuration consumed by pods. Both configuration types required data to be represented in a key:value pair format.
- Config Maps: use to store non-confidential data
- Secrets: use to store confidential data (tokens, SSH keys, passwords, certificates, etc)
[!ATTENTION] Config maps are not suited for storing large quantities of data. Please use external storage for this purpose. As a side-note, etcd, key-value store where Kubernetes stores all its state can only hold resources up to 1MN in size.
Secrets in Kubernetes are actually not encrypted, but rather base64 encoded, so best for storing critical sensitive information, recommendation is to use key vaults such as Hashicorp Vault with Helm sidecar or native offerings from public cloud providers, like Azure Key Vault.
Both config maps and secrets can be mounted into pods in 2 ways:
- As volumes
- As environmental variables
[!TIP] Below diagram shows those options on the example of config map, same applies to secrets
What Problem does it solve?
- enable separations of application code and configuration
- enable ingestion of secrets and other security sensitive information
- updates to config maps or secrets reflects in pods automatically
How to implement it?
Prerequisites
We are going to implement the example using Docker Desktop, since PWK does not work for me since a few days. The examples however will work on any Kubernetes setup.
Create Kubernetes Resources
[!NOTE] To work easier with kubectl we will create an alias
alias k=kubectl
We will create separate Kubernetes resources per experiment
[!WARNING] Always check content of the files before creating resources from remote source.
Let's experiment
[!TIP] Each experiment has corresponding
asciinema
recording, you can follow along and also copy/paste commands directly from the recording.
We are going to revisit scenarios from the section What Problem does it solve? and validate that the statements are correct.
Enable separations of application code and configuration
- Create config map
- Create deployment with config map mounted as volume
- Check how config map data is mounted into a folder specified in pod template
Resources to create:
#Create config map:
k apply -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/1-create-configmap.yaml
#Create deployment with config map mounted as volume:
k apply -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/4-Create-deployment.yaml
Cleanup Resources:
#Delete deployment:
k delete -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/4-Create-deployment.yaml
#Delete config map:
k delete -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/1-create-configmap.yaml
Conclusion: We have successfully proven applications and configuration can be easily decoupled using confg maps
Enable ingestion of secrets and other security sensitive information
[!TIP] Secrets are by detaulf base64 encoded, but it's possible to create secret with plain text by using stringData: instead of data section of secret YAML
Resources to create:
#Create encoded secret:
k apply -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/3-create-secret-encoded.yaml
#Create deployment with secret mounted as volume:
k apply -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/5-create-deployment-secret.yaml
- Create secret
- Create deployment with secret mounted as volume
- Check if secret is correctly mounted to a pod
- Display secret password value using describe command
- Decode secret password value from base64
echo 'dW5icmVha2FibGU=' | base64 --decode
Cleanup Resources:
#Delete encoded secret:
k delete -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/3-create-secret-encoded.yaml
#Delete deployment:
k delete -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/5-create-deployment-secret.yaml
[!ATTENTION] Kubernetes currently does not encrypt secrets in its data store etcd. Mounted secrets are only encoded, nevertheless, there are discussions to provide secrets encryption at rest and in transit, so it's considered best practice to use secrets whenever dealing with sensitive information.
Conclusion: We have successfully proven that base64 encoded secrets can be ingested and consumed by pod and in turn containers
Updates to config maps or secrets reflects in pods automatically
[!ATTENTION]
- This functionality applies only to configuration or secrets mounted to pods as volumes
- If you would like to reflect changes in environmental variables injected from configs or secrets, manual pod restart is required
- You can vote here to push up https://github.com/kubernetes/kubernetes/issues/22368 to introduce auto restarts similar to configs and secrets mounted as volumes
- Alternatively admission controller setup is possible, but this is out of scope for this exercise
Create Resources:
#Create config map:
k apply -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/1-create-configmap.yaml
#Create deployment with config map mounted as volume:
k apply -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/4-Create-deployment.yaml
- Create config map
- Create deployment with config map mounted as volume
- Check how config map data is mounted into a folder specified in pod template
- Edit config map and adjust one value
- Check how config map data is is updated in a folder pod specified in pod template as mount point
Cleanup Resources:
#Delete deployment:
k delete -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/4-Create-deployment.yaml
#Delete config map:
k delete -f https://raw.githubusercontent.com/Piotr1215/dca-exercises/master/k8s/configuration/1-create-configmap.yaml
Conclusion: We have successfully proven configuration values mounted to pod as volume are auto updated after config map changes
Challenge
Is there anything you would like to test? Think about a scenario, test it and let us know in comments.