Creating your own charts

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

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 version

It 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 page
  • sources: A list of URLs to source code for this project
  • Maintainers:
    • name: 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 icon
  • appVersion: The version of the app that this contains
  • deprecated: is this chart is deprecated? (boolean)

Versioning charts

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

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.

Deprecating charts

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

  • Release the new chart version in the chart repository
  • Remove the chart from the source repository (for example, Git)

Chart metadata files

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:

  • A description of the application or service the chart provides
  • Any prerequisites or requirements to run the chart
  • Descriptions of options in values.yaml and default values
  • Any other information that may be relevant to the installation or configuration of the chart

The 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.

Managing chart dependencies

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.

Managing dependencies with requirements.yaml

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.

Utilizing special fields in requirements.yaml

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:

  • Conditions (when set in values) always override tags. The first condition path that exists wins and subsequent ones for that chart are ignored.
  • Tags are evaluated as if any of the chart's tags are true then enable the chart.
  • Tags and condition values must be set in the top parent's values.
  • The tags: key-in values must be a top-level key. Globals and nested tags tables are not currently supported

Using templates and values

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.

Writing template 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" . }}

Using pipelines and functions

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"

Embedding predefined values

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.

Feeding values from a file

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

Scope, dependencies, and values

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
  ...
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset