第 5 篇 Chart 文件结构详解


🚀 本文内容:介绍 Chart 文件结构,便于后续分析 Chart 并做修改。

⭐ 思维导图

画板


Helm 使用的包格式称为 chart,chart 是一个描述 Kubernetes 相关资源的文件集合。

😂 怎么理解?

  • 首先,它是一个文件集合。存放各种文件。
  • 其次,文件是什么呢?是 Kubernetes 资源描述文件。比如 deployment、service 等 yaml 文件。

😊 示例:WordPress chart

wordpress/            # 目录名:chart 名称,不包含版本号
  Chart.yaml          # chart 描述信息,包含了 chart 信息的 YAML 文件
  values.yaml         # chart 默认配置信息
  values.schema.json  # 可选,chart 配置的 JSON shchema,用于验证传入的配置是否有效。
  templates/          # 可选,模板目录,存放各种模板文件,与 values 结合,生成有效的 K8s manifest 文件
  templates/NOTES.txt # 可选,模板简要说明,在安装后/查看版本时会打印出来(作为模板渲染,而不是纯文本)
  charts/             # 可选,依赖的子 chart 目录
  crds/               # 可选,自定义资源目录
  README.md           # 可选,READEME 文件
  LICENSE             # 可选,许可证文件

注意:Helm 保留使用 charts/、crds/、templates/ 目录,以及列举出的文件名。

Chart.yaml

Chart.yaml 是必需的,包含如下字段。

  • 🚀 核心字段:chart 名称、chart 版本号、chart API 版本号、兼容的 Kubernetes 版本、chart 类型、chart 依赖、chart 元数据信息
  • 🙂 不重要字段:chart 描述、主页、图标、关键字、维护者、源码地址

Chart.yaml 示例

下面以 bitnami/nginx 的 Chart.yaml 为例:

# chart 名称(必需)
name: nginx

# chart 版本号(必需)
## 会在包名上体现,包名是 nginx-17.1.0.tgz
version: 17.1.0

# chart API 版本(必需)
## 对于至少是 Helm3 的 chart,则值至少是 v2;
## Helm 及 Helm2,就不提了哦
apiVersion: v2

# 包含的应用版本号(可选)
## 与 version 字段没有关系,version 是 chart 的版本号
## 指定创建的应用的版本号,即 Nginx 本身的版本号是 1.26.0
appVersion: 1.26.0

# 兼容的 Kubernetes 版本(可选)
## 对 Kubernetes 版本进行约束,Helm 安装这个 chart 的时候会验证这个版本约束。
## 支持比较运算符,像下面的例子,就可以很好的避开 1.14.0 版本
## 速记符号 - 连字符:1.1 - 2.3.4 等价于 >= 1.1 <= 2.3.4
## 速记符号 - 通配符 x/X/*:1.2.x 等价于 >= 1.2.0 < 1.3.0
## 速记符号 - ~(允许改变补丁版本):~1.2.3 等价于 >= 1.2.3 < 1.3.0
## 速记符号 - ^(允许改变次版本):^1.2.3 等价于 >= 1.2.3 < 2.0.0
kubeVersion: >= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0

# 是否弃用 chart(可选)
## 布尔值 true/false
## 如果 lastest 版本被标记为弃用,则所有 chart 都会被标记为弃用
deprecated: false

# chart 类型(可选)
## 有两种类型:application(默认值)、library
## library 类型:提供针对 chart 构建的应用程序和功能。不能安装,不包含任何资源对象。
type: application

# chart 依赖列表 (可选)
dependencies:
## chart 名称
- name: common
  ## chart 版本
  version: 2.x.x
  ## 仓库 URL(可选)
  repository: oci://registry-1.docker.io/bitnamicharts
  ## 用于启用/禁用所有带 tag 的 chart(可选)
  tags:
  - bitnami-common
  ## 用于启用/禁用 chart(可选)
  condition: bitnami-common.enabled
  ## 导入依赖chart中的 values 到当前 chart 中(可选)
  import-values: # (可选)
    - ImportValue
  ## chart别名(可选),需多次添加相同的chart时很有用
  alias: common1

