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. ceph集群搭建详细教程(ceph-deploy)

    ceph-deploy比较适合生产环境,不是用cephadm搭建.相对麻烦一些,但是并不难,细节把握好就行,只是命令多一些而已. 实验环境 服务器主机 public网段IP(对外服务) cluster ...

  2. ElasticSearch之Refresh API

    使用本方法,显式的执行refresh操作. 默认情况下,ElasticSearch启动后台任务,周期性执行refresh操作,周期使用参数index.refresh_interval控制. 本方法触发 ...

  3. 轻量对象存储 LighthouseCOS 用户实践征文

    产品使用攻略.上云技术实践,有奖征集,多重好礼等您带回家- 存储桶一键挂载轻量应用服务器,简单易用,腾讯云轻量对象存储用户实践征文活动特惠:腾讯云轻量云专场特惠活动. 投稿说明 注册/登录腾讯云账号, ...

  4. UnionFind 并查集

    简介 UnionFind 主要用于解决图论中的动态联通性的问题(对于输入的一系列元素集合,判断其中的元素是否是相连通的). 以下图为例: 集合[1, 2, 3, 4] 和 [5, 6]中的每个元素之间 ...

  5. 如何使用 Helm 在 K8s 上集成 Prometheus 和 Grafana|Part 2

    在 Part 1 中,我们一起了解了什么是 Prometheus 和 Grafana,以及使用这些工具的前提条件和优势.在本部分,将继续带您学习如何安装 Helm 以及如何使用 Prometheus ...

  6. 分布式机器学习的故事:Docker改变世界

    分布式机器学习的故事:Docker改变世界 Docker最近很火.Docker实现了"集装箱"--一种介于"软件包"和"虚拟机"之间的概念- ...

  7. C++通过文件指针获取文件大小

    目录 1. 叙述 2. 结论 1. 叙述 对于读取本地文件,很多时候需要预先知道本地文件的大小在进行读取.网上给出的方案是移动文件指针,计算文件头和文件尾的偏移,计算出文件的大小.但是我总觉得这样做可 ...

  8. Markdown 编辑器及语法使用入门指南

    一.如何打开预览? 打开在线编辑器 - 点击如图所示 - 写作预览按钮即可: 如图所示,编写下面 Markdown 语法,进行对应语法的编写,愉快的写作了! 左侧 Markdown 语法 右侧实时显示 ...

  9. 用GaussDB合理管控数据资源的几点心得

    一.摘要 项目交付中可能会遇到同时包含核心交易(OLTP)和报表分析(OLAP)的混合业务场景,其中报表分析类业务复杂度高,消耗大量系统资源,但实时性要求较低,而核心交易类业务并发较大,多为简单事务处 ...

  10. 华为云GaussDB为MetaERP“成本核算”产品“保驾护航”

    摘要:华为宣布实现了自主创新的MetaERP研发,并且完成了对旧ERP系统的全面替换,这其中,就采用了华为云GaussDB数据库特有的全密态技术,对ERP系统中的绝密数据进行加密保护,从而保障了数据的 ...