In my previous article, I showed you how to create your own HELM Chart : "Helm — Create Helm Chart". Let's talk about Helm built-in functions and Values today.
Define Helm Chart
Let's quickly recap how to create a Helm Chart. A chart package is a collection of folders, and the folder name is the name of the chart package. For example, to create a mychart chart package:
$ helm create mychart
Creating mychart
$ tree mychart/
mychart/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── ingress.yaml
│ ├── NOTES.txt
│ └── service.yaml
└── values.yaml
2 directories, 7 filesLet's take a closer look at templates directory:
- NOTES.txt: "Help Text" for the chart. This is displayed to the user when they run helm install.
- deployment.yaml: basic manifest for creating Kubernetes deployments
- service.yaml: basic manifest for creating service for deployment
- ingress.yaml: resource manifest file for creating ingress objects
- _helpers.tpl: place to put template helpers, which can be reused throughout the chart
Here we understand what each file is for, and then we can delete all the files under the templates directory, and then create the template files ourselves:
$ rm -rf mychart/templates/*.*Create a Template
Here we create a very simple template ConfigMap:configmap.yamlfile under the templates directory:
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"In fact, now we have an installable chart package, which can be installed with the helm installcommand:
$ helm install mychart ./mychart
NAME: mychart
LAST DEPLOYED: Thu Jun 23 11:38:18 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: NoneIn the above output, we can see that our ConfigMap resource object has been created. Then we can see the actual template rendered resource file using the following command:
$ helm get manifest mychart
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"Now we see if the above ConfigMap file is exactly what we designed in the template file, let's delete the current one release:
$ helm delete mychart
release "mychart" deletedAdd a Simple Template
We can see that the name of the ConfigMap we defined above is fixed, but this is often not a good practice. We can generate the name of the resource by inserting the name of the release. For example, the name of the ConfigMap here is: mychart-configmap, which requires the use of Chart's template definition method.
Now let's redefine the above configmap.yaml file:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"We replaced the name with the template directive {{ .Release.Name }}-configmap , and injected the name of release into the template, so that the final generated ConfigMap name starts with the name of release. The Release template object here is one of the built-in objects in Helm, and there are many other built-in objects, which we will touch on later.
Now let's reinstall our Chart package, paying attention to the name of the ConfigMap resource object:
$ helm install mychart2 ./mychart
NAME: mychart2
LAST DEPLOYED: Thu Jun 23 11:40:19 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: Noneand let's check the manifest again:
helm get manifest mychart2
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart2-configmap
data:
myvalue: "Hello World"Now you can see the metadata.name is changed to mychart2-configmap .
Debugging
We use templates to generate the list of resource files, but it is very inconvenient if we want to debug. It is impossible for us to deploy an instance every time to verify whether the template is correct.
Fortunately, Helm provides us with --dry-run --debug option, when you execute helm install these two parameters, you can print the corresponding values and the final resource list file generated without actually deploying a release. For example, let's debug the chart package created above:
$ helm install mychart2 --dry-run --debug ./mychart
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /tmp/mychart
NAME: mychart2
LAST DEPLOYED: Thu Jun 23 11:44:56 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
affinity: {}
autoscaling:
enabled: false
maxReplicas: 100
minReplicas: 1
targetCPUUtilizationPercentage: 80
fullnameOverride: ""
image:
pullPolicy: IfNotPresent
repository: nginx
tag: ""
imagePullSecrets: []
ingress:
annotations: {}
enabled: false
hosts:
- host: chart-example.local
paths: []
tls: []
nameOverride: ""
nodeSelector: {}
podAnnotations: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
port: 80
type: ClusterIP
serviceAccount:
annotations: {}
create: true
name: ""
tolerations: []
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart2-configmap
data:
myvalue: "Hello World"Now we can easily test the code by using it without having to install a release instance every time, but it should be noted that this does not ensure that K8s itself will definitely accept the generated template. After debugging, you still need to go to the Install an actual release instance for verification.
Built-in objects
Just now we inserted the name of the release into the template using {{.Release.Name}}. The Release here is the built-in object of Helm. The following are some commonly used built-in objects, which can be used directly when needed:
Release
- Release : This object describes the release itself. It has several objects in it:
- Release.Name: release name
- Release.Time: time of release
- Release.Namespace: namespace of release (if not covered by manifest)
- Release.Service: The name of the release service (always Tiller).
- Release.Revision: The revision number of this release, accumulated from 1.
- Release.IsUpgrade: Set to true if the current action is an upgrade or rollback.
- Release.IsInstall: Set to true if the current action is an install.
Values
- Values : Values
values.yamlpassed into the template from files and user-provided files. By default, Values is empty.
Chart
- Chart:
Chart.yamlThe content of the file. All Chart objects will be obtained from this file. Available fields are listed in the Charts Guide in the chart guide , which can be viewed here.
Files
- Files: This provides access to all non-special files in the chart. While it cannot be used to access templates, it can be used to access other files in the chart. See the "Accessing Files" section.
- Files.Get is a function to get files by name (.Files.Get config.ini)
- Files.GetBytes is the function that gets the file contents as a byte array instead of a string. This is useful for things like pictures.
Capabilities
- Capabilities: This provides information about the capabilities supported by the K8s cluster.
- Capabilities.APIVersions is a set of version information.
- Capabilities.APIVersions.Has $version Indicates whether versions (batch/v1) are enabled on the cluster.
- Capabilities.KubeVersion provides methods to find the Kubernetes version. It has the following values: Major, Minor, GitVersion, GitCommit, GitTreeState, BuildDate, GoVersion, Compiler, and Platform.
- Capabilities.TillerVersion provides methods to find the Tiller version. It has the following values: SemVer, GitCommit, and GitTreeState.
Template
- Template: Contains information about the current template being executed
Name
- Name: file path to the current template (eg mychart/templates/mytemplate.yaml)
BasePath
- BasePath: The path to the current chart template directory (eg mychart/templates).
The above values can be used in any top-level template, note that built-in values always start with an uppercase letter. This also conforms Goto the naming convention. When you create your own name, you are free to use the convention that works for your team.
Values file
One of the built-in objects above is Values, which provides access to the value of the incoming chart. The value of the Values object has 4 sources:
- The values.yaml file in the chart package
- The values.yaml file of the parent chart package
- Custom yaml files passed in through
helm installorhelm upgrade -for parameters (we have already learned in the previous lesson)--values - value passed
--setin parameter
For example, here we re-edit the mychart/values.yaml file, clear all the default values, and add a new data: (values.yaml)
course: k8sThen we can use this value in the templates/configmap.yaml template file above:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
course: {{ .Values.course }}Then do a dry run:
$ helm install mychart --dry-run --debug ./mychart
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /tmp/mychart
NAME: mychart
LAST DEPLOYED: Thu Jun 23 11:52:05 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
course: k8s
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart2-configmap
data:
myvalue: "Hello World"
course: k8sWe can see that the value of course in the ConfigMap is rendered as k8s, because in the default values.yaml file, the value of this parameter is k8s. Similarly, we can easily override the value of course through parameters --set :
helm install mychart2 --dry-run --debug ./mychart --set course=python3
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /tmp/mychart
NAME: mychart2
LAST DEPLOYED: Thu Jun 23 11:53:33 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
course: python3
COMPUTED VALUES:
course: python3
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart2-configmap
data:
myvalue: "Hello World"
course: python3Because --set has higher priority than the default values.yaml file, our template is generated as course: python3.
The values file can also contain more structured content, for example, in the values.yaml file we can create a course section and add a few keys to it:
course:
k8s: devops
python: djangoNow we modify the template slightly:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
k8s: {{ .Values.course.k8s }}
python: {{ .Values.course.python }}