# 自定义元数据
## 自 v3.3.2 开始,不再允许添加额外的字段(会被抛弃),需使用 annotations 添加;
annotations:
  category: Infrastructure
  images: |
    - name: git
      image: docker.io/bitnami/git:2.45.1-debian-12-r0
    - name: nginx
      image: docker.io/bitnami/nginx:1.26.0-debian-12-r1
    - name: nginx-exporter
      image: docker.io/bitnami/nginx-exporter:1.1.0-debian-12-r23
  licenses: Apache-2.0

# ----------------- 不重要 ---------------------------
# chart 描述信息(可选)
description: NGINX Open Source is a web server ...

# 项目 home 页面的 URL (可选)
home: https://bitnami.com

# 用做 icon 的 SVG 或 PNG 图片 URL(可选)
icon: https://bitnami.com/assets/stacks/nginx/img/nginx-stack-220x234.png

# 项目的一些关键字(可选)
keywords:
- nginx
- http
- web
- www

# 项目源码的 URL 列表(可选)
sources:
- https://github.com/bitnami/charts/tree/main/bitnami/nginx

# 项目维护者(可选)
maintainers:
- name: Broadcom, Inc. All Rights Reserved.
  url: https://github.com/bitnami/charts
  email: xxx@xxx.com

子 chart 对 helm 安装/升级的影响

假设:

  • chart A 创建了如下 k8s 对象:A-namespace、A-StatefulSet、A-Service
  • A 是依赖于 chart B 创建的对象:B-namespace、B-ReplicaSet、B-Service

那么,helm install/upgrade 的顺序是什么呢?

  • A-namespace
  • B-namespace
  • A-Service
  • B-Servie
  • B-ReplicaSet
  • A-StatefulSet

👉 排序规则是什么?

  • 聚合成单一的集合;然后按照类型和名称排序;然后按这个顺序创建/升级。
  • Kubernetes 类型排序,按 kind_sorter.go 定义的枚举顺序进行。
// InstallOrder is the order in which manifests should be installed (by Kind).
// Those occurring earlier in the list get installed before those occurring later in the list.
var InstallOrder KindSortOrder = []string{
    "PriorityClass",
    "Namespace",
    "NetworkPolicy",
    "ResourceQuota",
    "LimitRange",
    "PodSecurityPolicy",
    "PodDisruptionBudget",
    "ServiceAccount",
    "Secret",
    "SecretList",
    "ConfigMap",
    "StorageClass",
    "PersistentVolume",
    "PersistentVolumeClaim",
    "CustomResourceDefinition",
    "ClusterRole",
    "ClusterRoleList",
    "ClusterRoleBinding",
    "ClusterRoleBindingList",
    "Role",
    "RoleList",
    "RoleBinding",
    "RoleBindingList",
    "Service",
    "DaemonSet",
    "Pod",
    "ReplicationController",
    "ReplicaSet",
    "Deployment",
    "HorizontalPodAutoscaler",
    "StatefulSet",
    "Job",
    "CronJob",
    "IngressClass",
    "Ingress",
    "APIService",
}

// UninstallOrder is the order in which manifests should be uninstalled (by Kind).
// Those occurring earlier in the list get uninstalled before those occurring later in the list.
var UninstallOrder KindSortOrder = []string{
    "APIService",
    "Ingress",
    "IngressClass",
    "Service",
    "CronJob",
    "Job",
    "StatefulSet",
    "HorizontalPodAutoscaler",
    "Deployment",
    "ReplicaSet",
    "ReplicationController",
    "Pod",
    "DaemonSet",
    "RoleBindingList",
    "RoleBinding",
    "RoleList",
    "Role",
    "ClusterRoleBindingList",
    "ClusterRoleBinding",
    "ClusterRoleList",
    "ClusterRole",
    "CustomResourceDefinition",
    "PersistentVolumeClaim",
    "PersistentVolume",
    "StorageClass",
    "ConfigMap",
    "SecretList",
    "Secret",
    "ServiceAccount",
    "PodDisruptionBudget",
    "PodSecurityPolicy",
    "LimitRange",
    "ResourceQuota",
    "NetworkPolicy",
    "Namespace",
    "PriorityClass",
}

