The Art of Helm Chart: Patterns from the Official Kubernetes Charts

Installing and managing Helm Charts can give you some complications that you may not have encountered before.







Helm Charts packages applications for installation into Kubernetes clusters. Installing Helm Chart is a bit like launching



, so Helm Chart developers face some of the same issues that developers producing installers face:







  • What assumptions can you make about the environment in which you are installing?
  • Can the app interact with other apps?
  • What configurations should be available to the user and how should they be offered?


But these questions are related to the specifics of Helm. To understand why, let's start with a picture of what happens when the user launches helm install



. We can then move on to looking at how some of the official Kubernetes charts address these issues.







Launch picturehelm install





I want to install MySQL on my cluster. But I don't need the version of MySQL that it stable/MySQL



installs in the values.yaml file in the official chart repository . So, I create my own file values.yaml



named mysql-values.yaml



with just one line:







imageTag: “5.7.10”
      
      





Then I run helm install stable/mysql --values=mysqlvalues.yaml



.







Helm (ignorant-camel



), MySQL . kubectl describe pod ignorant-camel-mysql-5dc6b947b-lf6p8



, imageTag



.







, , imageTag . helm install stabe/mysql --values=mysqlvalues.yaml --dry-run --debug



, Helm Kubernetes, .







Kubernetes , Helm Chart:







├── Chart.yaml
├── README.md
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── secrets.yaml
│   └── ...more yaml...
└── values.yaml
      
      





helm install stable/mysql



, values.yaml



Helm (, ) yaml , Kubernetes. helm install stable/mysql



, . , .







, values.yaml



— , , . , values.yaml



, , .







values.yaml



. , , . requirements.yaml



, , . , values.yaml



. , c Helm.







, ,



. , , — Helm Charts.







Helm



, Kubernetes . Helm Chart , , :

• , values.yaml



? , , , ?

• , , , ?

• , , (, )?

• , ?







, Helm Charts. , , , .







, , . Helm, . Helm , . .







, . , , , Helm 3 Lua. .







1.



, env, values.yaml



:







- name: ENV_VAR1
  value: {{ .Values.var1 }}
- name: ENV_VAR2
  value: {{ .Values.var2 }}
      
      





values.yaml



--set var1=foo



. , ? , , (, ENV_VAR1



var1



)? , . , , ?







Helm Charts, configmap



. / . configmap, unbound.conf. , . configmap



, :







{{- range .Values.localRecords }}
local-data: "{{ .name }} A {{ .ip }}"
local-data-ptr: "{{ .ip }} {{ .name }}"
{{- end }}
      
      





values.yaml localRecords



, :







localRecords:
- name: "fake3.host.net"
  ip: "10.12.10.10"
- name: "fake4.host.net"
  ip: "10.13.10.10"
      
      





Sonarqube chart , extraEnv



:







{{- range $key, $value := .Values.extraEnv }}
 — name: {{ $key }}
   value: {{ $value }}
{{- end }}
      
      





values.yaml



, :







extraEnv:
- ENV_VAR1: var1
- ENV_VAR2: var2
      
      





extraEnv



, . Buildkite , . values.yaml



:







{{- if .Values.extraEnv }}
{{ toYaml .Values.extraEnv | indent 12 }}
{{- end }}
      
      





, , , extraEnv



values.yaml



, (



) (



) , :







extraEnv:
 — name: ENV_VAR1
   value: "var1"
 — name: ENV_VAR2
   value: "var2"
      
      





Keycloak :







{{- with .Values.keycloak.extraEnv }}
{{ tpl . $ | indent 12 }}
{{- end }}
      
      





, extraEnv



, tpl



, , . , , :







extraEnv: |
 — name: KEYCLOAK_LOGLEVEL
   value: DEBUG
 — name: HOSTNAME
   value: {{ .Release.Name }}-keycloak
      
      





{{ .Release.Name }}



values.yaml



, , tpl



. , , , ( ). , values.yaml



, .







2.



, Helm, , ( ) . , , .







, , — . , Xray Postgres. , Postgres ( , , ):







{{- if .Values.postgresql.enabled }}
 — name: POSTGRES_USER
   value: {{ .Values.postgresql.postgresUser }}
 — name: POSTGRESS_PASSWORD
   valueFrom:
     secretKeyRef:
       name: {{ .Release.Name }}-postgresql
       key: postgres-password
 — name: POSTGRESS_DB
   value: {{ .Values.postgresql.postgresDatabase }}
 {{- else }}
