Chart per service approach
Use a Helm chart per microservice approach if you seek to achieve flexible, simple versioning and low complexity charts to package your application. Be careful, this technique might bring:
-
huge amount of duplication
-
difficulty to keep consistent many templates
-
hardship to introduce global changes
Goal of this section: customize the configuration of the tutorial microservice with another template and deploy it using Helm charts in a different namespace/project.
Inject configurations from a configmap template
When working with a microservice it is likely that you will inject and manage configurations using other Kubernetes resources, like ConfigMap or Secret.
Let’s inject a configuration from a ConfigMap for the tutorial microservice.
Navigate to the templates
folder and create a configmap.yaml
.
Open the configmap.yaml
you just created and add the following:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.configmap.region | quote }}
labels:
{{- include "faq.labels" . | nindent 4 }}
data:
region: {{.Values.configmap.region | upper | quote }} (1)
1 | Change the value for region to uppercase. |
Now add the default value for a region in values.yaml
:
configmap:
key: region
region: cee
And configure the deployment.yaml
template to use the new configmap:
env:
- name: POSTGRES_SERVER
value: {{ .Values.postgresql.server | default (printf "%s-postgresql" ( .Release.Name )) | quote }}
- name: POSTGRES_USERNAME
value: {{ .Values.postgresql.postgresqlUsername | quote }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.postgresql.secretName | default (printf "%s-postgresql" ( .Release.Name )) | quote }}
key: {{ .Values.postgresql.secretKey }}
- name: REGION
valueFrom:
configMapKeyRef:
name: {{ .Values.configmap.region }}
key: {{ .Values.configmap.key }}
Automatically roll out Deployments when a ConfigMap/Secret changes
Configmaps and Secrets are often used as configuration files, but when values change in these files they are not automatically picked up by a running application unless the deployment spec itself changes. This can potentially result in inconsistent deployments where the values have been updated but the application is actually still running with the old configuration wich is not what we want.
A solution to this problem is to use a sha256sum
function which can be used to ensure a deployment’s annotation section is updated if another file changes:
Don’t change the deployment.yaml file. This next snippet is just an example. |
kind: Deployment
spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
We can make this change even more elegant, because helm autogenerated the inclusion of annotations in deployment.yaml
when we initialized our Chart:
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
The above states the following: only if .Values.podAnnotations
is defined, then get the yaml definition from there.
We can thus modify the values.yaml
accordingly:
The podAnnotations key might already be present in the values.yaml. Update it if it exists, or create a new entry if it’s missing.
|
podAnnotations:
checksum/config: '{{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}'
As the above value contains both YAML and a Go template, we need to parse the yaml (toYaml
)
and use the template (tpl
) in deployment.yaml
with:
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
Upgrade the release
Update the existing release with the newly added configurations:
helm upgrade simple ./chart/faq
Run the following commands to verify the CEE output:
export POD_NAME=$(oc get pods -l app.kubernetes.io/instance=simple -o jsonpath={.items[0]..metadata.name})
kubectl exec $POD_NAME -- /bin/curl -s localhost:8080/ask/CEE
The output should be a JSON Array that contains an Object with the region set to a capitalized version of cee
from the configmap
in values.yaml.
Uninstall a release
Simply run the following command to uninstall your previous releases:
helm uninstall simple
helm uninstall faq-db
Replicate the installation in a different namespace
Let’s create a different namespace:
kubectl create ns qa
#permanently save the namespace for all subsequent kubectl commands
kubectl config set-context --current --namespace=qa
oc create project qa
And define a set of values for this namespace by making a copy of values.yaml
. Name the copy values.qa.yaml
.
Modify the region inside values.qa.yaml
:
configmap:
key: region
region: benelux
And now install the charts:
helm install faq-db \
--set postgresqlUsername=faq-default,postgresqlPassword=postgres,postgresqlDatabase=faq,persistence.enabled=false,securityContext.enabled=false,containerSecurityContext.enabled=false \
bitnami/postgresql (1)
helm install simple ./chart/faq --values ./chart/faq/values.qa.yaml (2)
helm install faq-db --set postgresqlUsername=faq-default,postgresqlPassword=postgres,postgresqlDatabase=faq,persistence.enabled=false,securityContext.enabled=false,containerSecurityContext.enabled=false,primary.podSecurityContext.enabled=false,primary.containerSecurityContext.enabled=
false --version 12.1.2 bitnami/postgresql (1)
helm install simple ./chart/faq --values ./chart/faq/values.qa.yaml (2)
1 | Install the PostgreSQL Helm chart in the new namespace/project. |
2 | Install the faq Helm chart in the qa namespace using the values dedicated to this namespace. |