「HELM」- 创建 Charts 并上传

该笔记将记录:通过 Helm 创建 Charts 并上传仓库的概述方法,以及相关问题的解决办法;

增 | 创建 Chart 制品

第一步、创建 Chart 项目

Helm | Helm Create

# helm create my-app
Creating my-app

# tree  my-app/
my-app/
├── charts -------------------------------------------------------------------- # 该目录当前 Chart 所依赖的 chart 保存;
├── Chart.yaml ---------------------------------------------------------------- # 关于 my-app 的信息;
├── templates ----------------------------------------------------------------- # 模板文件所在目录
│   ├── deployment.yaml
│   ├── _helpers.tpl ------------------------------------------------------------ # 自定义的帮助函数,用于变量计算等等;
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests ------------------------------------------------------------------- # 测试文件;
│       └── test-connection.yaml
└── values.yaml --------------------------------------------------------------- # 模板的默认值;

3 directories, 10 files

# helm template my-app                                                          # 对模板进行渲染,以检查是否存在错误
...

# helm install my-app --name=my-app-name                                        # 对其进行安装测试;

针对 PVC 存储

Template for persistent volumes on helm charts – Alekc’s Blog

第二步、修改 Chart 内容

按照需求对 Chart 进行修改:

版本号 | Version Number

Semantic Versioning 2.0.0 |
https://semver.org/spec/v2.0.0.html

Looping with the range action | https://helm.sh/docs/chart_template_guide/control_structures/#looping-with-the-range-action

...
  toppings: |-
    {{- range .Values.pizzaToppings }}
    - {{ . | title | quote }}
    {{- end }}
...

第三步、打包 Chart 项目

打包的目的是将 Chart 与其他人共享

# helm package my-app
Successfully packaged chart and saved it to: /x/x/x/my-app-0.1.0.tgz

通过 -d, –destination string 选项,能够制定 Chart 输出目录。

通过 –app-version 参数,来指定应用版本。该版本与 Chart 包含的应用有关。

通过 –version 参数,来指定 Chart 版本,该版本是 Chart 本身的版本,其与应用无关。

修改 Chart 参数值

  • 我们希望能够通过命令行来修改 values.yaml 的参数信息,而后 helm package 来完成打包工作。

第四步、推送 Chart 仓库

Helm | Helm Push
How to make and share your own Helm package | by Containerum
Harbor docs | Managing Helm Charts

Chart 仓库有多种形态:
1)通过 GitHub Page 实现的(核心是 index.yaml 文件);
2)类似 Harbor 提供的 ChartMuseum 仓库,提供 API 访问;
3)…………

多种 Chart 仓库上传 Chart 的方法也不相同;

Helm v2 + Harbor (version < 2.8)

Helm Push 的实现方式
现阶段,我们 CI/CD 使用 Helm v2 版本,原生的 helm 不包含 push 子命令。但是 helm 支持通过插件扩展,所以 helm push 命令是通过 ChartMuseum Plugin 提供的。同时 Harbor 仓库的 Chart 管理功能是通过 ChartMuseum Service 实现的。在 ChartMuseum Plugin 和 ChartMuseum Service 的配合下,实现 Chart 的管理与推送。

我们将讨论如何将 package 发送到 Harbor 镜像仓库(Harbor docs | Managing Helm Charts);

// -------------------------------------------------------- // 安装插件(# 需要在线安装,暂时未找到离线安装的方法)

# helm plugin install https://github.com/chartmuseum/helm-push

// -------------------------------------------------------- // 添加仓库

# helm repo add --username=admin --password=Passw0rd myrepo https://xx.xx.xx.xx/chartrepo/myproject

// -------------------------------------------------------- // 通过 helm push 进行推送

# helm push --username=admin --password=passw0rd chart_repo/hello-helm-0.1.0.tgz myrepo

// -------------------------------------------------------- // 对于新版本的 helm 需要使用如下命令:

# helm cm-push  ./my-app-0.1.0.tgz rivtower-registry
Pushing my-app-0.1.0.tgz to myrepo...
Done.

helm push – Error: scheme prefix missing from remote (e.g. “oci://”)

ChartMuseum – Helm Chart Repository

Harbor 集成 ChartMuseum 来提供 Chart 仓库服务,所以如果需要将 Chart 推送到 Harbor 镜像仓库:
1)需要 ChartMuseum 提供的 RUST API:curl –data-binary “@mychart-0.1.0.tgz” http://hostname/api/charts
2)如果使用 helm 命令,则需要使用 ChartMuseum 提供的 helm-push 插件,通过 helm push 推送;

新版本的 Harbor 镜像仓库(version 2.8),移除 ChartMuseum Service,改用 OCI 进行制品管理,所以本地无法再使用 ChartMuseum Plugin 来推送 Chart 包。同时,Helm v3 命令也内置 helm push 子命令来使用 OCI 进行 Chart 管理。

但是,从 Helm 3.7.0 起,push 成为 helm 的内置命令(oci://),导致 helm-push 插件提供的 helm push 失败;
helm-push 插件被迫改名 helm cm-push 命令,所以如果使用 ChartMuseum 提供的仓库,则需要使用 cm-push 命令;

# 打包与添加仓库保持不变
helm package --app-version=v1.12.7 --version=1.12.7 api-gateway
helm repo add rivtower oci://registry.example.com/chartrepo/gateway --username 'robot$jenkins-bot' --password ****

# 新的推送方式:
helm push ./api-gateway-1.12.7.tgz  oci://registry.example.com/gateway/backend/system-service-layer/

该方式下,在 Harbor 中,Image 与 Chart 存储在一起,都是 Artifacts 资源。

# 06/27/2023 现在我们还没有使用改方式来推送 Chart,原因是 Rancher 2.7 还不支持从 OCI-based Registry 中拉取 Chart 包。

查 | 查看 Chart 信息

可用 Chart 搜索

helm search repo "<chart-name>"
helm search repo "haproxy"                                  # 在仓库中,搜索 haproxy

helm search repo --versions "rancher-stable"                # 查看所有版本:-l, --versions
helm search repo --versions "rancher-stable" --version '^2.8' # 搜索特定版本

通过 Helm Show Chart 命令,能够查看 Chart 参数。

–devel | 通过该选项来查看开发版本。

查看 Chart 信息

我们需要读取其中的参数,但是该命令并不支持 –output yaml 类似功能,所以:

eval $(helm show chart ./your-chart-0.1.0.tgz | sed -E 's/(.+): (.+)/\1="\2"/g')

# 然后通过 $name, $version, ... 来获取对应信息即可。

helm show chart [CHART] [flags]
https://helm.sh/docs/helm/helm_show_chart/

获得 Chart 文件名

在 Jenkins CI 中,我们需要知道 helm package 生成的文件名,已将其推送到仓库中。

其输出文件 CHART_NAME-VERSION.tgz 采用命名约定,所以如果需要获得文件名:

eval $(helm show chart ./my-app | sed -E 's/(.+): (.+)/\1="\2"/g')
echo ${name}-${version}.tgz