ConfigMap
ConfigMap is the Kubernetes resource that allows you to externalize your application’s configuration.
An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc).
Environment Variables
MyRESTController.java includes a small chunk of code that looks to the environment
@RequestMapping("/configure")
public String configure() {
String databaseConn = environment.getProperty("DBCONN","Default");
String msgBroker = environment.getProperty("MSGBROKER","Default");
String hello = environment.getProperty("GREETING","Default");
String love = environment.getProperty("LOVE","Default");
return "Configuration: \n"
+ "databaseConn=" + databaseConn + "\n"
+ "msgBroker=" + msgBroker + "\n"
+ "hello=" + hello + "\n"
+ "love=" + love + "\n";
}
Environment variables can be manipulated at the Deployment level. Changes cause Pod redeployment.
Deploy myboot
:
kubectl apply -f apps/kubefiles/myboot-deployment.yml
Deploy myboot
Service:
kubectl apply -f apps/kubefiles/myboot-service.yml
And watch the pods status:
watch -n 1 -- kubectl get pods
Ask the application for its configuration:
IP=$(minikube ip -p devnation)
PORT=$(kubectl get service/myboot -o jsonpath="{.spec.ports[*].nodePort}")
If using a hosted Kubernetes cluster like OpenShift then use curl and the EXTERNAL-IP address with port 8080
or get it using kubectl
:
IP=$(kubectl get service myboot -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
PORT=$(kubectl get service myboot -o jsonpath="{.spec.ports[*].port}")
If you are in AWS, you need to get the hostname instead of ip.
|
IP=$(kubectl get service myboot -o jsonpath="{.status.loadBalancer.ingress[0].hostname}")
Curl the Service:
curl $IP:$PORT
curl $IP:$PORT/configure
Configuration for : myboot-66d7d57687-jsbz7
databaseConn=Default
msgBroker=Default
greeting=Default
love=Default
Set Environment Variables
kubectl set env deployment/myboot GREETING="namaste" \
LOVE="Aloha" \
DBCONN="jdbc:sqlserver://45.91.12.123:1443;user=MyUserName;password=*****;"
Watch the pods being reborn:
NAME READY STATUS RESTARTS AGE
myboot-66d7d57687-jsbz7 1/1 Terminating 0 5m
myboot-785ff6bddc-ghwpc 1/1 Running 0 13s
curl $IP:$PORT/configure
Configuration for : myboot-5fd9dd9c59-58xbh
databaseConn=jdbc:sqlserver://45.91.12.123:1443;user=MyUserName;password=*****;
msgBroker=Default
greeting=namaste
love=Aloha
Describe the deployment:
kubectl describe deployment myboot
...
Containers:
myboot:
Image: quay.io/burrsutter/myboot:v1
Port: 8080/TCP
Host Port: 0/TCP
Environment:
GREETING: namaste
LOVE: Aloha
DBCONN: jdbc:sqlserver://45.91.12.123:1443;user=MyUserName;password=*****;
Mounts: <none>
Volumes: <none>
...
Remove environment variables:
kubectl set env deployment/myboot GREETING- \
LOVE- \
DBCONN-
And verify that they have been removed:
curl $IP:$PORT/configure
Configuration for : myboot-66d7d57687-xkgw6
databaseConn=Default
msgBroker=Default
greeting=Default
love=Default
Create a ConfigMap
kubectl create cm my-config --from-env-file=apps/config/some.properties
kubectl get cm
kubectl get cm my-config
kubectl get cm my-config -o json
...
"data": {
"GREETING": "jambo",
"LOVE": "Amour"
},
"kind": "ConfigMap",
...
Or you can describe the ConfigMap
object:
kubectl describe cm my-config
Name: my-config
Namespace: myspace
Labels: <none>
Annotations: <none>
Data
====
GREETING:
====
jambo
LOVE:
====
Amour
Events: <none>
Now deploy the app with its request for the ConfigMap
:
kubectl apply -f apps/kubefiles/myboot-deployment-configuration.yml
And get its configure endpoint:
curl $IP:$PORT/configure
Configuration for : myboot-84bfcff474-x6xnt
databaseConn=Default
msgBroker=Default
greeting=jambo
love=Amour
And switch to the other properties file by recreating the ConfigMap
:
kubectl delete cm my-config
kubectl create cm my-config --from-env-file=apps/config/other.properties
kubectl delete pod -l app=myboot --wait=false
curl $IP:$PORT/configure
Configuration for : myboot-694954fc6d-nzdvx
databaseConn=jdbc:sqlserver://123.123.123.123:1443;user=MyUserName;password=*****;
msgBroker=tcp://localhost:61616?jms.useAsyncSend=true
hello=Default
love=Default
There are a lot more ways to have fun with ConfigMaps. The core documentation has you manipulate a Pod specification instead of a Deployment, but the results are basically the same: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap