I have a deployment with a pod that has his configuration defined through a lot of environment variables. Now I want to add a sidecar container that requires exactly the same environment variables as the already defined container. Instead of just copy/pasting all the variables I'd like to stick to the DRY principle.
The current definition looks something like this:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: container1
env:
- name: MYSQL_HOST
value: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
- name: MYSQL_DATABASE
value: {{ .Values.mariadb.auth.database | quote }}
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }}
key: {{ .Values.usernameKey | default "db-username" }}
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }}
key: {{ .Values.passwordKey | default "db-password" }}
The recommended way to reuse environment variables is through a ConfigMap. Now I can create this:
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
MYSQL_HOST: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
MYSQL_DATABASE: {{ .Values.mariadb.auth.database | quote }}
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: container1
envFrom:
- configMapRef:
name: config
- name: container2
envFrom:
- configMapRef:
name: config
But now I would still need to repeat myself for MYSQL_USER
and MYSQL_PASSWORD
(and for the 20 other env variables that are like this).
Is it possible to reuse the existing secrets MYSQL_USER
and MYSQL_PASSWORD
as environment variables without creating duplicates on container1
and container2
?
CodePudding user response:
You can do the same thing but mount a secret:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: secret
stringData:
MYSQL_USER: {{ .Values.usernameKey | default "db-username" }}
MYSQL_PASSWORD: {{ .Values.passwordKey | default "db-password" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
MYSQL_HOST: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
MYSQL_DATABASE: {{ .Values.mariadb.auth.database | quote }}
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: container1
envFrom:
- configMapRef:
name: config
- secretRef:
name: secret
- name: container2
envFrom:
- configMapRef:
name: config
- secretRef:
name: secret
CodePudding user response:
You can create a named template to do this. If you're only going to be using this template within a single Kubernetes object (multiple containers within the same Deployment) you could put it in that object's deployment.yml
file, or into the shared _helpers.tpl
file.
{{- define "env.mysql" -}}
- name: MYSQL_HOST
value: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
- name: MYSQL_DATABASE
value: {{ .Values.mariadb.auth.database | quote }}
- name: ET
value: cetera
{{- end -}}
Then wherever you need to use that block of variables, you can include
it, and indent
it to the correct level.
spec:
template:
spec:
containers:
- name: container1
env:
{{- include "env.mysql" . | indent 10 }}
- name: OTHER_ENVIRONMENT_VARIABLES
value: are okay too
Having define
d the template once, you can include
it as many times as you need to.