Kubernetes Configs
Creating a ConfigMap
You can create a ConfigMap imperatively with a single command: kubectl create configmap. As part of the command, you have to provide a mandatory command-line flag that points to the source of the data. Kubernetes distinguishes four different options:
- Literal values, which are key-value pairs as plain text.
- A file that contains key-value pairs and expects them to be environment variables.
- A file with arbitrary contents.
- A directory with one or many files.
The following commands show all options in action. You will find that a file and directory use the same command-line option, --from-file. Later, we’ll revisit how those key-value pairs are parsed and stored in a ConfigMap.
Literal values
kubectl create configmap db-config --from-literal=db=staging
Single file with environment variables
configmap/db-config created
ConfigMap YAML file manifest:
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-config
data:
database_url: jdbc:postgresql://localhost/test
user: fred
Consuming a ConfigMap as Environment Variables
apiVersion: v1
kind: Pod
metadata:
name: configured-pod
spec:
containers:
- image: nginx:1.19.0
name: app
envFrom:
- configMapRef:
name: backend-config
Sometimes, key-value pairs do not conform to typical naming conventions for environment variables or can’t be changed without impacting running services. You can redefine the keys used to inject an environment variable into a Pod with the valueFrom attribute.
apiVersion: v1
kind: Pod
metadata:
name: configured-pod
spec:
containers:
- image: nginx:1.19.0
name: app
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: backend-config
key: database_url
- name: USERNAME
valueFrom:
configMapKeyRef:
name: backend-config
key: user
Mounting a ConfigMap as Volume
Most programming languages can resolve and use environment variables to control the runtime behavior of an application. Especially when dealing with a long list of configuration data, it might be preferable to access the key-value pairs from the filesystem of the container.
apiVersion: v1
kind: Pod
metadata:
name: configured-pod
spec:
containers:
- image: nginx:1.19.0
name: app
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: backend-config
Creating a Secret
You can create a Secret imperatively with a single command: kubectl create secret. Similar to the command for creating a ConfigMap, you will have to provide an additional subcommand and a configuration option. It’s mandatory to spell out the subcommand right after the Kubernetes resource type secret.
In most cases, you will likely deal with the type generic, which provides the same command-line options to point to the source of the configuration data as kubectl create configmap:
- Literal values, which are key-value pairs as plain text.
- A file that contains key-value pairs and expects them to be environment variables.
- A file with arbitrary contents.
- A directory with one or many files.
kubectl create secret generic db-creds --from-literal=pwd=s3cre!
Of course, you can always take the declarative route, but there’s a little catch. You have to Base64-encode the configuration data value yourself when using the type Opaque. How can you do so? One way to encode and decode a value is the Unix command-line tool base64.
Declarative way:
apiVersion: v1
kind: Secret
metadata:
name: db-creds
type: Opaque
data:
pwd: czNjcmUh
Consuming a Secret as Environment Variables
Consuming the key-value pairs of a Secret as environment variables from a container works almost exactly the same way as it does for a ConfigMap. There’s only one difference: instead of using envFrom.configMapRef, you’d use envFrom.secretRef:
apiVersion: v1
kind: Pod
metadata:
name: configured-pod
spec:
containers:
- image: nginx:1.19.0
name: app
envFrom:
- secretRef:
name: db-creds
It’s important to understand that the container will make the environment variable available in a Base64-decoded value. In turn, your application running in the container will not have to implement Base64-decoding logic.
Creating a ResourceQuota
The Kubernetes primitive ResourceQuota establishes the usable, maximum amount of resources per namespace. Once put in place, the Kubernetes scheduler will take care of enforcing those rules.
Creating a ResourceQuota object is usually a task a Kubernetes administrator would take on, but it’s relatively easy to define and create such an object. First, create the namespace the quota should apply to:
kubectl create namespace team-awesome
kubectl get namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: awesome-quota
spec:
hard:
pods: 2
requests.cpu: "1"
requests.memory: 1024m
limits.cpu: "4"
limits.memory: 4096m
kubectl create -f awesome-quota.yaml --namespace=team-awesome
kubectl describe resourcequota awesome-quota --namespace=team-awesome
Test Pod Manifest:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx:1.18.0
name: nginx
resources:
requests:
cpu: "0.5"
memory: "512m"
limits:
cpu: "1"
memory: "1024m"