templates/ 与 values.yaml

模板编写:按 Go模板语言 书写,存放在 templates/ 目录下。当 helm 渲染 chart 时,它会通过模板引擎遍历目录中的每个文件。

Helm 增加了 50 个左右的附加模板函数(来自 Sprig库 )和一些其它的指定的函数,便于在模板中使用。

values.yaml:就是一个普通的 YAML 文件,定义配置的。

模板与 Value 示例

示例 values.yaml 如下:

imageRegistry: "docker.io"
dockerTag: "v1.1.0"
pullPolicy: "IfNotPresent"
storage: "s3"

示例模板如下:

apiVersion: v1
kind: ReplicationController
metadata:
  name: deis-database
  namespace: deis
  labels:
    app.kubernetes.io/managed-by: deis
spec:
  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: {{ required "A valid imageRegistry is required!" .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }}
          imagePullPolicy: {{ .Values.pullPolicy }}
          ports:
            - containerPort: 5432
          env:
            - name: DATABASE_STORAGE
              value: {{ default "minio" .Values.storage }}

上面的例子,是一个 k8s 副本控制器模板。

该模板,使用 Values 来取值,值来源于 values.yaml 文件。

  • 最简单:{{ .Values.dockerTag }}:获取 dockerTag 的值
  • 必填项:{{ required “A valid imageRegistry is required!” .Values.imageRegistry }} :获取 imageRegistry 的值,且必填
  • 默认值:{{ default “minio” .Values.storage }}:获取 storage 的值,默认为 “minio”

模板命令要括在 {{ 和 }} 之间。

{{ .Release.Name }}

  • 用点分隔每个命名空间的元素。
  • 第一个点,表示从作用域最顶层的命名空间开始
  • 表示从顶层命名空间开始查找 Release 对象,并在其中查找 Name 对象

预定义的 Values

Values 通过模板中 .Values 对象可访问 values.yaml 文件(或者通过–set 参数提供)的配置,也可以访问其他预定义的配置。

以下值都是预定义的,对每个模板有效,且可以被覆盖。名称区分大小写。

  • Release 对象:描述了版本发布本身的信息。
    • Release.Name:发布名称(非 chart )
    • Release.Namespace:发布命名空间
    • Release.Service:该 service 用来渲染当前模板
    • Release.IsInstall:当前操作是否是安装,设置为 true
    • Release.IsUpgrade:当前操作是否是升级/回滚,设置为 true
  • Values 对象:从默认 values.yaml 或用传递的 yaml 或者 --set 参数提供的配置。
  • Chart 对象:Chart.yaml 中的内容。比如版本,Chart.Version。
  • Files 对象:访问所有非特殊文件的对象,不能使用它访问 Template 对象,只能访问其他文件
    • Files.Get:通过文件名获取文件,比如 .Files.Get config.ini
    • Files.GetBytes 用字节数组代替字符串获取文件内容,常用于图片类文件
    • Files.Glob 用给定的 shell glob 模式匹配文件名返回文件列表
    • Files.Lines 逐行读取文件内容,常用于迭代文件每一行
    • Files.AsSecrets 使用 Base64 编码字符串返回文件体
    • Files.AsConfig 使用 YAML 格式反馈文件体
  • Capabilities 对象:提供关于 Kubenetes 集群支持功能的信息
    • Capabilities.APIVersions 版本列表
    • Capabilities.APIVersions.Has $version 说明集群中的版本 (比如,batch/v1) 或是资源 (比如,apps/v1/Deployment) 是否可用
    • Capabilities.KubeVersion Kubernetes 版本信息
      • Capabilities.KubeVersion.Version Kubernetes 版本号
      • Capabilities.KubeVersion.Major 主版本号
      • Capabilities.KubeVersion.Minor 次版本号
    • Capabilities.HelmVersion Helm 版本信息
      • Capabilities.HelmVersion.Version Helm 语义格式的版本
      • Capabilities.HelmVersion.GitCommit Helm的 git sha1 值
      • Capabilities.HelmVersion.GitTreeState Helm git 树的状态
      • Capabilities.HelmVersion.GoVersion 使用的 Go 编译器版本
  • Template 对象:包含当前被执行的当前模板信息
    • Template.Name: 模板名称,含路径。 比如 mychart/templates/mytemplate.yaml
    • Template.BasePath: 模板路径,比如 mychart/templates

