May 25, 2017
This post assumes that you have basic understanding of Kubernetes terms like pods and deployments.
We deploy our Rails applications on Kubernetes and frequently do rolling deployments.
While performing application deployments on kubernetes cluster, sometimes we need to change the application configuration file. Changing this application configuration file means we need to change source code, commit the change and then go through the complete deployment process.
This gets cumbersome for simple changes.
Let's take the case of wanting to add queue in sidekiq configuration.
We should be able to change configuration and restart the pod instead of modifying the source-code, creating a new image and then performing a new deployment.
This is where Kubernetes's ConfigMap comes handy. It allows us to handle configuration files much more efficiently.
Now we will walk you through the process of managing sidekiq configuration file using configmap.
First we need to create a configmap.
We can either create it using kubectl create configmap
command
or
we can use a yaml template.
We will be using yaml template test-configmap.yml
which already has sidekiq configuration.
apiVersion: v1
kind: ConfigMap
metadata:
name: test-staging-sidekiq
labels:
name: test-staging-sidekiq
namespace: test
data:
config: |-
---
:verbose: true
:environment: staging
:pidfile: tmp/pids/sidekiq.pid
:logfile: log/sidekiq.log
:concurrency: 20
:queues:
- [default, 1]
:dynamic: true
:timeout: 300
The above template creates configmap in the test
namespace and is only accessible in that namespace.
Let's launch this configmap using following command.
$ kubectl create -f test-configmap.yml
configmap "test-staging-sidekiq" created
After that let's use this configmap to create our sidekiq.yml
configuration file in deployment template named test-deployment.yml
.
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-staging
labels:
app: test-staging
namespace: test
spec:
template:
metadata:
labels:
app: test-staging
spec:
containers:
- image: <your-repo>/<your-image-name>:latest
name: test-staging
imagePullPolicy: Always
env:
- name: REDIS_HOST
value: test-staging-redis
- name: APP_ENV
value: staging
- name: CLIENT
value: test
volumeMounts:
- mountPath: /etc/sidekiq/config
name: test-staging-sidekiq
ports:
- containerPort: 80
volumes:
- name: test-staging-sidekiq
configMap:
name: test-staging-sidekiq
items:
- key: config
path: sidekiq.yml
imagePullSecrets:
- name: registrykey
Now let's create a deployment using above template.
$ kubectl create -f test-deployment.yml
deployment "test-pv" created
Once the deployment is created, pod running from that deployment will start sidekiq using the sidekiq.yml
mounted at /etc/sidekiq/config/sidekiq.yml
.
Let's check this on the pod.
deployer@test-staging-2766611832-jst35:~$ cat /etc/sidekiq/config/sidekiq_1.yml
---
:verbose: true
:environment: staging
:pidfile: tmp/pids/sidekiq_1.pid
:logfile: log/sidekiq_1.log
:concurrency: 20
:timeout: 300
:dynamic: true
:queues:
- [default, 1]
Our sidekiq process uses this configuration to start sidekiq. Looks like configmap did its job.
Further if we want to add one new queue to sidekiq, we can simply modify the configmap template and restart the pod.
For example if we want to add mailer
queue we will modify template as shown below.
apiVersion: v1
kind: ConfigMap
metadata:
name: test-staging-sidekiq
labels:
name: test-staging-sidekiq
namespace: test
data:
config: |-
---
:verbose: true
:environment: staging
:pidfile: tmp/pids/sidekiq_1.pid
:logfile: log/sidekiq_1.log
:concurrency: 20
:queues:
- [default, 1]
- [mailer, 1]
:dynamic: true
:timeout: 300
Let's launch this configmap using following command.
$ kubectl apply -f test-configmap.yml
configmap "test-staging-sidekiq" configured
Once the pod is restarted, it will use new sidekiq configuration fetched from the configmap.
In this way, we keep our Rails application configuration files out of the source-code and tweak them as needed.
If this blog was helpful, check out our full blog archive.