作者:正范
链接:https://kaiwu.lagou.com/course/courseInfo.htm?sid=&courseId=447&lagoufrom=noapp&wxinfo=2#/detail/pc?id=4517
通过前面的课程,相信你对 Kubernetes 中的对象有了很多了解。Kubernetes 是一个强大的容器调度系统,你可以通过一些声明式的定义,很方便地在 Kubernetes 中部署业务。
现在你一定很想尝试在 Kubernetes 中部署一个稍微复杂的系统,比如下面这个典型的三层架构:前端、后端和数据层。
(https://docs.bitnami.com/tutorials/_next/static/images/three-tier-kubernetes-architecture-28861dab09dbb6c2dd6ddb986f3a42d4.png.webp)
也许你内心里已经开始跃跃欲试,但是转念一想,事情好像没那么简单啊。你感觉到这里面要写一堆的 YAML 文件,每一层架构都至少要写 2 个 YAML 文件,写的时候还需要理解各种对象、注意各种缩进的层级关系、还要设置一堆配置参数等。这对于刚接触 Kubernetes 的人来说是一个很高的门槛,简直无法跨越。同时,对于业务交付的同学,也将是一个大灾难,因为如果缺少任何一个 YAML 文件,都会导致整个系统无法正常工作。
看到这里,你也许会想到能不能通过一种包的方式进行管理呢,类似于 Node.js 通过 npm 来管理包,Debian 系统通过 dpkg 来管理包,而 Python 通过 pip 来管理包。
那么在 Kubernetes 中, 这个答案就是Helm。
Helm 降低了使用 Kubernetes 的门槛,你无须从头开始编写应用部署文件,甚至都不需要了解 Kubernetes 中的各个对象以及相应的 YAML 语义。直接通过 Helm 就可以在自己的 Kubernetes 中一键部署需要的应用。
对于开发者而言,通过 Helm 进行打包,管理应用内部的各种依赖关系,极其方便。并且可以借助于版本化的概念,方便自身的迭代和分发。除此之外,Helm 还有一些其他强大的功能,请跟我一起开始今天 Helm 的学习之旅。
作为 CNCF 社区官方的项目,Helm 在今年四月份已经宣布毕业,这进一步彰显了 Helm 的市场接受度、生产环境采用率以及技术影响力。
我们先来理解下 Helm 中几个重要的概念。
Helm 中的几个概念
在 Helm 中,有三个非常核心的概念—— Chart、Config 和 Release。
Chart 可以理解成应用的安装包,通常包含了一组我们在 Kubernetes 要部署的 YAML 文件。一个 Chart 就是一个目录,我们可以将这个目录进行压缩打包,比如打包成 some-chart-version.tgz 类型的压缩文件,方便传输和存储。
每个这样的 Chart 包内都必须有一个 Chart.yaml 文件,类似这样:
apiVersion: v1name: redisversion: 11.0.0appVersion: 6.0.8description: Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.keywords: - redis - keyvalue - databasehome: https://github.com/bitnami/charts/tree/master/bitnami/redisicon: https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.pngsources: - https://github.com/bitnami/bitnami-docker-redis - http://redis.io/maintainers: - name: Bitnami email: containers@bitnami.com - name: desaintmartin email: cedric@desaintmartin.frengine: gotplannotations: category: Database
这个 Chart.yaml 主要用来描述该 Chart 的名字、版本号,以及关键字等信息。
有了这个 Chart,我们就可以在 Kubernetes集群中部署了。每一次的安装部署,我们称为一个 Release。在同一个 Kubernetes 集群中,可以有多个 Release。你可以将 Release 理解成是 Chart 包部署后的一个 Chart(应用)实例。
注:这个 Release 和我们通常概念中理解的“版本”有些差异。
同时,为了能够让 Chart 实现参数可配置,即 Config,我们在每个 Chart 包内还有一个 values.yaml 文件,用来记录可配置的参数和其默认值。在每个 Release 中,我们也可以指定自己的 values.yaml 文件用来覆盖默认的配置。
此外,我们还需要统一存放这些 Chart,即 Repository(仓库)。这个概念和我们以前的 yum repo 是一样的。本质上来说,Repository 就是一个 Web 服务器,不仅保存了一系列的 Chart 软件包让用户下载安装使用,还有对应的清单文件以供查询。
通过 Helm,我们可以同时使用和管理多个不同的 Repository,就像我们可以给 yum 配置多个源一样。
掌握了这些概念,我们现在再拉远视角,整体来看一下。
Helm 的安装及架构组成
首先,Helm 的安装非常简单,你可以通过如下的命令安装最新版本的 Helm 可执行文件:
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 11213 100 11213 0 0 12109 0 --:--:-- --:--:-- --:--:-- 12096Downloading https://get.helm.sh/helm-v3.3.1-darwin-amd64.tar.gzVerifying checksum... Done.Preparing to install helm into /usr/local/binPassword:helm installed into /usr/local/bin/helm
当然你也可以去官方的文档里选择合适自己的安装方式。
安装完成后,我们来查看下 Helm 的版本:
$ helm versionversion.BuildInfo{Version:"v3.3.1", GitCommit:"249e5215cde0c3fa72e27eb7a30e8d55c9696144", GitTreeState:"clean", GoVersion:"go1.14.7"}
可以看到目前我们安装的版本是 v3.3.1,这是 Helm 3 的一个版本。
其实在 Helm 3 之前,还有 Helm 2,目前还有不少人在继续使用 Helm 2 的版本。现在我们来简单了解下 Helm 2 和 Helm 3 。
Helm 2
Helm 2 于 2015 年在 KubeCon 上亮相。其架构如下图所示,是个常见的 CS 架构,由 Helm Client 和 Tiller 两部分组成。
(https://medium.com/dwarves-foundation/kubernetes-helm-101-78f70eeb0d1)
Tiller 是 Helm 的服务端, 用于接收来自 Helm Client 的请求,主要负责部署 Helm Chart、管理 Release(比如升级、删除、回滚等操作),以及在 Kubernetes 集群中创建应用。Tiller 通常部署在 Kubernetes 中,直接通过helm init就可以在 Kuberentes 集群中拉起服务。
Helm Client 主要负责跟用户进行交互,通过命令行就可以完成 Chart 的安装、升级、删除等操作。Helm Client 可以从公有或者私有的 Helm 仓库中拉取 Chart 包,通过用户指定的 Config,就可以直接传给后端的 Tiller 服务,使之在集群内进行部署。
这里,我们可以看到 Tiller 在 Helm 2 和 Kubernetes 集群中间其实起到了一个中转的作用,因此 Tiller 实际上是代替用户在 Kubernetes 集群中执行操作,所以 Tiller 在运行中往往需要一个很高的权限。这里 Tiller 存在着两大安全风险:
要对外暴露自身的端口;
自身运行过程中,跟 Kubernetes 交互需要很高的权限,这样才可以在 Kuberentes 中创建、删除各种各样的资源。
当然了,之所以有这种架构设计是由于在 Helm 2 开发的时候,Kubernetes 的 RBAC 体系还没有建立完成。Kubernetes 社区直到 2017 年 10 月份 v1.8 版本才默认采用了 RBAC 权限体系。随着 Kubernetes 的各项功能日益完善,主要是 RBAC 能力,Tiller 这个组件存在的必要性进一步降低,社区也在一直想着怎么去解决 TIller 的安全问题。
我们再来看看 Helm 3。
Helm 3
Helm 3 是在 Helm 2 之上的一次大更改,于 2019 年 11 月份正式推出。相比较于 Helm 2, Helm 3 简单了很多,移除了 Tiller,只剩下一个 Helm Client。在使用中,你只需要这一个二进制可执行文件即可,使用你当前用的 kubeconfig 文件,即可在 Kubernetes 集群中部署 Chart、管理 Release。
至此,Helm 2 开始要退出历史的舞台了。目前 Helm 社区官方也逐步开始暂停维护 Helm 2,最终的 Bugfix 修复截止到今年的 8 月份,版本号是 v2.16.10,而安全相关的 patch 会继续支持,直到 今年的 11 月份。
如果你还在使用 Helm 2,建议你尽快切换到 Helm 3 上来。Helm 社区也提供了相关的插件,帮助你从 Helm 2 迁移到 Helm 3 中,可以参考这篇 Helm 的官方迁移文档 (https://helm.sh/docs/topics/v2_v3_migration/),这里我就不再赘述了。
通过这个版本迭代的过程,你应该也清楚了 Helm 的原理,对它更加熟悉了,接下来我们一起动手实践看看。
如何创建和部署 Helm Chart
创建一个 Chart 很简单,通过helm create的命令就可以创建一个 Chart 模板出来:
$ helm create hello-worldCreating hello-world
我们现在来看看这个 Chart 的目录里面有什么:
$ tree ./hello-world./hello-world├── Chart.yaml├── charts├── templates│ ├── NOTES.txt│ ├── _helpers.tpl│ ├── deployment.yaml│ ├── hpa.yaml│ ├── ingress.yaml│ ├── service.yaml│ ├── serviceaccount.yaml│ └── tests│ └── test-connection.yaml└── values.yaml3 directories, 10 files
这里面包含了我们上面讲的 Chart.yaml 和 values.yaml。
先看看这里 Chart.yaml 的内容:
apiVersion: v2name: hello-worlddescription: A Helm chart for Kubernetes# A chart can be either an 'application' or a 'library' chart.## Application charts are a collection of templates that can be packaged into versioned archives# to be deployed.## Library charts provide useful utilities or functions for the chart developer. They're included as# a dependency of application charts to inject those utilities and functions into the rendering# pipeline. Library charts do not define any templates and therefore cannot be deployed.type: application# This is the chart version. This version number should be incremented each time you make changes# to the chart and its templates, including the app version.# Versions are expected to follow Semantic Versioning (https://semver.org/)version: 0.1.0# This is the version number of the application being deployed. This version number should be# incremented each time you make changes to the application. Versions are not expected to# follow Semantic Versioning. They should reflect the version the application is using.appVersion: 1.16.0
可以看到,这里 Chart 的名字就是我们 Chart 所在目录的名字。你在使用的时候,就可以在这个文件里面添加 keyword,以及 annotation,方便后续查找和分类。
values.yaml 里面包含了一些可配置的参数,你可以根据自己的需要进行添加,或者修改默认值等。
这个目录下面有个charts文件夹,主要用来放置一些子 Chart 包,也可以是 tar 包、 Chart 目录。你可以根据自己的场景,决定需不需要放置子 Chart 包。
这个目录里面还有个templates文件夹,这个文件夹里面的文件是一些模板文件,Helm 会根据values.yaml的参数进行渲染,然后在 Kubernetes 集群中创建出来。
你可以根据自己的需要,在这个templates目录下,添加和更改 yaml 文件。
你这样创建好了一个 Chart 包后,如果想要更改其中一些参数,可以将它们放到其他的文件里面,比如 myvalues.yaml 文件。
然后通过helm install命令,你就可以在 Kubernetes 集群里面部署 hello-world 这个 Chart 包:
helm install -f myvalues.yaml hello-world ./hello-world
或者,你可以通过添加 Repository 直接使用别人的 Chart,使用helm search来查找自己想要的 Chart:
$ helm repo add brigade https://brigadecore.github.io/charts"brigade" has been added to your repositories$ helm search repo brigadeNAME CHART VERSION APP VERSION DESCRIPTIONbrigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube...brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for...brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigadebrigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetesbrigade/brigade-project 1.0.0 v1.0.0 Create a Brigade projectbrigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes
更多 Helm 的使用命令,可以参考官方的使用文档,使用起来非常简单就不占用篇幅了。
写在最后
目前 Helm 是 CNCF 基金会旗下已经“毕业”的独立的项目。它简化了 Kubernetes 应用的部署和管理,大大提高了效率,越来越多的人在生产环境中使用 Helm 来部署和管理应用,所以我在这里用一个课时来专门讲解它的原理和使用,想让你在使用 Kubernetes 时如虎添翼。
往期文章
Kubernetes部署篇
Kubernetes 1.18.2集群部署 (单Master)+docker—kubeadm方式
Kubernetes 1.18.2集群部署 (多Master)+docker—kubeadm方式
Kubernetes 1.18.2集群部署 (多Master)+docker—二进制方式
Kubernetes 1.18.2集群部署 (单Master)+docker—shell脚本方式
Kubernetes 1.19.0集群部署 (多Master)+docker—kubeadm方式
Kubernetes 1.19.0集群部署 (多Master)+docker—二进制方式
Kubernetes 一条命令快速部署 Kubernetes 高可用集群—sealos
Kubernetes 一条命令快速部署 Kubernetes 高可用集群—kubei
Kubernetes Harbor v2.0.0私有镜像仓库部署
Kubernetes Harbor v2.0.2高可用私有镜像仓库部署
Kubernetes kubectx/kubens切换context和namespace
Kubernetes kubeadm更新一个10年有效期的证书
Kubernetes kubeadm初始化kubernetes集群延长证书过期时间
Kubernetes kubeadm升级集群
Kubernetes kubeadm基础使用
Kubernetes基础篇
Kubernetes 是什么?
Kubernetes 基础概念
Kubernetes 从零开始了解
Kubernetes 快速了解Kubernetes
Kubernetes kubectl命令
Kubernetes kubectl常用命令
Kubernetes kubectl常用命令大全
Kubernetes 创建、更新应用
Kubernetes 资源清单
Kubernetes Pod状态和生命周期管理
Kubernetes Pod Controller
Kubernetes ReplicaSet Controller
Kubernetes Deployment Controller
Kubernetes DamonSet Controller
Kubernetes Job、CronJob Controller
Kubernetes HPA Controller
Kubernetes HPA Controller 使用详解
Kubernetes KEDA基于Kubernetes事件驱动的自动缩放
Kubernetes 服务发现—Service
Kubernetes 内部服务发现—Coredns
Kubernetes 外部服务发现—Traefik ingress
Kubernetes 外部服务发现—Nginx Ingress Controller
Kubernetes 存储卷—Volumes
Kubernetes 存储卷—部署NFS服务器,供给静态pv和动态pv
Kubernetes 存储卷—PV和PVC的状态变化
Kubernetes 特殊存储卷—Secret和ConfigMap
Kubernetes StatefulSet Controller
Kubernetes 认证、授权和准入控制
Kubernetes dashboard认证访问-更新
Kubernetes 网络模型和网络策略
Kubernetes 网络原理解析
Kubernetes 网络插件-flannel
Kubernetes 网络插件-calico
Kubernetes Pod资源调度
Kubernetes 资源指标和集群监控
Kubernetes 容器云平台技术落地方案
Kubernetes v1.19.0 正式发布
Kubernetes Ratel自动生成yaml文件
Kubernetes 部署策略详解
Kubernetes 集群规模应该有多大?
Kubernetes 集群备份/恢复velero实战
Kubernetes 集群备份/恢复etcd数据实战
Kubernetes基础篇—Kubernetes 原理剖析与实战应用
Kubernetes 如何深入掌握 Kubernetes
Kubernetes 如何火起来的
Kubernetes 架构为什么是这样的
Kubernetes 集群搭建
Kubernetes 是如何搞定“不可变基础设施”的
Kubernetes Pod:最小调度单元的使用进阶及实践
Kubernetes 无状态应用:剖析K8S业务副本及水平扩展底层原理
Kubernetes 有状态应用:K8S如何通过 StatefulSet 支持有状态应用
Kubernetes 配置管理:K8S管理业务配置方式有哪些
Kubernetes 存储类型:如何挑选合适的存储插件
Kubernetes 存储管理:怎样对业务数据进行持久化存储
Kubernetes Service:轻松搞定服务发现和负载均衡
Kubernetes基础篇—Kubernetes 入门到实战
Kubernetes 入门到实战(一)俯瞰kubernetes全貌
Kubernetes 入门到实战(二)kubeadm部署kubernetes集群
Kubernetes 入门到实战(三)kubernetes快速入门
Kubernetes 入门到实战(四)kubernetes dashboard图形界面
Kubernetes 入门到实战(五)深入浅出详解Pod
Kubernetes 入门到实战(六)资源管理和服务质量
Kubernetes 入门到实战(七)深入玩转pod调度
Kubernetes 入门到实战(八)Pod健康检查机制
Kubernetes 入门到实战(九)初识Pod存储管理
Kubernetes 入门到实战(十)深入学习持久化存储PV和PVC
Kubernetes 入门到实战(十一)深入学习Deployment控制器
Kubernetes 入门到实战(十二)详解DaemonSet控制器
Kubernetes 入门到实战(十三)一次性任务Job和周期任务
Kubernetes 入门到实战(十四)statefulset(待续)
Kubernetes 入门到实战(十五)services的实现(待续)
Kubernetes 入门到实战(十六)基于nginx ingress实现服务暴露
Kubernetes 入门到实战 (十七) 基于haproxy实现ingress服务暴露
Kubernetes 入门到实战 (十八) 使用metric-server让HPA弹性伸缩愉快运行
Kubernetes 入门到实战 (十九) prometheus提供完备监控系统
Kubernetes应用部署篇
Kubernetes 部署WordPress博客
Kubernetes 部署Nginx+php-fpm+MySQL并运行Discuz
Kubernetes 使用StatefulSet部署MySQL高可用集群
Kubernetes 使用StatefulSet部署MongoDB高可用集群
Kubernetes 包管理工具—Helm2.13安装和使用
Kubernetes Helm2部署gitlab私有代码仓库
Kubernetes Helm2部署MySQL数据库
Kubernetes 包管理工具—Helm3.3安装和使用
Kubernetes Helm3部署MySQL数据库
Kubernetes Helm3部署kubernetes-dashboard
Kubernetes Helm3部署nginx-ingress NodePort方式
Kubernetes Helm3部署nginx-ingress LoadBalancer方式
Kubernetes监控篇
Kubernetes 部署Prometheus+Grafana+Alertmanager监控告警系统
Kubernetes Prometheus监控Nginx
Kubernetes Prometheus监控MySQL
Kubernetes Prometheus监控tomcat
Kubernetes 部署kube-prometheus监控告警系统
Kubernetes kube-prometheus中添加自定义监控项-监控etcd
Kubernetes kube-prometheus监控指标targets
Kubernetes kube-prometheus配置kubernetes-cadvisor服务自动发现
Kubernetes kube-prometheus Configuration信息
Kubernetes kube-prometheus中添加自定义监控项-监控MySQL
Kubernetes Grafana匿名登录/密码登录Kubernetes
Kubernetes Grafana迁移(导出导入)dashboard
Kubernetes Grafana数据持久化
Kubernetes日志篇
Kubernetes 使用Elastic Stack构建Kubernetes全栈监控
Kubernetes 日志架构
Kubernetes 使用 Loki 进行日志监控和报警
Kubernetes故障排除篇
Kubernetes 删除namespace时卡在Terminating状态
Kubernetes deploy,rs,sts Mismatch 的处理
Kubernetes master机器文件系统故障恢复过程
Kubernetes 如何修改容器时间而不改变宿主机时间?
Kubernetes面试问题篇
Kubernetes IT运维面试问题总结-简述Etcd、Kubernetes、Lvs、HAProxy等
Kubernetes 50个必须了解的Kubernetes面试问题
Kubernetes 面试题汇总1
Kubernetes 面试题汇总2