😊 Values 命名规范

  • 内置 Values:以大写字母开始,这符合 Go 的命名惯例。
  • 自定义 Values:使用小写字母开始,可方便地与内置对象区分开。很多 Artifact Hub 中的 chart,都是这样做的。

全局 Values

自 2.0.0-Alpha.2 开始,Helm 支持特殊的 global 值。

全局 Values 的作用域:只能往下传递,不会向上传递。且父 chart 的优先级更高。

  • 如果子 chart 声明了一个全局 Values,则只会向下传递到子 chart 的子 chart 中,不会向上传递到父 chart。
  • 子 chart 是无法影响父 chart 的值的。
  • 父 chart 的全局 Values 优先于子 chart 中的全局 Values。

示例如下:

title: "My WordPress Site" # Sent to the WordPress template

# 我是全局 Values !!!
global:
  app: MyWordPress

mysql:
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  port: 8080 # Passed to Apache

这个 global.app 在所有 chart 中生效。

  • 在 mysql 模板中,可以访问 {{.Values.global.app}}
  • 在 apache 模板中,可以访问 {{.Values.global.app}}

全局 Values 的本质:重新生成 values.yaml,给每个子 chart 也添加上 Values。

title: "My WordPress Site" # Sent to the WordPress template

global:
  app: MyWordPress

mysql:
  global:
    app: MyWordPress
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  global:
    app: MyWordPress
  port: 8080 # Passed to Apache

Values 作用域

Values 作用域:父 chart 可以访问子 chart 的 Values,但子 chart 无法访问父 chart 的 Values。

比如 WordPress chart 同时有 mysql 和 apache 作为依赖。

title: "My WordPress Site" # Sent to the WordPress template

mysql:
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  port: 8080 # Passed to Apache

✔️ WordPress chart 使用 .Values.mysql.password 访问 MySQL 密码。

❌ mysql chart 无法访问 title 属性,apache/port 也无法访问。

✔️ mysql chart 使用 .Values.password 访问 MySQL 密码。【命名空间删减,所以不需要写 mysql】

templates/NOTES.txt

NOTES.text 会在安装后及查看版本状态(helm install、helm status)时从打印出来。

这个文件会作为一个模板来评估,并用来显示使用说明、后续步骤、或者其他 chart 版本的相关信息。

比如 连接数据库的说明,Web UI 访问地址等。

values.schema.json

基于 values.yaml 定义一个结构,并使用 JSON 显示。

相当于定义了一个结构,values 值使用的时候(helm install、update、lint、template),会去验证结构是否正确。

{
  "$schema": "https://json-schema.org/draft-07/schema#",
  "properties": {
    "image": {
      "description": "Container Image",
      "properties": {
        "repo": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      },
      "type": "object"
    },
    "name": {
      "description": "Service name",
      "type": "string"
    },
    "port": {
      "description": "Port",
      "minimum": 0,
      "type": "integer"
    },
    "protocol": {
      "type": "string"
    }
  },
  "required": [
    "protocol",
    "port"
  ],
  "title": "Values",
  "type": "object"
}

