共计 7461 个字符,预计需要花费 19 分钟才能阅读完成。
作者:王易可(楚岳)
背景
Helm 是云原生畛域被宽泛采纳的客户端利用打包和部署工具,其简洁的设计和易用的体验失去了用户的认可并造成了本人的生态,到现在已有近万个利用应用 Helm Chart 的形式打包。Helm 的设计理念足够简洁,甚至能够演绎为以下两条:
1. 对简单的 Kubernetes API 做打包和模板化,形象并简化为大量参数。
2. 给出利用生命周期解决方案:制作、上传(托管)、版本化、散发(发现)、部署。
这两条设计准则保障了 Helm 足够灵便,同时也足够简略,可能涵盖全副的 Kubernetes API,很好的解决了云原生利用一次性交付的场景。然而对于具备肯定规模的企业而言,应用 Helm 做软件的继续交付就呈现了不小的挑战。
Helm 继续交付的挑战
Helm 设计之初就为了保障其简略易用,放弃了简单的组件编排。所以在利用部署时,Helm 是一股脑将所有的资源交付到 Kubernetes 集群中,冀望通过 Kubernetes 面向终态的自愈能力,自动化的解决利用的依赖和编排问题。 这样的设计在首次部署时可能没有问题,然而对于具备肯定规模的企业生产环境而言,就显得过于理想化了。
一方面,在利用降级时一股脑将资源全副更新很容易因为局部服务短暂的不可用造成整体的服务中断;另一方面,如果软件存在 BUG,也无奈及时回滚,很容易将影响范畴扩充,难以管制。在某些更重大的场景下,如存在生产环境局部配置被运维人工批改过,因为 Helm 一次性部署会将原有的批改全副笼罩,而 Helm 之前的版本与生产环境可能并不统一,导致回滚也无奈复原,造成更大面积的故障。
由此可见,当具备肯定规模当前,软件在生产环境的灰度和回滚的能力极其重要,而 Helm 本身并不能保障足够的稳定性。
如何针对 Helm 做金丝雀公布?
通常状况下,一个谨严的软件降级过程会听从相似如下流程:大抵分成三个阶段,第一阶段降级大量(如 20%)的实例,并切换大量流量到新版本,实现这个阶段后先暂停降级。通过人工确认之后持续第二个阶段,降级更大比例(如 90%)的实例和流量,再次暂停期待人工确认。最初阶段将全量降级到新版本并验证结束,从而实现整个公布过程。如果降级期间发现包含业务指标在内的任何异样,例如 CPU 或 memory 异样使用率升高或申请 500 日志过多等状况,能够疾速回滚。
下面就是一个典型的金丝雀公布的场景,那么针对 Helm Chart 利用,咱们该如何实现下面这个流程呢?业界的典型做法通常有如下两种:
- 批改 Helm Chart,将工作负载变成两份,并别离暴露出不同的 Helm 参数,在公布时一直批改两份工作负载的镜像、实例数和流量比例,从而实现灰度公布。
- 批改 Helm Chart,将原先的根底工作负载批改为具备同样性能然而具备灰度公布能力的自定义工作负载,并暴露出 Helm 参数,在公布是操纵这些灰度公布的 CRD。
这两个计划都很简单,有不小的革新老本,尤其是 当你的 Helm Chart 是第三方组件无奈批改或本身不具备保护 Helm Chart 能力时,这些办法都是不可行的。 即便真的去革新了,相比于原先简略的工作负载模式,也存在不小的稳定性危险。究其原因,还是在于 Helm 自身的定位只是一个包管理工具,设计时并不思考灰度公布、也不针对工作负载做治理。
事实上,当咱们跟社区的大量用户深刻交换当前,咱们发现大多数用户的利用并不简单,类别都是诸如 Deployment、StatefulSet 这些经典的类型。所以,咱们通过 KubeVela 弱小的插件机制,联结 OpenKruise 社区 [ 1] 做了一款针对这些限定类型的金丝雀公布插件。这款插件帮忙你不做任何迁徙革新,轻松实现 Helm Chart 的灰度公布。 不仅如此,如果你的 Helm Chart 比较复杂,你齐全能够针对你的场景定制一个插件,取得同样的体验。
上面咱们通过一个理论的例子(以 Deployment 工作负载为例),手把手带你感受一下残缺的流程。
应用 KubeVela 做金丝雀公布
筹备环境
- 装置 KubeVela
curl -fsSl https://static.kubevela.net/script/install-velad.sh | bash
velad install
查看文末文档 1 [ 2] 以理解更多装置细节。
- 启用相干的 addon
vela addon enable fluxcd
vela addon enable ingress-nginx
vela addon enable kruise-rollout
vela addon enable velaux
在这一步中,启动了以下几个插件:
1) fluxcd 插件帮忙咱们具备 helm 交付的能力;
2) ingress-nginx 插件用于提供金丝雀公布的流量治理能力;
3) kruise-rollout 提供金丝雀公布能力;
4) velaux 插件则提供界面操作和可视化。
- 将 nginx ingress-controller 的端口映射到本地
vela port-forward addon-ingress-nginx -n vela-system
首次部署
通过执行上面的命令,第一次公布 helm 利用。在这一步中,咱们通过 vela 的 CLI 工具部署,如果你相熟 Kubernetes,也能够通过 kubectl apply 部署,成果完全相同。
cat <<EOF | vela up -f -
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: canary-demo
annotations:
app.oam.dev/publishVersion: v1
spec:
components:
- name: canary-demo
type: helm
properties:
repoType: "helm"
url: "https://wangyikewxgm.github.io/my-charts/"
chart: "canary-demo"
version: "1.0.0"
traits:
- type: kruise-rollout
properties:
canary:
# The first batch of Canary releases 20% Pods, and 20% traffic imported to the new version, require manual confirmation before subsequent releases are completed
steps:
- weight: 20
# The second batch of Canary releases 90% Pods, and 90% traffic imported to the new version.
- weight: 90
trafficRoutings:
- type: nginx
EOF
在下面的例子中,咱们申明了一个名为 canary-demo 的利用,其中蕴含一个 helm 类型的组件(KubeVela 也反对其余类型的组件部署),在组件的参数中蕴含 chart 的地址以及版本等信息。
另外,咱们还为这个组件申明了 kruise-rollout 的运维特色,这个就是 kruise-rollout 这个插件装置后具备的能力。其中能够指定 helm 的降级策略,第一个阶段先降级 20% 的实例和流量,通过人工确认之后再降级 90%,最初全量升到最新的版本。
须要留神的是,为了演示成果直观(体现版本变动),咱们专门筹备了一个 chart [ 3]。该 helm chart 的主体蕴含一个 Deployment 和 Ingress 对象,这是 helm chart 制作时最通用的场景。如果你的 helm chart 同样具备上述的资源,也一样能够通过这个例子进行金丝雀的公布。
部署胜利之后,咱们通过上面的命令拜访你集群内的网关地址,将会看到上面的成果:
$ curl -H "Host: canary-demo.com" http://localhost:8080/version
Demo: V1
另外,通过 VelaUX 的资源拓扑页面,咱们能够看到五个 V1 版本的实例曾经全副就绪。
降级利用
利用上面的这个 yaml,来降级你的利用。
cat <<EOF | vela up -f -
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: canary-demo
annotations:
app.oam.dev/publishVersion: v2
spec:
components:
- name: canary-demo
type: helm
properties:
repoType: "helm"
url: "https://wangyikewxgm.github.io/my-charts/"
chart: "canary-demo"
# Upgade to version 2.0.0
version: "2.0.0"
traits:
- type: kruise-rollout
properties:
canary:
# The first batch of Canary releases 20% Pods, and 20% traffic imported to the new version, require manual confirmation before subsequent releases are completed
steps:
- weight: 20
# The second batch of Canary releases 90% Pods, and 90% traffic imported to the new version.
- weight: 90
trafficRoutings:
- type: nginx
EOF
咱们留神到新的 application 和首次部署的相比仅有两处改变:
- 把 app.oam.dev/publishVersion 的 annotation 从 v1 降级到了 v2。这代表这次批改是一个新的版本。
- 把 helm chart 的版本升级到了 2.0.0,该版本的 chart 中的 deployment 镜像的 tag 降级到了 V2。
一段时间之后,咱们会发现降级过程停在了咱们下面定义的第一个批次,也就是只降级 20% 的实例和流量。这个时候屡次执行下面拜访网关的命令,你会发现 Demo: v1 和 Demo: v2 交替呈现,并且有差不多 20% 的概率失去 Demo: v2 的后果。
$ curl -H "Host: canary-demo.com" http://localhost:8080/version
Demo: V2
再次查看利用的资源的拓扑状态,会看到由 kruise-rollout trait 创立进去的 rolloutCR 为咱们创立了一个新版本的实例,而之前工作负载创立进去的 5 个旧版本的实例并没有发生变化。
接下来,咱们通过 vela 的 CLI 执行上面的命令,通过人工审核复原持续降级:
vela workflow resume canary-demo
一段时间之后,通过资源拓扑图,咱们看到五个新版本的实例被创立进去了。这个时候咱们再次拜访网关,会发现呈现 Demo:v2 的概率大幅减少,靠近于 90%。
疾速回滚
通常在一个实在场景中的公布中,常常会有通过人工审核之后,发现新版本利用的状态异样,须要终止以后的降级,疾速将利用回退到降级开始前的版本。
咱们就能够执行上面的命令,先暂停以后的公布工作流:
$ vela workflow suspend canary-demo
Rollout default/canary-demo in cluster suspended.
Successfully suspend workflow: canary-demo
紧接着回滚到公布之前的版本,也就是 V1:
$ vela workflow rollback canary-demo
Application spec rollback successfully.
Application status rollback successfully.
Rollout default/canary-demo in cluster rollback.
Successfully rollback rolloutApplication outdated revision cleaned up.
这个时候,咱们再次拜访网关,会发现所有的申请后果又回到了 V1 的状态。
$ curl -H "Host: canary-demo.com" http://localhost:8080/version
Demo: V1
这时候,通过资源拓扑图,咱们能够看到,金丝雀版本的实例也全副被删除了,并且从始至终,v1 的五个实例,作为稳固版本的实例,始终没有产生任何变动。
如果你将下面的回滚操作改为复原持续降级,将会继续执行后续的降级过程,实现全量公布。
上述 demo 的残缺操作过程请参考文末文档 2 [ 4]。
如果你心愿间接应用原生的 K8s 资源实现下面过程能够参考文末文档 3 [ 5]。另外,除了 Deployment,kruise-rollout 插件还反对了 StatefulSet 和 OpenKruise 的 CloneSet,如果你的 chart 中的工作负载类型是以上三种都能够通过下面的例子实现金丝雀公布。
置信你也看留神到,下面的例子咱们给出的是基于 nginx-Ingress-controller 的七层流量切分计划,另外咱们也反对了 Kubernetes Gateway 的 API [ 6] 从而可能反对更多的网关类型和四层的流量切分计划。
公布过程的稳定性是如何保障的?
首次部署实现后,kruise rollout 插件(以下简称 rollout)会监听 Helm Chart 部署的资源,在咱们的例子中就是 deployment,servcie 和 ingress,还反对 StatefulSet 以及 OpenKruise Cloneset。rollout 会接管这个 deployment 后续的降级动作。
在进行降级时,新版本的 Helm 部署首先失效,会将 deployment 的镜像更新为 v2,然而这个时候 deployment 的降级过程会被 rollout 从 controller-manager 手中接管,使得 deployment 上面的 Pod 不会被降级。于此同时,rollout 会复制一个金丝雀版本的 deployemnt,镜像的 tag 为 v2,并创立一个 service 筛选到它上面的实例,和一个指向这个 service 的 ingress,最初通过设置 ingress 绝对应的 annotation,让这个 ingress 承接金丝雀版本的流量(具体能够参考文末文档 4 [ 7]),从而实现流量切分。
在通过所有的人工确认步骤之后,实现全量公布时,rollout 会把稳固版本的 deployment 降级控制权交还给 controller-manager,届时稳固版本的实例会陆续降级到新版本,当稳固版本的实例全副就绪之后,才会陆续销毁金丝雀版本的 deployment,service 和 ingress,从而保障了整个过程中申请流量不会因为打到没有就绪的实例上,导致申请异样,做到无损的金丝雀公布。
之后咱们还将在以下方面继续迭代,反对更多的场景并带来更加稳固牢靠的降级体验:
- 降级过程对接 KubeVela 的 workflow 体系,从而引入更加丰盛的两头步骤扩大体系,反对降级过程中通过 workflow 执行告诉发送等性能。甚至在各个步骤的暂停阶段,对接内部的可观测性体系,通过查看日志或者监控等指标,主动决策是否持续公布或回滚,从而实现无人值守的公布策略。
- 集成 istio 等 更多的 addon,反对 ServiceMesh 的流量切分计划。
- 除了反对基于百分比流量切分形式,反对基于 header 或 cookie 的流量切分规定,以及反对诸如蓝绿公布等个性。
总结
前文曾经提到,KubeVela 反对 Helm 做金丝雀公布的流程齐全是通过插件(Addon)体系实现的,fluxcd addon 助咱们通过部署和治理 helm chart 的生命周期。kruise-rollout addon 帮忙咱们实现 workload 的实例降级以及在降级过程中流量的切换。通过组合两个 addon 的形式,实现了对于 Helm 利用的全生命周期的治理和金丝雀降级,不须要对你的 Helm Chart 做任何改变。你也能够针对你的场景编写插件 [ 8],实现更非凡的场景或流程。
基于 KubeVela 弱小的可扩大能力,你不仅能够灵便的组合这些 addon,你还能够放弃下层利用不做任何变动的状况下,依据不同的平台或环境动静替换底层的能力实现。 例如,如果你更心愿采纳 argocd 不是 fluxcd 实现对于 Helm 利用的部署,你就能够通过启用 argocd 的 addon 实现雷同的性能,下层的 Helm 利用不须要做任何扭转或迁徙。
当初 KubeVela 社区曾经提供了数十个 addon,能够可能帮忙平台扩大 可观测性,gitops,finops,rollout 等各方面的能力。
如果你对 addon 感兴趣的话,也十分欢送为 Addon 的仓库 [ 9] 提交你的自定义插件,为社区奉献新的生态能力!
参考链接:
[1] OpenKruise 社区:
https://openkruise.io/
[2] 文档 1:
https://kubevela.net/docs/ins…
[3] chart:
https://github.com/wangyikewx…
[4] 文档 2:
https://kubevela.net/docs/tut…
[5] 文档 3:
*https://kubevela.net/docs/tut…
[6] API:
https://gateway-api.sigs.k8s.io/
[7] 文档 4:
https://kubernetes.github.io/…
[8] 编写插件:
https://kubevela.net/docs/pla…
[9] Addon 的仓库地址:
https://github.com/kubevela/c…
您能够通过如下资料理解更多对于 KubeVela 以及 OAM 我的项目的细节:
- 我的项目代码库:github.com/oam-dev/kubevela 欢送 Star/Watch/Fork!
- 我的项目官方主页与文档:kubevela.io,从 1.1 版本开始,已提供中文、英文文档,更多语言文档欢送开发者进行翻译。
- 我的项目钉钉群:23310022;Slack:CNCF #kubevela Channel
- 退出微信群:请先增加以下 maintainer 微信号,表明进入 KubeVela 用户群:
戳此处:查看 KubeVela 我的项目官网!!