helm chart详解及常用命令:helm template / package / plugin

Posted a772304419

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了helm chart详解及常用命令:helm template / package / plugin相关的知识,希望对你有一定的参考价值。


​Helm​​​ 是 kubernetes 的官方包管理工具。根据官网上的描述 ​​Helm is the best way to find, share, and use software built for Kubernetes.​​ 可以看出 helm 在 kubernetes 社区中的定位。

这篇文章并不是 helm 的入门文章,而是着重于如何在本地开发 chart。希望进行 helm 入门的同学可以参考官方文档。

概述

本文会分为两个部分来探讨如何在本地开发 chart,分别是:

  • Chart 的规范
  • Helm 提供的本地开发功能

Chart 的规范

根据定义,一个 Chart 是一些有相关性的 Kubernetes 资源的集合。一个 chart 可以是一个简单的应用,比如 memcached,或者是一个复杂的集合,比如一个 full-stack 的 web 的应用,含有 server,ui,database,cache 等等。

Chart 从本质上只不过是一些文件,不过这些文件需要满足一定的规范,比如目录的规范和文件名的规范。

Chart 的目录结构

根据规定,符合如下目录结构的目录就是一个 Chart,目录名即为 Chart 名(不包含版本信息):

wordpress/
Chart.yaml # A YAML file containing information about the chart
LICENSE # OPTIONAL: A plain text file containing the license for the chart
README.md # OPTIONAL: A human-readable README file
requirements.yaml # OPTIONAL: A YAML file listing dependencies for the chart
values.yaml # The default configuration values for this chart
charts/ # OPTIONAL: A directory containing any charts upon which this chart depends.
templates/ # OPTIONAL: A directory of templates that, when combined with values,
# will generate valid Kubernetes manifest files.
templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes

虽然这里看到 charts 和 templates 文件夹都是 optional 的,但是至少需要有一个存在,chart 才是合法的。

Chart.yaml 文件

每个 Chart 都必须有一个 ​​Chart.yaml​​ 文件,这个文件的内容如下:

name: The name of the chart (required)
version: A SemVer 2 version (required)
description: A single-sentence description of this project (optional)
keywords:
- A list of keywords about this project (optional)
home: The URL of this projects home page (optional)
sources:
- A list of URLs to source code for this project (optional)
maintainers: # (optional)
- name: The maintainers name (required for each maintainer)
email: The maintainers email (optional for each maintainer)
url: A URL for the maintainer (optional for each maintainer)
engine: gotpl # The name of the template engine (optional, defaults to gotpl)
icon: A URL to an SVG or PNG image to be used as an icon (optional).
appVersion: The version of the app that this contains (optional). This neednt be SemVer.
deprecated: Whether or not this chart is deprecated (optional, boolean)
tillerVersion: The version of Tiller that this chart requires. This should be expressed as a SemVer range: ">2.0.0" (optional)

Chart 的版本

每个 Chart 都必须有一个版本号,版本号必须遵守​​语义化版本规范 V2​​。每个 package(Chart 打包后的东西)同时由 name 和 version 来唯一确定。

比如,一个叫做 ​nginx​​ 的版本为 ​​1.2.3​​​ 的 Chart,打包后就是 ​​nginx-1.2.3.tgz​​。

更复杂的语义化版本号是被支持的,比如 ​​version: 1.2.3-alpha.1+ef365​​ 但是非语义化的版本是不被允许的。

Helm 和 Tiller 都会使用 Chart 的名称 + 版本来唯一标识一个 package,所以 Chart.yaml 里面的版本一定要对应 package 的文件名。

appVersion

appVersion 其实并没啥用,只是指定了 Chart 包含的应用的版本,对 helm 和 tiller 来说并不会有啥影响,也不需要和 Chart 的 version 一致。自己随便写都可以……

Deprecating Chart

可以通过在 ​​Chart.yaml​​​ 里面把 ​​deprecated​​​ 设为 ​​true​​ 来标识一个 Chart 已经是 deprecated 状态。

License,ReadME 和 Notes

一个 Chart 还可以有 License 来标识 License 信息,README.md 来包含一些介绍信息,以及一个 templates/NOTES.txt 文件来指导如何去安装或者使用。

templates/NOTES.txt 文件会被当做普通的 template 来对待(意味着其中可以有变量),并且会在每次 ​​helm status​​​ 之后和 ​​helm install​​ 之后被打印到 STDOUT。

比如 ​​stable/mysql​ 的 NOTES.txt 如下:

MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
template "mysql.fullname" . . .Release.Namespace .svc.cluster.local

To get your root password run:

MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace .Release.Namespace template "mysql.fullname" . -o jsonpath=".data.mysql-root-password" | base64 --decode; echo)

To connect to your database:

1. Run an Ubuntu pod that you can use as a client:

kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il

2. Install the mysql client:

$ apt-get update && apt-get install mysql-client -y

3. Connect using the mysql cli, then provide your password:
$ mysql -h template "mysql.fullname" . -p

To connect to your database directly from outside the K8s cluster:
- if contains "NodePort" .Values.service.type
MYSQL_HOST=$(kubectl get nodes --namespace .Release.Namespace -o jsonpath=.items[0].status.addresses[0].address)
MYSQL_PORT=$(kubectl get svc --namespace .Release.Namespace template "mysql.fullname" . -o jsonpath=.spec.ports[0].nodePort)

- else if contains "ClusterIP" .Values.service.type
MYSQL_HOST=127.0.0.1
MYSQL_PORT= default "3306" .Values.service.port