一个符合上述结构的 values.yaml 文件:

name: frontend
protocol: https
port: 443

或者这样:values.yaml + --set 参数

name: frontend
protocol: https
helm install --set port=443

用户自定义资源(CRD)

使用 Kubernetes 的 CustomResourceDefinition(CRD),可声明自定义的资源类型。

在 Helm 3 中,CRD 被视作特殊对象,其会在 chart 的其它部分之前安装,并有一些限制。

CRD 文件说明:

  • 放在 chart 的 crds/ 目录下,Helm 会加载此目录下所有 YAML 文件到 Kubernetes;
  • 多个 CRD 可放在一个 YAML 文件中(使用 YAML 的开始和结束符分隔);
  • CRD 文件无法模板化,只能是普通的 YAML 文件;

CRD 安装顺序

安装顺序:先上传 CRD,暂停 chart 安装直到 CRD 可以被 API 服务使用,然后启动模板引擎,渲染 chart 其它部分,并上传到 Kubernetes。

😁 很明显,CRD 是先运行好的,然后再执行 chart 中的相关 k8s 资源

所以,我们可以在模板中使用 CRD 中定义的资源。

比如,如下 chart,定义了 crontab 资源。

crontabs/
  Chart.yaml
  crds/
    crontab.yaml
  templates/
    mycrontab.yaml

crontab.yaml 文件如下,可以看到,没有任何模板指令,就是纯粹的 K8s 资源文件。

kind: CustomResourceDefinition
metadata:
  name: crontabs.stable.example.com
spec:
  group: stable.example.com
  versions:
    - name: v1
      served: true
      storage: true
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab

然后模板 mycrontab.yaml 可以创建一个新的 CronTab:Helm 在安装 templates/ 内容之前会保证 CronTab 类型安装成功并对 Kubernetes API 可用

apiVersion: stable.example.com
kind: CronTab
metadata:
  name: {{ .Values.name }}
spec:
   # ...

CRD 限制说明

CRD 的限制:不像大部分的 Kubernetes 对象,CRD 是全局安装的

CRD 受到以下限制:

  • CRD 从不重新安装。如果 Helm 确定 crds/ 目录中的 CRD 已经存在(忽略版本),Helm 不会安装或升级。
  • CRD 从不会在升级或回滚时安装。Helm 只会在安装时创建 CRD。
  • CRD 从不会被删除。自动删除 CRD 会删除集群中所有命名空间中的所有 CRD 内容。因此 Helm 不会删除 CRD。

希望升级或删除 CRD 时,应谨慎地手动执行此操作。

README.md

chart 的自述文件 README.md:使用 Markdown 格式

一般包含:

  • chart 描述信息
  • chart 先决条件
  • values.yaml 的可选项、默认值、描述
  • 其它相关信息

LICENSE

LICENSE 许可证,是一个包含了 chart license 的纯文本文件。

chart 可以包含一个许可证,因为模板里不仅是配置,还有代码逻辑。

如果需要,可以为 chart 安装的应用提供单独的许可证。

相关博文

1.第 1 篇 Helm 简介及安装
2.第 2 篇 Helm 部署 MySQL【入门案例】
3.第 3 篇 Helm 命令、环境变量、相关目录
4.第 4 篇 Chart 仓库详解
5.第 5 篇 Chart 文件结构详解
6.第 6 篇 自定义 Helm Chart
7.第 7 篇 Helm 部署 Nacos【详细步骤】
8.第 8 篇 Chart 修改入门示例:Nacos
9.第 9 篇 Helm 部署 Seata Server
10.第 10 篇 Chart 修改完美示例:Seata Server
11.第 11篇 Helm 部署 RabbitMQ
12.第 12 篇 Helm 部署 Redis
13.第13 篇 Helm 部署 ElasticSearch

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甘蓝聊Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值