0. 前言

在 kubernetes 的系列文章中,我们介绍了 kubernetes 的种种概念,特性。不过对于如何部署并没有介绍,想象下如果 kubernetes 中 pod 的数量达到成百,上千,上万的话,如何对 pod 进行有效管理就成了迫在眉睫的大事。

因此,Helm 应运而生,Helm 是 Kubernetes 的包管理器,它以 chart 的方式组织,部署 pod,达到统一管理的目的。

1. Helm 架构

在 Helm3 中,Helm 结构分为 client 和 library。client 是命令行客户端,负责:

  • 本地 chart 开发
  • 管理仓库
  • 管理发布
  • 和 library 建立接口:发送安装的 chart 和发送升级或卸载现有 release 请求。

library 提供执行所有 Helm 操作的逻辑,与 Kubernetes API 服务交互提供以下功能:

  • 结合 chart 和配置构建 release
  • 将 chart 安装到 Kubernetes 中,并提供后续 Release 对象
  • 与 Kubernetes 交互升级和卸载 Release

注:这是 Helm3 的架构,在 Helm2 中还有 Tiller 组件,为何在 Helm3 中移除 Tiller 可参考 这里

2. 使用 Helm

2.1 Helm 三大概念

Chart 代表着 Helm 包。它包含在 Kubernetes 集群内部运行应用程序,工具或服务所需的所有资源定义。

Repository 是用来存放和共享 charts 的地方。

Release 是运行在 Kubernetes 集群中的 chart 的实例。一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 release。

可以这样解释 Helm:Helm 安装 charts 到 Kubernetes 集群中,每次安装都会创建一个新的 release。

2.2 快速实践 Helm

2.2.1 安装 helm chart

Helm 的 charts 有两个来源,一个是官方自带的 Artifact Hub, 一个是用户自建 repo。

可以通过 search 命令从这两个来源搜索 charts:

// helm search hub
$ helm search hub wordpress
URL CHART VERSION APP VERSION DESCRIPTION
https://artifacthub.io/packages/helm/kube-wordp... 0.1.0 1.1 this is my wordpress package
... // helm search repo
$ helm repo list
Error: no repositories to show $ helm repo add kube-wordpress https://harsh-del.github.io/wordpress-charts/charts/
"kube-wordpress" has been added to your repositories $ helm repo list
NAME URL
kube-wordpress https://harsh-del.github.io/wordpress-charts/charts/ $ helm search repo wordpress
NAME CHART VERSION APP VERSION DESCRIPTION
kube-wordpress/wordpress 0.1 1.1 this is my wordpress package

helm search 基于模糊匹配识别字符串,因此不需要指定全名。

search 到 charts 后,通过 helm install 安装 charts:

helm install my-wordpress kube-wordpress/wordpress --version 0.1.0

