应用管理Helm介绍

865 阅读7分钟

应用管理

众所周知Kubernetes(简称 K8s)是一个能够部署和管理容器的平台,然而,它还没有抽象到“应用”这一层概念:一个应用往往由多个 K8s 资源(Deployment、Service、ConfigMap 等等)组成。为了管理部署应用,我们需要一个能把这些资源关系整合起来管理的工具,这也就诞生了helm。 应用管理又有以下几个层面:

  • 应用包定义
  • 应用依赖管理
  • 应用版本管理
  • 应用运行管理

举个例子: 要在k8s上部署一个java web应用,需要两个YAML文件:

  • webdeploy.yaml,用于描述Java Web程序的K8s Deployment
  • websvc.yaml,用于描述的程序访问的入口的 K8s Service

然后,我们需要执行两次 kubectl apply -f 把这些 YAML 文件都提交给 K8s 来负责运行和管理。这里只是简单的一个java web应用,实际上一个应用还存在许多依赖关系,可能涉及到非常多的yaml文件,要怎么样去管理这个应用对应的所有 k8s 资源呢,helm应运而生。

helm简介

Helm是可简化Kubernetes应用程序安装和管理的工具。把k8s比作操作系统的话,Helm就相当于apt / yum。

  • Helm渲染template并直接与Kubernetes API通信
  • Helm可在笔记本电脑,CI/CD或您希望在其上运行的任何位置运行。
  • Charts是包含至少两项内容的Helm软件包:
  • 软件包说明定义(Chart.yaml)
  • 一个或多个template,其中包含Kubernetes清单文件
  • Charts可以存储在本地磁盘或者仓库(harbor等),也可以从远程仓库中获取(例如Debian或RedHat软件包)

那helm是怎么跟应用管理联系起来的呢,我们来看一个chart的目录结构:

.
`-- myqpp                           # myapp Chart目录
    |-- Chart.yaml                  # 描述这个 Chart 的相关信息、包括名字、描述信息、版本等
    |-- charts                      # myapp这个 charts 依赖的其他charts放这个目录下
    |-- templates                   # 模板目录
    |   |-- NOTES.txt               # Chart部署到集群后的一些信息,例如:如何使用、列出缺省值等
    |   |-- _helpers.tpl            # 以 _ 开头的文件不会部署到 k8s 上,可用于定制通用信息
    |   |-- deployment.yaml         # deployment模板文件
    |   |-- ingress.yaml            # ingress模板文件
    |   |-- service.yaml            # service模板文件
    |   |-- serviceaccount.yaml     # service account 模板文件
    |   `-- tests
    |       `-- test-connection.yaml
    `-- values.yaml                 # 模板的参数值文件,这些参数值会在安装时应用到template中生成部署文件

从charts结构中可以看出来,结构文件中包含了应用的定义,应用依赖关系的定义,并且在使用helm install 安装一个应用时需要指定一个或者自动生成一个release name,有了release name就可以对应用进行版本管理,当然也可以对应用进行升级,回滚等操作。

helm进化史

  1. helm v1:Helm在2015年始于现在被称为Helm Classic的一个Deis项目,最初被KubeCon引入。
  2. helm v2:2016年与Kubernetes Deployment Manager的GCS工具合并,并被转移到Kubernetes下。由于代码库的合并,当年晚些时候发布了Helm 2.0。并在最终的Helm 2.0版本中将GCS工具保留的功能特性重命名为Tiller。 2018年6月,Helm被纳入CNCF项目。
  3. helm v3:Helm 3于2019年11月正式发布,当Helm 3开发周期开始时,Tiller就被移除,使Helm更接近其最初作为客户端工具的愿景(开源社区的神奇力量)。

helm使用

参考官网安装helm3:helm.sh/docs/intro/…

helm相关命令:

Available Commands:
  completion  # 为指定的shell生成自动完成脚本(bash或zsh)
  create      # 创建一个具有给定名称的新 chart
  dependency  # 管理 chart 的依赖关系
  env         # 打印 Helm 客户端环境信息
  get         # 下载一个命名 release
  help        # 列出所有帮助信息
  history     # 获取 release 历史
  install     # 安装 chart
  lint        # 对 chart 进行语法检查
  list        # releases 列表
  package     # 将 chart 目录打包成 chart 包用于分享
  plugin      # 添加列表或删除 helm 插件
  pull        # 从仓库下载 chart 并(可选)将其解压缩到本地目录中
  repo        # 添加列表删除更新和索引 chart 存储库
  rollback    # 将版本回滚到以前的版本
  search      # 在 chart 存储库中搜索关键字
  show        # 显示一个chart的相关信息
  status      # 显示指定 release 的状态
  template    # 本地渲染模板
  test        # 测试一个 release
  uninstall   # 删除一个指定名臣的release
  upgrade     # 升级一个 release
  verify      # 验证给定路径上的 chart 是否已签名且有效
  version     # 打印helm版本信息

