A chart is a collection of files that describe a related set of Kubernetes resources. A single chart might be used to deploy something simple, such as a memcached
pod, or something complex, such as a full web app stack with HTTP servers, databases, caches, and so on.
Charts are created as files laid out in a particular directory tree. Then they can be packaged into versioned archives to be deployed. The key file is Chart.yaml
.
The Chart.yaml
file is required for a chart. It requires a name and version fields:
Name
: The name of the chart (same as the directory name)Version
: A SemVer 2
versionIt may also contain various optional fields:
description
: A single sentence description of this project keywords:A list of keywords about this project:
home
: The URL of this project's home pagesources
: A list of URLs to source code for this projectname
: The maintainer's name (required for each maintainer)email
: The maintainer's e-mail (optional for each maintainer)engine
: The name of the template engine (defaults to gotpl
)icon
: A URL to an SVG or PNG image to be used as an iconappVersion
: The version of the app that this containsdeprecated
: is this chart is deprecated? (boolean)The version
field inside of the Chart.yaml
is used by many of the Helm tools, including the CLI and the Tiller server. When generating a package, the helm package
command will use the version that it finds in the Chart.yaml
as a token in the package name. The system assumes that the version number in the chart package name matches the version number in the Chart.yaml
. Failure to meet this assumption will cause an error.
The appVersion
field is not related to the version field. It is not used by Helm and serves as metadata or documentation for users that want to understand what they are deploying. Correctness is not enforced by Helm.
When managing charts in a chart
repository
, it is sometimes necessary to deprecate a chart. The optional deprecated field in Chart.yaml
can be used to mark a chart as deprecated. If the latest version of a chart in the repository is marked as deprecated, then the chart as a whole is considered deprecated. The chart name can later be reused by publishing a newer version that is not marked as deprecated. The workflow for deprecating charts, as followed by the kubernetes/
charts project, is as follows:
Update the chart's Chart.yaml
to mark the chart as deprecated, bumping the version
chart
repository
source
repository
(for example, Git)Charts contain various metadata files that describe the installation, configuration, usage, and license of a chart. A README
for a chart should be formatted in markdown (README.md
), and should generally contain the following:
values.yaml
and default valuesThe chart can also contain a short plain text templates/NOTES.txt
file that will be printed out after installation, and when viewing the status of a release. This file is evaluated as a template, and can be used to display usage notes, next steps, or any other information relevant to a release of the chart. For example, instructions could be provided for connecting to a database, or accessing a web UI. Since this file is printed to STDOUT
when running helm install
or helm status
, it is recommended to keep the content brief and point to the README
for greater detail.
In Helm, a chart may depend on any number of other charts. These dependencies are expressed explicitly by copying the dependency charts into the charts/
sub-directory during installation.
A dependency can be either a chart archive (foo-1.2.3.tgz
) or an unpacked chart directory. But its name cannot start with _
or .
. Such files are ignored by the chart loader.
Instead of manually placing charts in the charts/
sub-directory, it is better to declare dependencies using a requirements.yaml
file inside of your chart.
A requirements.yaml
file is a simple file for listing the chart dependencies:
dependencies: - name: foo version: 1.2.3 repository: http://example.com/charts - name: bar version: 3.2.1 repository: http://another.example.com/charts
The name
field is the name of the chart you want.
The version
field is the version of the chart you want.
The repository
field is the full URL to the chart
repository
. Note that you must also use helm repo
add to add that repository
locally.
Once you have a dependencies file, you can run the Helm dependency update and it will use your dependency file to download all of the specified charts into the charts sub-directory for you:
$ helm dep up foo-chart Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "local" chart repository ...Successfully got an update from the "stable" chart repository ...Successfully got an update from the "example" chart repository ...Successfully got an update from the "another" chart repository Update Complete. Happy Helming! Saving 2 charts
Downloading Foo from repo http://example.com/charts
Downloading Bar from repo http://another.example.com/charts
When the Helm dependency update retrieves charts, it will store them as chart archives in the charts/
directory. So for the preceding example, one would expect to see the following files in the charts
directory:
charts/ foo-1.2.3.tgz bar-3.2.1.tgz
Managing charts with requirements.yaml
is a good way to easily keep charts updated, and also share requirements information throughout a team.
In addition to the other fields, each requirements entry may contain the optional fields tags and condition.
All charts are loaded by default. If tags or condition fields are present, they will be evaluated and used to control loading for the charts they are applied to:
Condition - The condition
field holds one or more YAML paths (delimited by commas). If this path exists in the top parent's values and resolves to a boolean value, the chart will be enabled or disabled based on that boolean value. Only the first valid path found in the list is evaluated, and if no paths exist then the condition has no effect.
Tags - The tags
field is a YAML list of labels to associate with this chart. In the top parent's values, all charts with tags can be enabled or disabled by specifying the tag and a boolean value.
Here is an example requirements.yaml
and values.yaml
that make good use of conditions and tags to enable and disable the installation of dependencies. The requirements.yaml
file defines two conditions for installing its dependencies based on the value of the global enabled
field and the specific sub-charts enabled
field:
# parentchart/requirements.yaml
dependencies:
- name: subchart1 repository: http://localhost:10191 version: 0.1.0 condition: subchart1.enabled, global.subchart1.enabled tags: - front-end - subchart1 - name: subchart2 repository: http://localhost:10191 version: 0.1.0 condition: subchart2.enabled,global.subchart2.enabled tags: - back-end - subchart2
The values.yaml
file assigns values to some of the condition variables. The subchart2
tag doesn't get a value, so it is considered enabled:
# parentchart/values.yaml subchart1: enabled: true tags: front-end: false back-end: true
You can set tag and conditions values from the command line too when installing a chart, and they'll take precedence over the values.yaml
file:
helm install --set subchart2.enabled=false
The resolution of tags and conditions is as follows:
true
then enable the chart.Any non-trivial application will require configuration and adaptation to the specific use case. Helm charts are templates that use the Go template language to populate placeholders. Helm supports additional functions from the Sprig
library and a few other specialized functions. The template files are stored in the templates/
sub-directory of the chart. Helm will use the template engine to render all files in this directory and apply the provided value files.
Template files are just text files that follow the Go template language rules. They can generate Kubernetes configuration files. Here is the service template file from the Gitlab CE chart:
apiVersion: v1 kind: Service metadata: name: {{ template "fullname" . }} labels: app: {{ template "fullname" . }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" spec: type: {{ .Values.serviceType }} ports: - name: ssh port: {{ .Values.sshPort | int }} targetPort: ssh - name: http port: {{ .Values.httpPort | int }} targetPort: http - name: https port: {{ .Values.httpsPort | int }} targetPort: https selector: app: {{ template "fullname" . }}
Helm allows rich and sophisticated syntax in the template files via the built-in Go template functions, sprig functions, and pipelines. Here is an example template that takes advantage of these capabilities. It uses the repeat, quote, and upper functions for the food and drink keys, and it uses pipelines to chain multiple functions together:
apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap data: greeting: "Hello World" drink: {{ .Values.favorite.drink | repeat 3 | quote }} food: {{ .Values.favorite.food | upper | quote }}
See if the values file has the following section:
favorite: drink: coffee food pizza
If it does, then the resulting chart would be as follows:
apiVersion: v1 kind: ConfigMap metadata: name: cool-app-configmap data: greeting: "Hello World" drink: "coffeecoffeecoffee" food: "PIZZA"
Helm provides some predefined values you can use in your templates. In the Gitlab chart above the Release.Name
, Release.Service
, Chart.Name
, and Chart.Version
are examples of Helm predefined values. Other predefined values are as follows:
Release.Time
Release.Namespace
Release.IsUpgrade
Release.IsInstall
Release.Revision
Chart
Files
Capabilities
The Chart is the content of Chart.yaml
. The files and capabilities predefined values are map-like
objects that allow access via various functions. Note that unknown fields in Chart.yaml
are ignored by the template engine and cannot be used to pass
arbitrary structured data to templates.
Here is part of the Gitlab
CE
default values file. The values from this file are used to populate multiple templates. For example, the serviceType
, sshPort
, httpPort
, and httpsPort
values are used in the preceding service template:
image: gitlab/gitlab-ce:9.0.0-ce.0 serviceType: LoadBalancer sshPort: 22 httpPort: 80 httpsPort: 443 resources: requests: memory: 1Gi cpu: 500m limits: memory: 2Gi cpu: 1
You can provide your own YAML values
files to override the defaults during the install
command:
$ helm install --values=custom-values.yaml gitlab-ce
Value files can declare values for the top-level chart, as well as for any of the charts that are included in that chart's charts/
directory. For example, the gitlab-ce values.yaml
file contains some default values for its dependency charts, postgresql
and redis
:
postgresql: imageTag: "9.6" cpu: 1000m memory: 1Gi postgresUser: gitlab postgresPassword: gitlab postgresDatabase: git lab persistence: size: 10Gi redis: redisPassword: "gitlab" resources: requests: memory: 1Gi persistence: size: 10Gi
The top-level chart has access to values of its dependent charts, but not vice versa. There is also a global value that is accessible to all charts. For example, you could add something like this:
global: app: cool-app
When a global is present, it will be replicated to each dependent chart's values as follows:
global: app: cool-app postgresql: global: app: cool-app ... redis: global: app: cool-app ...