vlambda博客
学习文章列表

K8s 应用的部署利器:初识 Helm

本文由我从英文原文翻译而来,英文原作者也是我。感兴趣的朋友可点击文末的“阅读原文”查看 Medium 平台上的英文原文。

在云原生技术席卷的数字化时代,Kubernetes(亦简称为 K8s)是有关云原生话题的焦点之一。云原生解决方案层出不穷,无论在开发还是生产中都越来越多地适配诸如 K8s 等容器环境。然而,K8s 的学习成本较高,在一个 K8s 集群中部署应用往往并非易事。要知道,容器化的应用通常包含多个组件,它们之间相互松耦合,沟通方式也不尽相同。

以 K8s 具体的资源对象来说,我们可能需要 Deployment 运行主要组件,PersistentVolume、PersistentVolumeClaim 和 StorageClass 提供持久化存储,Service 来暴露应用,Secret 和 ConfigMap 来存储各类信息,各种基于 RBAC 的 Role、RoleBinding 和 ServiceAccount 来管理用户与应用权限,甚至是 CustomResourceDefinition 来创建特殊资源等。所有的这些资源对象都需要自己的 YAML 配置文件。考虑到工作效率与维护成本,每次都手动创建 YAML 文件并进行维护并不现实。那么,是否有一种方式,可以将一个应用的所有部分统一管理和维护呢?

Helm 正好满足了这样的需求。

Helm 2015 年由 Deis 开发,2018 年 6 月进入 CNCF 孵化,2020 年 4 月正式从 CNCF 毕业。简单来讲,Helm 是一个 K8s 开源软件包管理工具,有点像 Linux 的包管理工具(例如 YUM)。使用 Helm 在 K8s 集群上安装应用时,你不需要去手动创建一个个 YAML 文件,而是直接告诉 Helm 你要安装哪个应用,通过对应的 Helm 命令将应用整体安装,Helm 知道该应用包括哪些资源对象的 YAML 文件, 它们统一存储在一个配置文件包中,即 Helm Chart。根据此 Chart,Helm 会帮你搞定后续的升级或卸载等。

做个简单的类比,你在 iPhone 上安装游戏时会去分别下载游戏的地图包、人物包或声音包,然后再一起安装吗?当然不会。去 App Store 上搜索应用,点一个按钮就能安装或升级,这才是通常的做法。

从这个角度上来说,Helm 有点像 K8s 的应用商店,虽然没有 iPhone 的 App Store 里面那么生动的宣传视频和文案,但用户安装应用的逻辑类似。实际上,在执行 Helm 命令时,你可以自定义一些参数(例如副本数和 PersistenVolume 的大小等),或许这也是 Helm 比 App Store 更高级的地方😂。

Helm 一般可用来:

  1. 在 K8s 集群上安装应用。
  2. 升级应用。
  3. 回滚应用版本。
  4. 卸载应用。

Helm 能做到这些功能的主要原因是它可以识别执行对应操作需要修改 Chart 中的哪些配置文件。

安装 Helm

Helm 可以安装在 Linux,Windows 或 Mac 操作系统上,具体可以参考 Helm 的官方文档[1]。这里我简单说几种在 Linux 上安装 Helm v3 的方式。

  1. 通过脚本:

    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.sh
  2. 通过 Snapcrafters 社区的 Snap:

    sudo snap install helm --classic
  3. 通过 Apt (Debian/Ubuntu):

    curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
    sudo apt-get install apt-transport-https --yes
    echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
    sudo apt-get update
    sudo apt-get install helm

由于要使用 Helm 在 K8s 集群上安装应用,我推荐使用 KubeKey[2] 创建 K8s 集群。KubeKey 是一个轻量级的云原生工具,在搭建 K8s 集群时会默认安装 Helm v3。如果你还没用过 KubeKey,可以去看看我的文章 KubeKey: A Lightweight Installer for Kubernetes and Cloud Native Addons[3]

在介绍 Helm 组件之前,这里先简单说一下 Helm 的版本。随着 K8s 的演变,Helm 自身也更新了很多。Helm v2 在 2016 年 11 月发布,3 年后 Helm v3 也正式推出。那么,我们该如何选择?如果你安装 Helm v2,则还要在 K8s 集群上安装 Tiller。Tiller 相当于一个介于用户和 K8s API Server 间的媒介,帮助两方沟通,即你先使用 Helm 命令和 Tiller 沟通,然后 Tiller 再与 K8s 集群连接,从而执行相关的操作。Tiller 本身权限很大,这会引起很多安全问题,使得任何用户都能操作集群资源。在 K8s 出现 RBAC 等相关资源后,Helm v3 中便不再使用 Tiller。感兴趣的小伙伴可以去看看 Helm 官网上的这篇文章[4],了解 Helm v3 中的主要更新。

Helm 组件

Helm 通过 Chart 来安装、管理 K8s 应用,本质上 Chart 是一组与应用相关文件的集合,让 Helm 可以根据这些文件在 K8s 上部署必要的资源。

要想获取不同应用的 Helm Chart 并安装,我们需要先添加存放这些 Chart 的仓库。Helm Chart 由应用开发者提供,他们将应用打包好后上传至 Artifact Hub[5] 以便所有人使用。

一般来说,一个应用的 Helm Chart 包含以下文件或文件夹,部分非必需:

  • templates 文件夹:包含应用所使用的模板文件。其中部分字段的值并非直接写出,而是引用 values.yaml 文件中的预设配置。
  • values.yaml:包含应用的预设值,用户可以根据需要自定义这些配置。
  • Chart.yaml:此 Chart 包本身的基本信息。
  • crds 文件夹(非必需):自定义资源。
  • LICENSE(非必需):Chart 的许可证信息。
  • charts 文件夹:安装此应用所需要的一些依赖文件等。
  • README.md(非必需):安装和使用该应用的用户指南。