helm install 可以从多个来源安装 charts:

  • chart 的仓库(如上所述)
  • 本地 chart 压缩包(helm install foo foo-0.1.1.tgz)
  • 解压后的 chart 目录(helm install foo path/to/foo)
  • 完整的 URL(helm install foo https://example.com/charts/foo-1.2.3.tgz)

需要注意的是,helm install 安装的资源是有顺序的,顺序定义在 InstallOrder

当然,也可以直接使用 helm create 创建一个模板 chart,通常开发人员会基于模板 chart 自定义应用 charts:

$ helm create demo
Creating demo $ ls
demo

2.2.2 验证 helm chart

在安装 chart 部署应用的时候往往会验证 chart 是否完整可用。

使用 helm lint 验证 chart 是否可用:

$ ls
Chart.yaml charts templates values.yaml $ helm lint
==> Linting .
[INFO] Chart.yaml: icon is recommended 1 chart(s) linted, 0 chart(s) failed

使用 helm template 可对 chart 模板进行渲染,并且查看渲染结果:

$ helm template demo -f ./values.yaml --dry-run --debug
install.go:173: [debug] Original chart version: ""
Error: non-absolute URLs should be in form of repo_name/path_to_chart, got: demo

使用 helm install 的 --dry-run 和 --debug 选项可查看预安装情况:

$ helm install my-wordpress kube-wordpress/wordpress --version 0.1.0 --dry-run --debug
install.go:173: [debug] Original chart version: "0.1.0"
install.go:190: [debug] CHART PATH: /var/home/core/.cache/helm/repository/wordpress-0.1.tgz NAME: my-wordpress
LAST DEPLOYED: Sun Apr 24 08:36:04 2022
NAMESPACE: ci1
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
...

除了上述验证 chart 命令外,也可以通过 helm unittest 验证 helm chart 文件是否符合 ut 要求,更多信息可参考这里

2.2.3 测试 Release

helm install 安装完,Helm 会以 Release 的形式呈现整个资源部署情况。

可以通过 helm status [Release name] 查看资源部署情况:

$ helm status demo
NAME: demo
LAST DEPLOYED: Sun Apr 24 08:47:14 2022
NAMESPACE: ci1
STATUS: deployed
REVISION: 1
TEST SUITE: demo-test-connection
Last Started: Sun Apr 24 08:47:59 2022
Last Completed: Mon Jan 1 00:00:00 0001
Phase: Running
NOTES:
...

可以看到资源是 deployed 状态,注意 deployed 状态并不表示 pod 是 running 的(只表示消息发给 Kubernetes 正确执行了)。

值得一提的是 TEST SUITE,这里的 test suite 定义是轻量级的测试单元,负责测试部署应用的运行状态,连通性等等。可通过 helm test 执行该测试单元:

$ helm test demo
helmNAME: demo
LAST DEPLOYED: Sun Apr 24 08:47:14 2022
NAMESPACE: ci1
STATUS: deployed
REVISION: 1
TEST SUITE: demo-test-connection
Last Started: Sun Apr 24 08:47:59 2022
Last Completed: Sun Apr 24 08:52:59 2022
...

注意,该测试单元在 helm install 时并不会执行。

2.2.4 show chart 和 Release 信息

通过 helm show 和 helm get 命令可获取 chart 和 Release 的信息。这在获取配置文件时是有用的。

仅以 Release 举例:

$ helm get values demo
USER-SUPPLIED VALUES:
null $ helm get manifest demo
---
# Source: demo/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: demo
labels:
helm.sh/chart: demo-0.1.0
app.kubernetes.io/name: demo
app.kubernetes.io/instance: demo
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
---
...

2.3 helm 升降级

除了 helm install 安装 Release 外,还有 helm ugprade 和 helm rollback 可对 Release 进行升降级。

其中,helm upgrade 使用 三路策略 保证升降级的完整性。

在升级过程中使用的是最小侵入式升级策略,保证只升级改动资源。

3. helm client 简要实现

由前描述可知,helm client 调用 helm library 实现 chart 资源的创建。在应用开发过程中,可调用 helm 接口实现 helm client 的简要实现。

这里使用 helm 的 action 接口实现 2.2.4 节 helm get Release 信息的功能。

3.1 解析 kubeconfig 实现 Helm 到 Kubernetes 认证鉴权

func TransferKubeConfigToBase64(kubeconfigPath string) (string, error) {
if _, err := os.Stat(kubeconfigPath); os.IsNotExist(err) {
return "", err
} kubeconfigBytes, err := ioutil.ReadFile(kubeconfigPath)
if err != nil {
return "", err
} return base64.StdEncoding.EncodeToString(kubeconfigBytes), nil
}

定义 TransferKubeConfigToBase64 函数实现 kubeconfig 文件的解析。kubeconfig 包含 kubernetes 的认证,鉴权信息,如 API server,用户名,密码,namespace 等。

3.2 根据 kubeconfig 创建 helm client

options := helmclient.NewOptions(kubeConfig)
client, err := helmclient.NewHelmClient(&options)
if err != nil {
return err
}

其中 NewOptions 函数和 Options 结构体定义如下:

func NewOptions(kubeConfig string) Options {
return Options{
KubeConfig: kubeConfig,
Log: logging.NewLogger().Infof,
Namespace: config.ResourceConfig.Namespace,
}
} // Options defines the options for helm client's configuration
type Options struct {
RepositoryConfigPath string
RepositoryCachePath string
Debug bool
KubeConfig string
Namespace string
Log action.DebugLog
}

重点在于 NewHelmClient

// New returns a new Helm client with the provided options
func NewHelmClient(options *Options) (Client, error) { kubeConfig, err := base64.StdEncoding.DecodeString(options.KubeConfig)
if err != nil {
return nil, fmt.Errorf("decode kubeconfig failed: %w", err)
} clientGetter, err := NewRESTClientGetter(kubeConfig)
if err != nil {
return nil, fmt.Errorf("new rest client getter failed: %w", err)
} ns, _, err := clientGetter.ToRawKubeConfigLoader().Namespace()
if err != nil {
return nil, fmt.Errorf("get namespace from KubeConfig fail: %w", err)
} // Helm does not expose Namespace property, it has to be configured in this
// environment way.
ns = options.Namespace if err := os.Setenv("HELM_NAMESPACE", ns); err != nil {
return nil, fmt.Errorf("setting namespace fail, %w", err)
} settings := cli.New()
setEnvSettings(options, settings) actionConfig := new(action.Configuration)
err = actionConfig.Init(
clientGetter,
settings.Namespace(),
os.Getenv("HELM_DRIVER"),
options.Log,
)
if err != nil {
return nil, err
} return &client{
Settings: settings,
ActionConfig: actionConfig,
}, nil
}

关于代码详细实现可参考 这里, 具体不再展开。

3.3. 调用 helm library 接口实现 helm client

3.3.1 实现 helm list

client 调用 action 包的 NewList 创建 list 对象,并且调用对象的 Run 方法实现 helm list:

import (
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/release"
) releases, err := client.List()
if err != nil {
return err
} // List is to get the release name in specific namespace
// same as "helm list -n [namespace]"
func (c *client) List() ([]*release.Release, error) {
list := action.NewList(c.ActionConfig)
return list.Run()
}

3.3.2 实现 helm get values

values, err := client.GetValues(name)
if err != nil {
return err
} func (c *client) GetValues(name string) (map[string]interface{}, error) {
getValues := action.NewGetValues(c.ActionConfig)
return getValues.Run(name)
}

至此我们开发了 helm client 的简易基本功能。

4. 总结

最大的感受是想玩好 Helm 并不是那么容易的,如果我们想深入理解的话,还是有不少内容可以挖的。比如 Helm 怎么实现 chart 到 manifest 的解析,模糊匹配怎么做到的,怎么实现

最小倾入式升级,都是可以深挖的点。

当然,关于 helm 的使用及日常开发的最佳实践还是 cover 到一点的,详细内容可参考 Helm 官网


玩转 Helm的更多相关文章

  1. Sentry(v20.12.1) K8S 云原生架构探索,玩转前/后端监控与事件日志大数据分析,高性能+高可用+可扩展+可伸缩集群部署

    Sentry 算是目前开源界集错误监控,日志打点上报,事件数据实时分析最好用的软件了,没有之一.将它部署到 Kubernetes,再搭配它本身自带的利用 Clickhouse (大数据实时分析引擎)构 ...

  2. Why Helm? - 每天5分钟玩转 Docker 容器技术(160)

    本章我们将学习 Helm,Kubernetes 的包管理器. 每个成功的软件平台都有一个优秀的打包系统,比如 Debian.Ubuntu 的 apt,Redhat.Centos 的 yum.而 Hel ...

  3. Helm 架构 - 每天5分钟玩转 Docker 容器技术(161)

    在实践之前,我们先来看看 Helm 的架构. Helm 有两个重要的概念:chart 和 release. chart 是创建一个应用的信息集合,包括各种 Kubernetes 对象的配置模板.参数定 ...

  4. 部署 Helm - 每天5分钟玩转 Docker 容器技术(162)

    本节我们将安装和部署 Helm 客户端和 Tiller 服务器. Helm 客户端 通常,我们将 Helm 客户端安装在能够执行 kubectl 命令的节点上,只需要下面一条命令: curl http ...

  5. 使用 Helm - 每天5分钟玩转 Docker 容器技术(163)

    Helm 安装成功后,可执行 helm search 查看当前可安装的 chart. 这个列表很长,这里只截取了一部分.大家不禁会问,这些 chart 都是从哪里来的? 前面说过,Helm 可以像 a ...

  6. 手把手教你玩转 Gitea|使用 Helm 在 K3s 上安装 Gitea

    前言 在前面的文章中,演示了如何用 Docker 镜像和 Windows 二进制包来安装运行 Gitea.今天是玩转 Gitea 系列的使用 Helm 在 K3s 上安装 Gitea. 关于 Gite ...

  7. 用 ConfigMap 管理配置 - 每天5分钟玩转 Docker 容器技术(159)

    Secret 可以为 Pod 提供密码.Token.私钥等敏感数据:对于一些非敏感数据,比如应用的配置信息,则可以用 ConfigMap. ConfigMap 的创建和使用方式与 Secret 非常类 ...

  8. chart 目录结构 - 每天5分钟玩转 Docker 容器技术(164)

    chart 是 Helm 的应用打包格式.chart 由一系列文件组成,这些文件描述了 Kubernetes 部署应用时所需要的资源,比如 Service.Deployment.PersistentV ...

  9. 再次实践 MySQL chart - 每天5分钟玩转 Docker 容器技术(166)

    学习了 chart 结构和模板的知识后,现在重新实践一次 MySQL chart,相信会有更多收获. chart 安装前的准备 作为准备工作,安装之前需要先清楚 chart 的使用方法.这些信息通常记 ...

  10. 开发自己的 chart - 每天5分钟玩转 Docker 容器技术(167)

    Kubernetes 给我们提供了大量官方 chart,不过要部署微服务应用,还是需要开发自己的 chart,下面就来实践这个主题. 创建 chart 执行 helm create mychart 的 ...

随机推荐

  1. 测试框架TestNG学习笔记

    目录 一.TestNG的基本介绍和如何在maven中引用 二.TestNG基本注解与执行顺序实战 2.1 注解实战 @Test标签 2.2 注解实战 BeforeMethod和AfterMethod ...

  2. 基于yolo的口罩识别(开源代码和数据集)

    2020年开头真的很人意外,开年爆发了疫情.此次疫情牵动了各行各业,在这里衷心的感谢奋斗在一线的医疗工作者:您们辛苦了.作为一名非医专业的学生,在这样情况下,除了不乱跑以外,我也想以另一种方式去致敬那 ...

  3. MySQL运维8-Mycat范围分表

    一.范围分片 根据指定的字段及其配置的范围与数据节点的对应情况,来决定该数据属于哪一个分片. 说明1:范围分片会提前提供一个分片的范围默认是0-500万是一个分片,500万-1000万是一个分片,10 ...

  4. Taurus .Net Core 微服务开源框架:Admin 插件【4-8】 - 配置管理-Mvc【Plugin-Limit 接口访问限制、IP限制、Ack限制】

    前言: 继上篇:Taurus .Net Core 微服务开源框架:Admin 插件[4-7] - 配置管理-Mvc[Plugin-Metric 接口调用次数统计] 本篇继续介绍下一个内容: 1.系统配 ...

  5. Windows Server 2012 R2在桌面上显示我的电脑等图标

     从Windows 2012 开始,微软取消了服务器桌面个性化选项,如何重新调出配置界面,可以使用微软命令.方法如下: 按下「Win鍵」+「R」,在运行里输入: rundll32.exe shell3 ...

  6. zabbix 默认消息

    故障事件: {TRIGGER.NAME}监控状态: {TRIGGER.STATUS}报警严重性: {TRIGGER.SEVERITY}触发结果: {TRIGGER.URL}告警时间:{EVENT.DA ...

  7. Spring Boot结合Element UI前后端分离的aixos的简单操作

    1:axios是什么? 基于promise用于浏览器和node.js的http客户端 axios官网:http://www.axios-js.com/  2:准备工作: 安装axios:npm ins ...

  8. JavaFx设置图标(二)

    JavaFx设置图标(二) JavaFX 从入门入门到入土系列 JavaFx设置图标,需要注意,我这里是Maven管理项目 需要将图片放到resources/img/avatar.jpg下 impor ...

  9. Numpy计算近邻表时间对比

    技术背景 所谓的近邻表求解,就是给定N个原子的体系,找出满足cutoff要求的每一对原子.在前面的几篇博客中,我们分别介绍过CUDA近邻表计算与JAX-MD关于格点法求解近邻表的实现.虽然我们从理论上 ...

  10. 通过 KernelUtil.dll 劫持 QQ / TIM 客户端 QQClientkey / QQKey 详细教程(附源码)

    前言 由于 QQ 9.7.20 版本后已经不能通过模拟网页快捷登录来截取 QQClientkey / QQKey,估计是针对访问的程序做了限制,然而经过多方面测试,诸多的地区.环境.机器也针对这种获取 ...