...
      
      





Xray



, , Postgres. , , ? . ?







extraEnv



, Keycloak. extraEnv



, Postgres, . values.yaml



:







extraEnv: |
 — name: POSTGRES_USER
   value: {{ .Values.postgresql.postgresUser }}
 — name: POSTGRESS_PASSWORD
   valueFrom:
     secretKeyRef:
       name: {{ .Release.Name }}-postgresql
       key: postgres-password
 — name: POSTGRESS_DB
   value: {{ .Values.postgresql.postgresDatabase }}
      
      





|



, , tpl



.







, , configmap. — .Files.Get



. , values.yaml, , . , .Files.Get tpl. configmap , :







conf_file1: {{ tpl (.Files.Get "files/conf_file1") . | quote }}
      
      





Secret base64:







conf_file1: {{ tpl (.Files.Get "files/conf_file1") . | b64enc | quote }}
      
      





ConfigMap



, .Files.Glob



:







{{ (tpl (.Files.Glob "files/*").AsConfig . ) | indent 2 }}
      
      





AsSecret



, tpl



. , Glob Get :







{{ range $path, $bytes := .Files.Glob "files/*" }}
{{ base $path }}: '{{ tpl ($root.Files.Get $path) . | b64enc }}'
{{ end }}
      
      





3. -



extraEnv



Keycloak



, , , . , Keycloak Keycloak



, JSON



, Keycloak



. , extraVolumes



:







{{- with .Values.keycloak.extraVolumes }}
{{ tpl . $ | indent 8 }}
{{- end }}
      
      





extraVolumeMounts



:







          volumeMounts:
            - name: scripts
              mountPath: /scripts
{{- with .Values.keycloak.extraVolumeMounts }}
{{ tpl . $ | indent 12 }}
{{- end }}
      
      





( JSON) values.yaml:







extraVolumes: |
 — name: custom-secret
   secret:
     secretName: custom-secret
extraVolumeMounts: |
 - name: custom-secret
   mountPath: "/realm/"
   readOnly: true
      
      





(volumes) volumeMounts



values.yaml



. , , initContainers



( sidecars



). , , .







Keycloak , preStartScript, :







{{- with .Values.keycloak.preStartScript }}                           
echo 'Running custom pre-start script...'                       
{{ . | indent 4 }}                         
{{- end }}
      
      





, , .Values.keycloak.preStartScript



values.yaml



. , , .







4.



Helm, helm create



, (Service), Ingress. Ingress. , . , RabbitMQ, , Ingress :







{{- if .Values.ingress.enabled }}
...
{{-end}
      
      





, .







, RabbitMQ , (host-based):







rules:
  {{- if .Values.ingress.hostName }}
  - host: {{ .Values.ingress.hostName }}
    http:
  {{- else }}
  - http:
  {{- end }}
      
      





( , , , . RabbitMQ .)







RabbitMQ ( else ). , (, RabbitMQ , ):







- path: {{ default "/" .path }}
  backend:
    serviceName: {{ template "rabbitmq.fullname" . }}
    servicePort: {{ .Values.rabbitmq.managerPort }}
      
      





, , .







toYaml:







{{- with .Values.ingress.annotations }}
 annotations:
{{ toYaml . | indent 4 }}
{{- end }}
      
      





values.yaml



, :







annotations:
  kubernetes.io/ingress.class: nginx
  nginx.ingress.kubernetes.io/rewrite-target: /
      
      





, .yaml , , . , , , . , NGINX :







annotations:
  kubernetes.io/ingress.class: nginx
  nginx.ingress.kubernetes.io/rewrite-target: /
  nginx.ingress.kubernetes.io/configuration-snippet: |
     more_set_headers 'Access-Control-Allow-Origin: $http_origin';    
      
      





Art of the Helm Chart



Helm Chart , . , , . . , , , .







There are other issues that we have not covered, such as testing and security. It was just a look at a specific piece of the official charts. I've tried to focus on patterns that I find particularly useful for getting users to do what they want with your charts. The official Kubernetes charts have been extremely helpful for me while working on the Helm charts for the Activity project . Hopefully the explanation in this post will help encourage others to dive into the official repo and take inspiration from its charts.








All Articles