查看版本:

[20:19:28] Helm $ helm version
version.BuildInfo{Version:"v3.0.1", GitCommit:"7c22ef9ce89e0ebeb7125ba2ebf7d421f3e82ffa", GitTreeState:"clean", GoVersion:"go1.13.4"}

新建一个chart,使用helm create的话,它会提供一个大概的初始化框架:

[17:10:57] Helm $ helm create testapp
Creating testapp
[17:11:29] Helm $ tree
.
`-- testapp
    |-- Chart.yaml
    |-- charts
    |-- templates
    |   |-- NOTES.txt
    |   |-- _helpers.tpl
    |   |-- deployment.yaml
    |   |-- ingress.yaml
    |   |-- service.yaml
    |   |-- serviceaccount.yaml
    |   `-- tests
    |       `-- test-connection.yaml
    `-- values.yaml

.....

helm vs operator

有同学可能要说了:使用operator它不香吗?为啥还用helm?

Operator本质上是针对特定的场景去做有状态服务,或者说针对拥有复杂应用的应用场景去简化其运维管理的一种思路。Helm的话,它其实是一个比较普适的工具,想法也很简单,就是把K8S资源模板化,方便共享,然后在不同的配置中重用。

Operator是将运维人员对软件操作的知识给代码化,同时利用Kubernetes强大的抽象来管理大规模的软件应用。 Operator使用了Kubernetes的自定义资源扩展API机制,如使用CRD(CustomResourceDefinition)来创建。Operator通过这种机制来创建、配置和管理应用程序。

其实Operator做的东西Helm大部分也可以做。用Operator去监控更新etcd的集群状态,也可以用定制的Chart做同样的事情。只不过你可能需要一些更复杂的处理而已,例如在etcd没有建立起来时候,你可能需要一些init Container去做配置的更新,去检查状态,然后把这个节点用对应的信息给拉起来。删除的时候,则加一些PostHook去做一些处理。所以说Helm是一个更加普适的工具。两者甚至可以结合使用,比如stable仓库里就有etcd-operator chart。

helm是为了配置分离,更多的是作为一个包管理工具,operator则是针对复杂应用的自动化管理。如果把helm比作apt、yum,operator就是systemd。

可以预见Helm将成为云原生应用管理炽手可热的工具。

helm vs kustomize

先说说kustomize: kustomize git仓库的描述是这样的:

Customization of kubernetes YAML configurations

很容易看得出来kustomize的重点在于kubernetes YAML配置管理,再来看看一个app在kustomize中的目录结构:

~/myApp
├── base
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── development
    │   ├── cpu_count.yaml
    │   ├── kustomization.yaml
    │   └── replica_count.yaml
    └── production
        ├── cpu_count.yaml
        ├── kustomization.yaml
        └── replica_count.yaml

kustomize 是通过描述文件的叠加覆盖,来生成完整的部署时用的Yaml,并通过build来进行部署,比如上面的myApp在部署开发环境和生产环境时可以选择不同的overlays进行叠加覆盖。

helm 与 kustomize的区别: 工作流程上的区别: Helm 的基础流程比较瀑布:定义 Chart->填充->运行。 Kustomize 的用法比较迭代:Base 和 Overlay 都是可以独立运作的,可以通过overlay进行增加新对象,或者对编写 Base 时未预料的内容进行变更覆盖。

例如我们定义了一个很基础的应用,由 Deployment + Service 组成,如果后续部署中需要完成两个变更:

  • 新建 Ingress 对象
  • 修改镜像地址/名称/TAG

在 Helm 中需要:

  • 在 Chart 中加入对 Ingress 的定义
  • 用变量控制 Ingress 是否进行渲染
  • Ingress 模板应该包含特定的主机名、注解等变量
  • 把镜像也定义成变量
  • 在 Values.yaml 中对这些变量进行赋值。

而在 Kustomize 中:

  • 无需对 Base 进行修改
  • 直接在新的 Overlay 中写入 Ingress Resource 使用内置的 image transformer 替换原有镜像

总体来说: Helm针对复杂型应用(比如istio)以及处理各种依赖来说非常实用,Chart相对固定是一种静态管理,非常适合对外整体交付(比如应用整体迁移到其他k8s集群)。 Kustomize从目录结构中就可以看出来,管理的是变更的应用(生产环境,预发布环境,测试环境不同配置),可以随时fork出一个新版本并推到新的环境,是一个相对动态的管理,正是这种动态的管理也非常适合集成到devops(CI/CD)的流程中。

Helm与Kustomize由于致力解决的问题不同,所以他们并不是竞争者。

参考

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

helm手册:whmzsu.github.io/helm-doc-zh…

Kustomize:github.com/kubernetes-…