I have a single values.yaml file with the following two containers:
...
nginx:
image:
repository: _ADDRESS_
tag: stable
pullPolicy: IfNotPresent
flask:
image:
repository: _ADDRESS_
tag: stable
pullPolicy: IfNotPresent
...
Is it best practice to duplicate the following code manually within the deployment file for each container and just change the variables or is there a more standard way of dealing with this? Feels as if it limits the abstraction so was just curious as to whether I am doing this wrong.
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
Thank you for your time. If there are any details I can add to simplify my question, please don't hesitate to mention them and I will edit the post.
CodePudding user response:
I believe this covers your need, omit the image,tag and pull policy in your values and you can use the default function as
.
.
image: "{{ .Values.image.repository | default "_ADDRESS_" }}:{{ .Values.image.tag | default "stable" }}"
imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }}
.
.
Additional info, you can even provide a more dynamical behavior using Template function list
CodePudding user response:
Is it best practice to duplicate the following code manually within the deployment file for each container
Yes.
In principle it's possible to write a generic Helm template that produces a Deployment YAML specification. But then you'll run into a problem where the Flask application listens on port 5000 but the Nginx server uses port 80, and the Flask application has a dedicated /health
endpoint but the Nginx server should just probe /
, and so on, and you'd need to make these differences visible in the values.yaml
. This has two problems: you're exposing fixed details of the application as configuration, and in effect you're republishing the entire Kubernetes YAML structure as Helm values.
For some things that really do get repeated over and over, you could use a helper template; for example
{{- define "container.common" -}}
securityContext: {{- toYaml .Values.securityContext | nindent 2 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
resources: {{- toYaml .Values.resources | nindent 2 }}
{{- end -}}
- name: {{ .Chart.Name }}
{{ include "container.common" . | indent 2 }}
ports: { ... }
livenessProbe: { ... }
readinessProbe: { ... }
But for details like ports:
and the probes, again, these are fixed properties of the image (the Flask application will always listen on port 5000 and the end user will never need to configure it) and it's appropriate to write it in the templates/flask-deployment.yaml
file, even if it looks very similar to settings in other files.