# Execute the following commands to route the connection:
export POD_NAME=$(kubectl get pods --namespace .Release.Namespace -l "app= template "mysql.fullname" . " -o jsonpath=".items[0].metadata.name")
kubectl port-forward $POD_NAME default "3306" .Values.service.port : default "3306" .Values.service.port

- end

mysql -h $MYSQL_HOST -P$MYSQL_PORT -u root -p$MYSQL_ROOT_PASSWORD

可以看出来,NOTES.txt 是用来给用户作使用上的指导的。

Chart 的依赖

我们都知道,软件开发过程中,复用是一个很重要的概念,同样的,Chart 也可以依赖于其它的 Chart,可以复用其它的 Chart 的内容。

使用 requirements.yaml

Helm 提供了两种对 Chart 复用的方法,第一种是在 ​​requirements.yaml​​ 中指定依赖的 Chart,如下:

dependencies:
- name: apache
version: 1.2.3
repository: http://example.com/charts
- name: mysql
version: 3.2.1
repository: http://another.example.com/charts

如果说需要对一个 chart 复用多次,可以这么干:

# parentchart/requirements.yaml
dependencies:
- name: subchart
repository: http://localhost:10191
version: 0.1.0
alias: new-subchart-1
- name: subchart
repository: http://localhost:10191
version: 0.1.0
alias: new-subchart-2
- name: subchart
repository: http://localhost:10191
version: 0.1.0

除此之外,Helm 还可以选择性的去使用依赖的 chart,具体可以参考 ​​tags and condition​​。

直接使用 charts 来手动管理

第二种是直接把需要用的 Chart 放到 ​​charts​​ 文件夹下。一般情况下推荐使用第一种,第二种是在需要对依赖的 chart 做魔改的情况下用到的。

Helm 还提供了 ​​helm dep​​ 这个命令来方便对依赖的管理,之后会介绍到。

依赖的一些实现细节

在 ​​helm install​​​ 和 ​​helm upgrade​​ 的时候,helm 会把依赖和当前 chart 打包成一个集合一起送给 tiller,然后(目前是)按照类型 + 字母顺序来 apply,并不是先去 install 依赖再去 install 当前的 chart。

例如,我们有一个 chart,会有以下三个东西:

  • namespace “A-Namespace”
  • statefulset “A-StatefulSet”
  • service “A-Service”

这个 chart 依赖于另一个 chart,有如下三个东西:

  • namespace “B-Namespace”
  • replicaset “B-ReplicaSet”
  • service “B-Service”

那么在安装或者升级的过程中,顺序如下:

  • A-Namespace
  • B-Namespace
  • A-StatefulSet
  • B-ReplicaSet
  • A-Service
  • B-Service

Helm 客户端提供的和本地开发相关的功能

Helm 的客户端提供了一些和本地开发相关的命令,这里简单介绍一下。

helm completion

顾名思义,提供了命令补全,使用方式也比较简单:

$ source <(helm completion zsh)

helm create

可以通过这个命令直接创建出一个符合 Chart 规范的目录出来,比如:

$ helm create myweb
$ tree myweb
myweb
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── ingress.yaml
│ └── service.yaml
└── values.yaml

2 directories, 7 files

helm dependency

顾名思义,是用来进行依赖管理的,可以被简写为 ​​helm dep​​,具体使用如下:

$ helm dep
Manage the dependencies of a chart.

Helm charts store their dependencies in charts/. For chart developers, it is
often easier to manage a single dependency file (requirements.yaml)
which declares all dependencies.

The dependency commands operate on that file, making it easy to synchronize
between the desired dependencies and the actual dependencies stored in the
charts/ directory.

A requirements.yaml file is a YAML file in which developers can declare chart
dependencies, along with the location of the chart and the desired version.
For example, this requirements file declares two dependencies:

# requirements.yaml
dependencies:
- name: nginx
version: "1.2.3"
repository: "https://example.com/charts"
- name: memcached
version: "3.2.1"
repository: "https://another.example.com/charts"

The name should be the name of a chart, where that name must match the name
in that charts Chart.yaml file.

The version field should contain a semantic version or version range.

The repository URL should point to a Chart Repository. Helm expects that by
appending /index.yaml to the URL, it should be able to retrieve the chart
repositorys index. Note: repository can be an alias. The alias must start
with alias: or @.

Starting from 2.2.0, repository can be defined as the path to the directory of
the dependency charts stored locally. The path should start with a prefix of
"file://". For example,

# requirements.yaml
dependencies:
- name: nginx
version: "1.2.3"
repository: "file://../dependency_chart/nginx"

If the dependency chart is retrieved locally, it is not required to have the
repository added to helm by "helm add repo". Version matching is also supported
for this case.

Usage:
helm dependency [command]

Aliases:
dependency, dep, dependencies


Available Commands:
build rebuild the charts/ directory based on the requirements.lock file
list list the dependencies for the given chart
update update charts/ based on the contents of requirements.yaml

Flags:
-h, --help help for dependency

Use "helm dependency [command] --help" for more information about a command.

helm fetch

一看这就是个下载别的 chart 的命令,为啥我要说和本地开发有关系呢?

因为我认为,helm 的官方 repo 里面的 chart 最大的作用就是作为一个 best practice 来展示给使用者一个示例。

所以,当不知道该怎么写的时候,去抄吧

以上是关于helm chart详解及常用命令:helm template / package / plugin的主要内容,如果未能解决你的问题,请参考以下文章

Helm 常用命令

[转帖]helm模板文件chart编写语法详解

helm模板文件chart编写语法详解

Helm常用用法和遇到的一些问题

详解如何自定义开发构建一个Helm Chart包

helm详解