这里我们着重看一下前三项。

templates 文件夹

templates 文件夹下存放着创建应用所需要的各种 K8s 配置文件,例如 Deployment 和 Service 等。以下是一个简单的 Deployment 示例:

# deployment.yaml

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: nginx-deployment  
  labels:  
    app: nginx  
spec:  
  replicas: {{ .Values.replicaCount }}  
  selector:  
    matchLabels:  
      app: nginx  
  template:  
    metadata:  
      labels:  
        app: nginx  
    spec:  
      containers:  
      - name: nginx  
        image: {{ .Values.image.registry }}/nginx:{{ .Values.dockerTag }}  
        imagePullPolicy: {{ .Values.pullPolicy }}  
        ports:  
        - containerPort: 80

如果你熟悉 K8s 各类资源的 YAML 文件结构,相信你对这样一个文件并不陌生。与一般的 YAML 文件不同的是,我们可以看到 replicasimage 以及 imagePullPolicy 这三个字段的值没有直接写出,而是以模板的形式放在括号内,Helm 在读取这些文件时会根据这些模板寻找 values.yaml 中所定义的值。这么一来,后续我们在创建应用前可以对这些参数的值在同一个文件中统一管理,不用一个个修改 YAML 文件。

values.yaml

如上文所说,values.yaml 文件中存储着 templates 文件夹下各个 YAML 文件所引用的值。开发者们会提前定义这些值的默认参数,后续在部署应用前,我们可以按照自己的需求进行修改。以下是一个 values.yaml 示例文件:

# values.yaml

replicaCount: 1  

image:  
  registry: example.io  

dockerTag: latest  

pullPolicy: Always

要让 Helm 跳过 values.yaml 文件中的配置,使用你所定义的参数来安装应用,我们可以采用以下三种方式之一:

  1. 在命令中添加 --set <字段名>=<字段值> 参数,例如 --set replicaCount=2。要安装应用,使用 helm install 命令,格式为 helm install [NAME] [CHART] [flags]
  2. 创建新的 values.yaml 文件(例如 new-values.yaml),在此新文件中添加你想要自定义的字段和值,然后在安装命令中添加 --values new-values.yaml
  3. 使用 helm pull 命令(例如 helm pull --untar bitnami/nginx)把 Chart 包整体下载到本地,手动修改 values.yaml 中的参数值,然后执行安装。请注意,使用该方法需要在执行安装命令时指定本地路径,例如 helm install release-name ./nginx

有关 Helm 各类命令的使用,我会在另外一篇文章中单独说明。

Chart.yaml

此文件包括 Helm Chart 本身的基本信息,以下是一个示例文件:

# Chart.yaml

apiVersion: v2
appVersion: 1.xx.x
dependencies:
- name: common
  repository: https://charts.bitnami.com/bitnami
  tags:
  - bitnami-common
  version: 1.x.x
description: NGINX Open Source is a web server that can be also used as a reverse
  proxy, load balancer, and HTTP cache. Recommended for high-demanding sites due to
  its ability to provide faster content.
home: https://github.com/bitnami/charts/tree/master/bitnami/nginx
icon: https://bitnami.com/assets/stacks/nginx/img/nginx-stack-220x234.png
keywords:
- nginx
- http
- web
- www
- reverse proxy
maintainers:
- email: [email protected]
  name: Bitnami
name: nginx
sources:
- https://github.com/bitnami/bitnami-docker-nginx
- https://www.nginx.org
version: xx.x.x
  • apiVersion:Helm v3 中此值为 v2。在 Helm v2 的时候不存在,用于区别 Chart 可使用的 Helm 版本。如果 apiVersion 字段未指定,大概率这个 Chart 要通过 Helm v2 使用。

  • appVersion:应用版本。

  • dependencies:部署该应用要需要的依赖,比如其他的 Chart。

  • description:描述应用的基本信息。

  • home:此应用的主页。

  • icon:此应用的图标。

  • keywords:描述此应用的关键词,帮助用户快速在仓库中搜索。

  • maintainers:应用的维护者信息。

  • name:Chart 的名字。

  • sources:与此 Chart 相关的一些资源,例如源代码网页等。

  • version:Chart 本身的版本,用于记录 Chart 包的改变。

关于 Helm:我们还需要知道什么

本文主要介绍有关 Helm 的基础知识以及安装。我会在其他文章中介绍 Helm 的常用命令以及如何编写 Helm 的模板文件,以深入了解 Helm。

参考资料

Helm 文档[6]

CNCF Helm Project Journey Report[7]

相关链接

[1]

Helm 官方文档: https://helm.sh/docs/intro/install/

[2]

KubeKey: https://github.com/kubesphere/kubekey

[3]

KubeKey: A Lightweight Installer for Kubernetes and Cloud Native Addons: https://dzone.com/articles/kubekey-a-lightweight-installer-for-kubernetes-and

[4]

Helm v3 更新: https://helm.sh/docs/faq/changes_since_helm2/

[5]

Artifact Hub: https://artifacthub.io/

[6]

Helm 官方文档: https://helm.sh/docs/

[7]

CNCF Helm Project Journey Report: https://www.cncf.io/reports/helm-project-journey-report/


注:👇 点击“阅读原文”查看我发在 Medium 上的英文原文。