官方文档:https://v3.helm.sh/zh/docs/
实在之前也写过关于helm的一篇文章【Kubernetes(k8s)包管理器Helm(Helm3)先容&Helm3安装Harbor】,可能讲的不足细致,这里会更加细致的讲解helm。
二、Helm 架构三、Helm 安装
下载地址:https://github.com/helm/helm/releases
# 下载包$ wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz# 解压压缩包$ tar -xf helm-v3.9.4-linux-amd64.tar.gz# 制作软连接$ ln -s /opt/helm/linux-amd64/helm /usr/local/bin/helm# 验证$ helm version$ helm help
四、Helm 组件及干系术语Helm——Helm 是一个命令行下的客户端工具。紧张用于 Kubernetes 运用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。Chart——Chart 代表着 Helm 包。它包含在 Kubernetes 集群内部运行运用程序,工具或做事所需的所有资源定义。你可以把它看作是 Homebrew formula,Apt dpkg,或 Yum RPM 在Kubernetes 中的等价物。Release——Release 是运行在 Kubernetes 集群中的 chart 的实例。一个 chart 常日可以在同一个集群中安装多次。每一次安装都会创建一个新的 release。Repoistory——Repository(仓库) 是用来存放和共享 charts 的地方。它就像 Perl 的 CPAN 档案库网络 或是 Fedora 的 软件包仓库,只不过它是供 Kubernetes 包所利用的。五、Helm Chart 详解1)Chart 目录构造
# 通过helm create命令创建一个新的chart包helm create nginxtree nginx
nginx/├── charts #依赖其他包的charts文件├── Chart.yaml # 该chart的描述文件,包括ico地址,版本信息等├── templates # #存放k8s模板文件目录│ ├── deployment.yaml # 创建k8s资源的yaml 模板│ ├── _helpers.tpl # 下划线开头的文件,可以被其他模板引用│ ├── hpa.yaml # 弹性扩缩容,配置做事资源CPU 内存│ ├── ingress.yaml # ingress 合营service域名访问的配置│ ├── NOTES.txt # 解释文件,helm install之后展示给用户看的内容│ ├── serviceaccount.yaml # 做事账号配置│ ├── service.yaml # kubernetes Serivce yaml 模板│ └── tests # 测试模块│ └── test-connection.yaml └── values.yaml # 给模板文件利用的变量
可能有写包还会有以下几个目录:
wordpress/... LICENSE # 可选: 包含chart容许证的纯文本文件 README.md # 可选: 可读的README文件 values.schema.json # 可选: 一个利用JSON构造的values.yaml文件 charts/ # 包含chart依赖的其他chart crds/ # 自定义资源的定义...
2)Chart.yaml 文件
apiVersion: chart API 版本 (必需)name: chart名称 (必需)version: chart 版本,语义化2 版本(必需)kubeVersion: 兼容Kubernetes版本的语义化版本(可选)description: 一句话对这个项目的描述(可选)type: chart类型 (可选)keywords: - 关于项目的一组关键字(可选)home: 项目home页面的URL (可选)sources: - 项目源码的URL列表(可选)dependencies: # chart 必要条件列表 (可选) - name: chart名称 (nginx) version: chart版本 ("1.2.3") repository: (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name") condition: (可选) 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled ) tags: # (可选) - 用于一次启用/禁用 一组chart的tag import-values: # (可选) - ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项 alias: (可选) chart中利用的别名。当你要多次添加相同的chart时会很有用maintainers: # (可选) - name: 掩护者名字 (每个掩护者都须要) email: 掩护者邮箱 (每个掩护者可选) url: 掩护者URL (每个掩护者可选)icon: 用做icon的SVG或PNG图片URL (可选)appVersion: 包含的运用版本(可选)。不须要是语义化,建议利用引号deprecated: 不被推举的chart (可选,布尔值)annotations: example: 按名称输入的批注列表 (可选).
从 v3.3.2,不再许可额外的字段。推举的方法是在 annotations 中添加自定义元数据。每个chart都必须有个版本号(version)。版本必须遵照 语义化版本 2 标准。 不像经典Helm, Helm v2以及后续版本会利用版本号作为发布标记。仓库中的包通过名称加版本号标识。
比如 nginx chart的版本字段version: 1.2.3按照名称被设置为:
nginx-1.2.3.tgz
【温馨提示】appVersion字段与version字段并不干系。这是指定运用版本的一种办法。比如,这个drupal chart可能有一个 appVersion: "8.2.1",表示包含在chart(默认)的Drupal的版本是8.2.1。
3)Chart 依赖管理(dependencies)当前chart依赖的其他chart会在dependencies字段定义为一个列表。
dependencies: - name: apache version: 1.2.3 repository: https://example.com/charts - name: mysql version: 3.2.1 repository: https://another.example.com/charts
name字段是你须要的chart的名称version字段是你须要的chart的版本repository字段是chart仓库的完全URL。把稳你必须利用helm repo add在本地添加仓库你可以利用仓库的名称代替URL
示例演示:
helm repo add bitnami https://charts.bitnami.com/bitnamihelm pull bitnami/wordpresstar -xf wordpresscat wordpress/Chart.yaml
一旦你定义好了依赖,运行 helm dependency update 就会利用你的依赖文件下载所有你指定的chart到你的charts/目录。
helm dependency update ./wordpress
当 helm dependency update 拉取chart时,会在charts/目录中形成一个chart包。因此对付上面的示例,会在chart目录中期望看到以下文件:
wordpress/charts/├── common├── common-2.0.1.tgz├── mariadb├── mariadb-11.2.2.tgz├── memcached└── memcached-6.2.3.tgz
依赖中的tag和条件字段
除了上面的其他字段外,每个需求项可以包含可选字段 tags 和 condition。所有的chart会默认加载。如果存在 tags 或者 condition 字段,它们将被评估并用于掌握它们运用的chart的加载。
Condition ——条件字段field 包含一个或多个YAML路径(用逗号分隔)。 如果这个路径在上层values中已存在并解析为布尔值,chart会基于布尔值启用或禁用chart。 只会利用列表中找到的第一个有效路径,如果路径为未找到则条件无效。Tags——tag字段是与chart关联的YAML格式的标签列表。在顶层value中,通过指定tag和布尔值,可以启用或禁用所有的带tag的chart。# parentchart/Chart.yamldependencies: - 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
# parentchart/values.yamlsubchart1: enabled: truetags: front-end: false back-end: true
在上面的例子中,所有带 front-end tag的chart都会被禁用,但只要上层的value中 subchart1.enabled 路径被设置为'true',该条件会覆盖 front-end标签且 subchart1 会被启用。一旦 subchart2利用了back-end标签并被设置为了 true,subchart2就会被启用。 也要把稳只管subchart2 指定了一个条件字段, 但是上层value没有相应的路径和value,因此这个条件不会生效。
--set 参数可以用来设置标签和条件值。
helm install --set tags.front-end=true --set subchart2.enabled=false
标签和条件的解析:
条件 (当设置在value中时)总是会覆盖标签 第一个chart条件路径存在时会忽略后面的路径。标签被定义为 '如果任意的chart标签是true,chart就可以启用'。标签和条件值必须被设置在顶层value中。value中的tags:键必须是顶层键。4)通过依赖导入子Value在某些情形下,许可子chart的值作为公共默认通报到父chart中是值得的。利用 exports格式的额外好处是它可是将来的工具可以自检用户可设置的值。被导入的包含值的key可以在父chart的 dependencies 中的 import-values字段以YAML列脸色势指定。 列表中的每一项是从子chart中exports字段导入的key。导入exports key中未包含的值,利用 子-父格式。两种格式的示例如下所述。利用导出格式:如果子chart的values.yaml文件中在根节点包含了exports字段,它的内容可以通过指定的可以被直接导入到父chart的value中, 如下所示:
# parent's Chart.yaml filedependencies: - name: subchart repository: http://localhost:10191 version: 0.1.0 import-values: - data
# child's values.yaml fileexports: data: myint: 99
只要我们再导入列表中指定了键data,Helm就会在子chart的exports字段查找data键并导入它的内容。
终极的父级value会包含我们的导出字段:
# parent's valuesmyint: 99
【把稳】父级键 data 没有包含在父级终极的value中,如果想指定这个父级键,要利用'子-父' 格式。
下面示例中的import-values 指示Helm去拿到能再child:路径中找到的任何值,并拷贝到parent:的指定路径。
# parent's Chart.yaml filedependencies: - name: subchart1 repository: http://localhost:10191 version: 0.1.0 ... import-values: - child: default.data parent: myimports
上面的例子中,在subchart1里面找到的default.data的值会被导入到父chart的myimports键中,细节如下:
# parent's values.yaml filemyimports: myint: 0 mybool: false mystring: "helm rocks!"
# subchart1's values.yaml filedefault: data: myint: 999 mybool: true
父chart的结果值将会是这样:
# parent's final valuesmyimports: myint: 999 mybool: true mystring: "helm rocks!"
六、Templates and Values1)Templates and Values 简介Helm Chart 模板是按照 Go模板措辞书写, 增加了50个旁边的附加模板函数 来自 Sprig库 和一些其他 指定的函数。所有模板文件存储在chart的 templates/ 文件夹。 当Helm渲染chart时,它会通过模板引擎遍历目录中的每个文件。
模板的Value通过两种办法供应:
Chart开拓者可以在chart中供应一个命名为 values.yaml 的文件。这个文件包含了默认值。Chart用户可以供应一个包含了value的YAML文件。可以在命令行利用 helm install命令时通过-f指定value文件。模板示例
apiVersion: v1kind: ReplicationControllermetadata: name: deis-database namespace: deis labels: app.kubernetes.io/managed-by: deisspec: replicas: 1 selector: app.kubernetes.io/name: deis-database template: metadata: labels: app.kubernetes.io/name: deis-database spec: serviceAccount: deis-database containers: - name: deis-database image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} imagePullPolicy: {{ .Values.pullPolicy }} ports: - containerPort: 5432 env: - name: DATABASE_STORAGE value: {{ default "minio" .Values.storage }}
上面的例子,疏松地基于 https://github.com/deis/charts, 是一个Kubernetes副本掌握器的模板。可以利用下面四种模板值(一样平常被定义在values.yaml文件):
imageRegistry: Docker镜像的源注册表dockerTag: Docker镜像的tagpullPolicy: Kubernetes的拉取策略storage: 后台存储,默认设置为"minio"2)预定义的 ValuesValues通过模板中.Values工具可访问的values.yaml文件(或者通过 --set 参数)供应, 但可以模板中访问其他预定义的数据片段。
以下值是预定义的,对每个模板都有效,并且可以被覆盖。和所有值一样,名称 区分大小写。
Release.Name: 版本名称(非chart的)Release.Namespace: 发布的chart版本的命名空间Release.Service: 组织版本的做事Release.IsUpgrade: 如果当前操作是升级或回滚,设置为trueRelease.IsInstall: 如果当前操作是安装,设置为trueChart: Chart.yaml的内容。因此,chart的版本可以从 Chart.Version 得到, 并且掩护者在Chart.Maintainers里。Files: chart中的包含了非分外文件的类图工具。这将不许可您访问模板, 但是可以访问现有的其他文件(除非被.helmignore打消在外)。 利用{{ index .Files "file.name" }}可以访问文件或者利用{{.Files.Get name }}功能。 您也可以利用{{ .Files.GetBytes }}作为[]byte访问文件内容。Capabilities: 包含了Kubernetes版本信息的类图工具。({{ .Capabilities.KubeVersion }}) 和支持的Kubernetes API 版本({{ .Capabilities.APIVersions.Has "batch/v1" }})考虑到前面部分的模板,values.yaml文件供应的必要值如下:
imageRegistry: "quay.io/deis"dockerTag: "latest"pullPolicy: "Always"storage: "s3"
values文件被定义为YAML格式。chart会包含一个默认的values.yaml文件。 Helm安装命令许可用户利用附加的YAML values覆盖这个values:
helm install --generate-name --values=myvals.yaml wordpress
3)范围,依赖和值
Values文件可以声明顶级chart的值,以及charts/目录中包含的其他任意chart。 或者换个说法,values文件可以为chart及其任何依赖项供应值。比如,上面示范的WordPress chart同时有 mysql 和 apache 作为依赖。values文件可以为以下所有这些组件供应依赖:
title: "My WordPress Site" # Sent to the WordPress templatemysql: max_connections: 100 # Sent to MySQL password: "secret"apache: port: 8080 # Passed to Apache
更高阶的chart可以访问下面定义的所有变量。因此WordPress chart可以用.Values.mysql.password访问MySQL密码。 但是低阶的chart不能访问父级chart,以是MySQL无法访问title属性。同样也无法访问apache.port。
4)全局Values从2.0.0-Alpha.2开始,Helm 支持分外的"global"值。设想一下前面的示例中的修正版本:
title: "My WordPress Site" # Sent to the WordPress templateglobal: app: MyWordPressmysql: max_connections: 100 # Sent to MySQL password: "secret"apache: port: 8080 # Passed to Apache
面添加了global部分和一个值app: MyWordPress。这个值以.Values.global.app在 所有 chart中有效。
比如,mysql模板可以以{{.Values.global.app}}访问app,同样apache chart也可以访问。 实际上,上面的values文件会重新天生为这样:
title: "My WordPress Site" # Sent to the WordPress templateglobal: app: MyWordPressmysql: global: app: MyWordPress max_connections: 100 # Sent to MySQL password: "secret"apache: global: app: MyWordPress port: 8080 # Passed to Apache
七、Helm 资源安装顺序NamespaceNetworkPolicyResourceQuotaLimitRangePodSecurityPolicyPodDisruptionBudgetServiceAccountSecretSecretListConfigMapStorageClassPersistentVolumePersistentVolumeClaimCustomResourceDefinitionClusterRoleClusterRoleListClusterRoleBindingClusterRoleBindingListRoleRoleListRoleBindingRoleBindingListServiceDaemonSetPodReplicationControllerReplicaSetDeploymentHorizontalPodAutoscalerStatefulSetJobCronJobIngressAPIService八、Helm 安装 Chart 包的三种办法
Helm 自带一个强大的搜索命令,可以用来从两种来源中进行搜索:
helm search hub 从 Artifact Hub 中查找并列出 helm charts。 Artifact Hub中存放了大量不同的仓库。helm search repo 从你添加(利用 helm repo add)到本地 helm 客户端中的仓库中进行查找。该命令基于本地数据进行搜索,无需连接互联网。# 添加bitnami仓库源helm repo add bitnami https://charts.bitnami.com/bitnami# 从bitnami源查找所有chart包,不指定详细源的话,会查找本地添加的所有源地址的所有chart包helm search repo bitnami
1)values 传参
安装过程中有两种办法通报配置数据:
--values (或 -f):利用 YAML 文件覆盖配置。可以指定多次,优先利用最右边的文件。--set:通过命令行的办法对指定项进行覆盖。如果同时利用两种办法,则 --set 中的值会被合并到 --values 中,但是 --set中的值优先级更高。在--set 中覆盖的内容会被被保存在 ConfigMap 中。可以通过 helm get values <release-name> 来查看指定 release 中 --set 设置的值。也可以通过运行 helm upgrade 并指定 --reset-values 字段来打消 --set 中设置的值。示例如下:
echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yamlhelm install -f values.yaml bitnami/wordpress --generate-name
2)【第一种办法】直接在线 安装不须要先下载包到本地
helm install mysql bitnami/mysqlhelm list
3)【第二种办法】离线安装 直接通过安装包安装
# 先删除helm uninstall mysql# 拉包到本地helm pull bitnami/mysql# 不解压直接安装helm install mysql ./mysql-9.3.1.tgzhelm list
4)【第三种办法】离线安装 解压包再安装
# 拉包到本地helm pull bitnami/mysql# 解压安装tar -xf mysql-9.3.1.tgz# 开始安装helm install mysql ./mysql \--namespace=mysql \--create-namespace \--set image.registry=myharbor.com \--set image.repository=bigdata/mysql \--set image.tag=8.0.30 \--set primary.service.type=NodePort \--set service.nodePorts.mysql=30306# 查看在运行的Releasehelm list# 卸载helm uninstall mysql -n mysql
九、Helm 根本语法1)变量
模板(templates/)中的变量都放在{{}}中,比如:{{ .Values.images }} 表示 Values 工具下的images 字段。Values来源于values.yaml文件或者-f指定的yaml文件,或者--set设置的变量。
【温馨提示】利用-删除空格和换行符,要想删除那行其他的空格和换行符可以用{{-或者-}},一个是删除左边的空格和换行符,一个是删除右边的空格和换行符。
2)内置工具Release: Release工具描述了版本发布本身。包含了以下工具:Release.Name: release名称;Release.Namespace: 版本中包含的命名空间(如果manifest没有覆盖的话);Release.IsUpgrade: 如果当前操作是升级或回滚的话,该值将被设置为trueRelease.IsInstall: 如果当前操作是安装的话,该值将被设置为trueRelease.Revision: 这次修订的版本号。安装时是1,每次升级或回滚都会自增;Release.Service: 该service用来渲染当前模板。Helm里始终Helm。Values: Values工具是从values.yaml文件和用户供应的文件传进模板的。默认为空Chart: Chart.yaml文件内容。 Chart.yaml里的所有数据在这里都可以可访问的。比如 {{ .Chart.Name }}-{{ .Chart.Version }} 会打印出 mychart-0.1.0。Template: 包含当前被实行确当前模板信息Template.Name: 当前模板的命名空间文件路径 (e.g. mychart/templates/mytemplate.yaml);Template.BasePath: 当前chart模板目录的路径 (e.g. mychart/templates)。3)常用的内置函数1、quote and squote该函数将值转换成字符串用双引号(quote) 或者单引号(squote)括起来。示例如下:
apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmapdata: myvalue: "Hello World" drink: {{ .Values.favorite.drink | quote }} food: {{ .Values.favorite.food | upper | quote }}
颠倒命令是模板中的常见做法。可以常常看到 .val | quote 而不是 quote .val。实际上两种操作都是可以的。
2、default这个函数许可你在模板中指定一个默认值,以防这个值被忽略。
# 如果.Values.favorite.drink是非空值,则利用它,否则会返回tea。drink: {{ .Values.favorite.drink | default "tea" | quote }}# 还可以这样写,如果.Bar是非空值,则利用它,否则会返回foo。default "foo" .Bar
"空"定义取决于以下类型:
整型: 0字符串: ""列表: []字典: {}布尔: false以及所有的nil (或 null)
3、print
返回各部分组合的字符串,非字符串类型会被转换成字符串。
print "Matt has " .Dogs " dogs"
【温馨提示】当相邻两个参数不是字符串时会在它们之间添加一个空格。
4、println和 print效果一样,但会在末端新添加一行。
5、printf返回参数按顺序通报的格式化字符串。
printf "%s has %d dogs." .Name .NumberDogs{{- printf "%d" (.Values.externalCache.port | int ) -}}{{- printf "%s" .Values.existingSecret -}}{{- printf "%v" .context.Values.redis.enabled -}}# %s 字符串占位符,未解析的二进制字符串或切片# %d 数字占位符,十进制# %v 默认格式的值,当打印字典时,加号参数(%+v)可以添加字段名称
更多占位符的利用,可以参考官方文档:https://helm.sh/zh/docs/chart_template_guide/function_list/
6、trimtrim行数移除字符串两边的空格:
trim " hello "
7、trimAll
从字符串中移除给定的字符:
trimAll "$" "$5.00"
上述结果为:5.00 (作为一个字符串)。
8、lower将全体字符串转换成小写:
lower "HELLO"
上述结果为: hello
9、upper将全体字符串转换成大写:
upper "hello"
上述结果为: HELLO
10、title首字母转换成大写:
title "hello world"
上述结果为: Hello World
11、substr获取字符串的子串,有三个参数:
start (int)end (int)string (string)substr 0 5 "hello world"
上述结果为: hello
12、abbrev用省略号截断字符串 (...)
abbrev 5 "hello world"# 第一个参数:最大长度# 第二个参数:字符串
上述结果为: he..., 由于将省略号算进了长度中。
13、contains测试字符串是否包含在另一个字符串中:
contains "cat" "catch"
14、cat
cat 函数将多个字符串合并成一个,用空格分隔:
cat "hello" "beautiful" "world"
上述结果为: hello beautiful world
15、indentindent 以指定长度缩进给定字符串所在行,在对齐多行字符串时很有用:
indent 4 $lots_of_text
上述结果会将每行缩进4个空格。
16、nindentnindent 函数和indent函数一样,但可以在字符串开头添加新行。
nindent 4 $lots_of_text
上述结果会在字符串所在行缩进4个字符,并且在开头新添加一行。
17、replace实行大略的字符串更换。
# 下面两行等价replace " " "-" "I Am Henry VIII" "I Am Henry VIII" | replace " " "-"# 参数1:待更换字符串# 参数2:要更换字符串# 参数3:源字符串
上述结果为: I-Am-Henry-VIII
18、datedate函数格式化日期,日期格式化为YEAR-MONTH-DAY:
now | date "2006-01-02"
想理解更多内置函数,可以参考官方文档:https://helm.sh/zh/docs/chart_template_guide/function_list/
4)类型转换函数Helm供应了以下类型转换函数:
atoi: 字符串转换成整型。float64: 转换成 float64。int: 按系统整型宽度转换成int。int64: 转换成 int64。toDecimal: 将unix八进制转换成int64。toString: 转换成字符串。toStrings: 将列表、切片或数组转换成字符串列表。toJson (mustToJson): 将列表、切片、数组、字典或工具转换成JSON。toPrettyJson (mustToPrettyJson): 将列表、切片、数组、字典或工具转换成格式化JSON。toRawJson (mustToRawJson): 将列表、切片、数组、字典或工具转换成HTML字符未转义的JSON。5)正则表达式(Regular Expressions)Helm 包含以下正则表达式函数
regexFind(mustRegexFind)regexFindAll(mustRegexFindAll)regexMatch (mustRegexMatch)regexReplaceAll (mustRegexReplaceAll)regexReplaceAllLiteral(mustRegexReplaceAllLiteral)regexSplit (mustRegexSplit)6)编码和解码函数Helm有以下编码和解码函数:
b64enc/b64dec: 编码或解码 Base64b32enc/b32dec: 编码或解码 Base327)Dictionaries and Dict FunctionsHelm 供应了一个key/value存储类型称为dict("dictionary"的简称,Python中也有)。dict是无序类型。字典的key 必须是字符串。但值可以是任意类型,乃至是另一个dict 或 list。
1、创建字典(dict)下面是创建三个键值对的字典:
$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3"
2、获取值(get)
给定一个映射和一个键,从映命中获取值。
get $myDict "name1"
上述结果为: "value1"
把稳如果没有找到,会大略返回""。不会天生error。
3、添加键值对(set)利用set给字典添加一个键值对。
$_ := set $myDict "name4" "value4"
把稳set 返回字典 (Go模板函数的一个哀求),因此你可能须要像上面那样利用利用$_赋值来获取值。
4、删除(unset)给定一个映射和key,从映命中删除这个key。
$_ := unset $myDict "name4"
和set一样,须要返回字典。
5、判断key(hasKey)hasKey函数会在给定字典中包含了给定key时返回true。
hasKey $myDict "name1"
如果key没找到,会返回false。
6、pluckpluck 函数给定一个键和多个映射,并得到所有匹配项的列表:
pluck "name1" $myDict $myOtherDict
上述会返回的list包含了每个找到的值([value1 otherValue1])。
7、合并 dict(merge, mustMerge)将两个或多个字典合并为一个, 目标字典优先:
$newdict := merge $dest $source1 $source2
8、获取所有 keys
keys函数会返回一个或多个dict类型中所有的key的list。由于字典是 无序的,key不会有可预见的顺序。 可以利用sortAlpha存储。
keys $myDict | sortAlpha
当供应了多个词典时,key会被串联起来。利用uniq函数和sortAlpha获取一个唯一有序的键列表。
keys $myDict $myOtherDict | uniq | sortAlpha
9、获取所有 values
values函数类似于keys,返回一个新的list包含源字典中所有的value(只支持一个字典)。
$vals := values $myDict
上述结果为: list["value1", "value2", "value 3"]。
把稳 values不能担保结果的顺序;如果你须要顺序, 请利用sortAlpha。
8)Lists and List FunctionsHelm 供应了一个大略的list类型,包含任意顺序的列表。类似于数组或切片,但列表是被设计用于不可变数据类型。
1、创建列表$myList := list 1 2 3 4 5
上述会天生一个列表 [1 2 3 4 5]。
2、获取列表第一项(first, mustFirst)获取列表中的第一项,利用 first。
first $myList# 返回 1
first 有问题时会出错,mustFirst 有问题时会向模板引擎返回缺点。
3、获取列表的尾部内容(rest, mustRest)获取列表的尾部内容(除了第一项外的所有内容),利用rest。
rest $myList# 返回 [2 3 4 5]
rest有问题时会出错,mustRest 有问题时会向模板引擎返回缺点。
4、获取列表的末了一项(last, mustLast)利用last获取列表的末了一项:
last $myList # 返回 5。这大致类似于反转列表然后调用first。
5、获取列表所有内容(initial, mustInitial)
通过返回所有元素 但 除了末了一个元素。
initial $myList # 返回 [1 2 3 4]。
initial有问题时会出错,但是 mustInitial 有问题时会向模板引擎返回缺点。
6、末端添加元素(append, mustAppend)在已有列表中追加一项,创建一个新的列表。
$new = append $myList 6
上述语句会设置 $new 为 [1 2 3 4 5 6]。 $myList会保持不变。
append 有问题时会出错,但 mustAppend 有问题时会向模板引擎返回缺点。
7、前面添加元素(prepend, mustPrepend)将元素添加到列表的前面,天生一个新的列表。
prepend $myList 0
上述语句会天生 [0 1 2 3 4 5]。 $myList会保持不变。
prepend 有问题时会出错,但 mustPrepend 有问题时会向模板引擎返回缺点。
8、多列表连接(concat)将任意数量的列表串联成一个。
concat $myList ( list 6 7 ) ( list 8 )
上述语句会天生 [1 2 3 4 5 6 7 8]。 $myList 会保持不变。
9、反转(reverse, mustReverse)反转给定的列表天生一个新列表。
reverse $myList
上述语句会天生一个列表: [5 4 3 2 1]。
reverse 有问题时会出错,但 mustReverse 有问题时会向模板引擎返回缺点。
10、去重(uniq, mustUniq)天生一个移除重复项的列表。
list 1 1 1 2 | uniq
上述语句会天生 [1 2]
uniq 有问题时会出错,但 mustUniq 有问题时会向模板引擎返回缺点。
11、过滤(without, mustWithout)without 函数从列表中过滤内容。
without $myList 3# 上述语句会天生 [1 2 4 5]
一个过滤器可以过滤多个元素:
without $myList 1 3 5# 这样会得到: [2 4]
without 有问题时会出错,但 mustWithout 有问题时会向模板引擎返回缺点。
12、判断元素是否存在(has, mustHas)验证列表是否有特定元素。
has 4 $myList
上述语句会返回 true, 但 has "hello" $myList 就会返回false。
has 有问题时会出错,但 mustHas 有问题时会向模板引擎返回缺点。
13、删除空项(compact, mustCompact)吸收一个列表并删除空值项。
$list := list 1 "a" "foo" ""$copy := compact $list
compact 会返回一个移除了空值(比如, "")的新列表。
compact 有问题时会出错,但 mustCompact 有问题时会向模板引擎返回缺点。
14、index利用index list [n]获取列表的第n个元素。利用index list [n] [m] ...获取多位列表元素。
index $myList 0 返回 1,同 myList[0]index $myList 0 1 同 myList[0][1]15、获取部分元素(slice, mustSlice)从列表中获取部分元素,利用 slice list [n] [m]。等同于 list[n:m].
slice $myList 返回 [1 2 3 4 5]。 等同于 myList[:]。slice $myList 3 返回 [4 5]等同于 myList[3:]。slice $myList 1 3 返回 [2 3]等同于 myList[1:3]。slice $myList 0 3 返回 [1 2 3]等同于 myList[:3]。slice 有问题时会出错,但 mustSlice 有问题时会向模板引擎返回缺点。
16、构建一个整数列表(until)until 函数构建一个整数范围。
until 5
上述语句会天生一个列表: [0, 1, 2, 3, 4]。
对循环语句很有用: range $i, $e := until 5。
17、seqseq 5 => 1 2 3 4 5seq -3 => 1 0 -1 -2 -3seq 0 2 => 0 1 2seq 2 -2 => 2 1 0 -1 -2seq 0 2 10 => 0 2 4 6 8 10seq 0 -2 -5 => 0 -2 -4
9)数学函数(Math Functions)1、求和(add)
利用add求和。接管两个或多个输入。
add 1 2 3
2、自加1(add1)
自增加1,利用 add1。
3、相减(sub)相减利用 sub。
4、除(div)整除利用 div。
5、取模(mod)取模利用mod。
6、相乘(mul)相乘利用mul。接管两个或多个输入。
mul 1 2 3
7、获取最大值(max)
返回一组整数中最大的整数。
max 1 2 3# 返回 3
8、获取最小值(min)
返回一组数中最小的数。
min 1 2 3 # 会返回 1。
9、获取长度(len)
以整数返回参数的长度。
len .Arg
10)Network Functions
Helm供应了几个网络函数:
getHostByName吸收一个域名返回IP地址。getHostByName "www.google.com"会返回对应的www.google.com的地址。10)条件语句运算符:
eq: 即是(equal to)ne: 不即是(not equal to)lt: 小于(less than)le: 小于即是(less than or equal to)gt: 大于(greater than)ge: 大于即是(greater than or equal to)
if/else 用法:
{{if 命令}}…{{else if 命令}}…{{else}}…{{end}}
如果因此下值时,管道会被设置为 false:
布尔false数字0空字符串nil (空或null)空凑集(map, slice, tuple, dict, array)
【示例】
apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmapdata: myvalue: "Hello World" drink: {{ .Values.favorite.drink | default "tea" | quote }} food: {{ .Values.favorite.food | upper | quote }} {{ if eq .Values.favorite.drink "coffee" }}mug: "true"{{ end }}
11)变更浸染域 with
下一个掌握构造是with操作。这个用来掌握变量范围。回忆一下,.是对 当前浸染域 的引用。因此.Values便是见告模板在当前浸染域查找Values工具。
with的语法与if语句类似:
{{ with PIPELINE }} # restricted scope{{ end }}
浸染域可以被改变。with许可你为特定工具设定当前浸染域(.)。比如,我们已经在利用.Values.favorite。 修正配置映命中的.的浸染域指向.Values.favorite:
apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmapdata: myvalue: "Hello World" {{- with .Values.favorite }} drink: {{ .drink | default "tea" | quote }} food: {{ .food | upper | quote }} {{- end }}
但是这里有个把稳事变,在限定的浸染域内,无法利用.访问父浸染域的工具。缺点示例如下:
{{- with .Values.favorite }}drink: {{ .drink | default "tea" | quote }}food: {{ .food | upper | quote }}release: {{ .Release.Name }}{{- end }}
这样会报错由于Release.Name不在.限定的浸染域内。但是如果对调末了两行便是正常的, 由于在{{ end }}之后浸染域被重置了。
{{- with .Values.favorite }}drink: {{ .drink | default "tea" | quote }}food: {{ .food | upper | quote }}{{- end }}release: {{ .Release.Name }}
或者,我们可以利用$从父浸染域中访问Release.Name工具。当模板开始实行后$会被映射到根浸染域,且实行过程中不会变动。 下面这种办法也可以正常事情:
{{- with .Values.favorite }}drink: {{ .drink | default "tea" | quote }}food: {{ .food | upper | quote }}release: {{ $.Release.Name }}{{- end }}
也可以在外界限说变量,遵照$name变量的格式且指定了一个分外的赋值运算符::=。 我们可以利用针对Release.Name的变量重写上述内容。
apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmapdata: myvalue: "Hello World" {{- $relname := .Release.Name -}} {{- with .Values.favorite }} drink: {{ .drink | default "tea" | quote }} food: {{ .food | upper | quote }} release: {{ $relname }} {{- end }}
把稳在with块开始之前,赋值$relname := .Release.Name。 现在在with块中,$relname变量仍会实行版本名称。
12)rang循环语句很多编程措辞支持利用for循环,foreach循环,或者类似的方法机制。 在Helm的模板措辞中,在一个凑集中迭代的办法是利用range操作符。
定义values
favorite: drink: coffee food: pizzapizzaToppings: - mushrooms - cheese - peppers - onions
现在我们有了一个pizzaToppings列表(模板中称为切片)。修正模板把这个列表打印到配置映命中:
apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmapdata: myvalue: "Hello World" {{- with .Values.favorite }} drink: {{ .drink | default "tea" | quote }} food: {{ .food | upper | quote }} {{- end }} toppings: |- {{- range .Values.pizzaToppings }} - {{ . | title | quote }} {{- end }}
有时能在模板中快速创建列表然后迭代很有用,Helm模板的tuple可以很随意马虎实现该功能。在打算机科学中, 元组表示一个有固定大小的类似列表的凑集,但可以是任意数据类型。这大致表达了tuple的用法。
sizes: |- {{- range tuple "small" "medium" "large" }} - {{ . }} {{- end }}
上述模板会天生以下内容:
sizes: |- - small - medium - large
13)命名模板
此时须要超越模板,开始创建其他内容了。该部分我们会看到如何在一个文件中定义 命名模板,并在其他地方利用。命名模板 (有时称作一个 部分 或一个 子模板)仅仅是在文件内部定义的模板,并利用了一个名字。有两种创建办法和几种不同的利用方法。
三种声明和管理模板的方法:define,template,和block,在这部分,我们将利用这三种操作并先容一种分外用场的 include方法,类似于template操作。命名模板时要记住一个主要细节:模板名称是全局的。如果您想声明两个相同名称的模板,哪个末了加载就利用哪个。 由于在子chart中的模板和顶层模板一起编译,命名时要把稳 chart特定名称。一个常见的命名老例是用chart名称作为模板前缀:{{ define "mychart.labels" }}。利用特定chart名称作为前缀可以避免可能由于 两个不同chart利用了相同名称的模板而引起的冲突。在编写模板细节之前,文件的命名老例须要把稳:
templates/中的大多数文件被视为包含Kubernetes清单NOTES.txt是个例外命名以下划线(_)开始的文件则假定 没有 包含清单内容。这些文件不会渲染为Kubernetes工具定义,但在其他chart模板中都可用。这些文件用来存储局部和赞助工具,实际上当我们第一次创建mychart时,会看到一个名为_helpers.tpl的文件,这个文件是模板局部的默认位置。
1、用define和template声明和利用模板define操作许可我们在模板文件中创建一个命名模板,语法如下:
{{- define "MY.NAME" }} # body of template here{{- end }}
比如我们可以定义一个模板封装Kubernetes的标签:
{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }}{{- end }}
现在我们将模板嵌入到了已有的配置映命中,然后利用template包含进来:
{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }}{{- end }}apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmap {{- template "mychart.labels" }}data: myvalue: "Hello World" {{- range $key, $val := .Values.favorite }} {{ $key }}: {{ $val | quote }} {{- end }}
当模板引擎读取该文件时,它会存储mychart.labels的引用直到template "mychart.labels"被调用。 然后会按行渲染模板,因此结果类似这样:
# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata: name: running-panda-configmap labels: generator: helm date: 2022-09-04data: myvalue: "Hello World" drink: "coffee" food: "pizza"
把稳:define不会有输出,除非像本示例一样用模板调用它。
按照老例,Helm chart将这些模板放置在局部文件中,一样平常是_helpers.tpl。把这个方法移到那里:
{{/ Generate basic labels /}}{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }}{{- end }}
2、设置模板范围
在上面定义的模板中,我们没有利用任何工具,仅仅利用了方法。修正定义好的模板让其包含chart名称和版本号:
{{/ Generate basic labels /}}{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }} chart: {{ .Chart.Name }} version: {{ .Chart.Version }}{{- end }}
3、include 方法
假设定义了一个大略模板如下:
{{- define "mychart.app" -}}app_name: {{ .Chart.Name }}app_version: "{{ .Chart.Version }}"{{- end -}}
现在假设我想把这个插入到模板的labels:部分和data:部分:
apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmap labels: {{ template "mychart.app" . }}data: myvalue: "Hello World" {{- range $key, $val := .Values.favorite }} {{ $key }}: {{ $val | quote }} {{- end }}{{ template "mychart.app" . }}
如果渲染这个,会得到以下缺点:
$ helm install --dry-run measly-whippet ./mychartError: unable to build kubernetes objects from release manifest: error validating "": error validating data: [ValidationError(ConfigMap): unknown field "app_name" in io.k8s.api.core.v1.ConfigMap, ValidationError(ConfigMap): unknown field "app_version" in io.k8s.api.core.v1.ConfigMap]
要查看渲染了什么,可以用--disable-openapi-validation参数重新实行: helm install --dry-run --disable-openapi-validation measly-whippet ./mychart。 输入不是我们想要的:
# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata: name: measly-whippet-configmap labels: app_name: mychartapp_version: "0.1.0"data: myvalue: "Hello World" drink: "coffee" food: "pizza"app_name: mychartapp_version: "0.1.0"
把稳两处的app_version缩进都不对,为啥?由于被更换的模板中文本是左对齐的。由于template是一个行为,不是方法,无法将 template调用的输出传给其他方法,数据只是大略地按行插入。
为了处理这个问题,Helm供应了一个include,可以将模板内容导入当前管道,然后通报给管道中的其他方法。下面这个示例,利用indent精确地缩进了mychart.app模板:
apiVersion: v1kind: ConfigMapmetadata: name: {{ .Release.Name }}-configmap labels:{{ include "mychart.app" . | indent 4 }}data: myvalue: "Hello World" {{- range $key, $val := .Values.favorite }} {{ $key }}: {{ $val | quote }} {{- end }}{{ include "mychart.app" . | indent 2 }}
现在天生的YAML每一部分都可以精确缩进了:
# Source: mychart/templates/configmap.yamlapiVersion: v1kind: ConfigMapmetadata: name: edgy-mole-configmap labels: app_name: mychart app_version: "0.1.0"data: myvalue: "Hello World" drink: "coffee" food: "pizza" app_name: mychart app_version: "0.1.0"
include 相较于利用template,在helm中利用include被认为是更好的办法 只是为了更好地处理YAML文档的输出格式。
14)NOTES.txt文件该部分会先容为chart用户供应解释的Helm工具。在helm install 或 helm upgrade命令的末了,Helm会打印出对用户有用的信息。 利用模板可以高度自定义这部分信息。
要在chart添加安装解释,只需创建templates/NOTES.txt文件即可。该文件是纯文本,但会像模板一样处理, 所有正常的模板函数和工具都是可用的。让我们创建一个大略的NOTES.txt文件:
Thank you for installing {{ .Chart.Name }}.Your release is named {{ .Release.Name }}.To learn more about the release, try: $ helm status {{ .Release.Name }} $ helm get all {{ .Release.Name }}
现在如果我们实行helm install rude-cardinal ./mychart 会在底部看到:
RESOURCES:==> v1/SecretNAME TYPE DATA AGErude-cardinal-secret Opaque 1 0s==> v1/ConfigMapNAME DATA AGErude-cardinal-configmap 3 0sNOTES:Thank you for installing mychart.Your release is named rude-cardinal.To learn more about the release, try: $ helm status rude-cardinal $ helm get all rude-cardinal
利用NOTES.txt这种办法是给用户供应关于如何利用新安装的chart细节信息的好方法。只管并不是必需的,强烈建议创建一个NOTES.txt文件。
15)模板调试调试模板可能很棘手,由于渲染后的模板发送给了Kubernetes API server,可能会以格式化以外的缘故原由谢绝YAML文件。以下命令有助于调试:
helm lint 是验证chart是否遵照最佳实践的首选工具helm install --dry-run --debug 或 helm template --debug:我们已经看过这个技巧了, 这是让做事器渲染模板的好方法,然后返复天生的清单文件。helm get manifest: 这是查看安装在做事器上的模板的好方法。当你的YAML文件解析失落败,但你想知道天生了什么,检索YAML一个大略的办法是注释掉模板中有问题的部分, 然后重新运行 helm install --dry-run --debug:
apiVersion: v2# some: problem section# {{ .Values.foo | quote }}
以上内容会被渲染同时返回完全的注释:
apiVersion: v2# some: problem section# "bar"
实在这里紧张是正对官方文档进行整理,列出了常见的利用语法,想理解更多,可以参考官方文档,官方文档讲解的很细致,有疑问的小伙伴欢迎给我留言哦,后续会持续分享【云原生和大数据】干系的文章,请小伙伴耐心等待哦~