乐趣区

关于云原生:OpenKruise-如何实现应用的可用性防护

作者|赵明山(立衡)

前言

OpenKruise 是阿里云开源的云原生利用自动化治理套件,也是以后托管在 Cloud Native Computing Foundation (CNCF) 下的 Sandbox 我的项目。它来自阿里巴巴多年来容器化、云原生的技术积淀,是阿里外部生产环境大规模利用的基于 Kubernetes 之上的规范扩大组件,也是紧贴上游社区规范、适应互联网规模化场景的技术理念与最佳实际。
 
OpenKruise 在 2021.9.6 公布了最新的 v0.10.0 版本新增了弹性拓扑治理和利用平安防护等能力,本文将为大家揭晓 OpenKruise 是如何实现利用的可用性防护能力。

背景

在文章开始局部,我想先聊聊到底什么是“利用的可用性防护”。例如,在 Kubernetes 下面部署的 ETCD 服务,时刻要保障可用的实例数不小于 N(受限于 raft 协定的选举机制)。很多同学都会想到 Deployment 中能够设置 maxUnavailable,那不就行了吗?再说了,还会有 RS Controller 在做正本管制呢?认真想想,Deployment 的 MaxUnavailable 是在利用滚动公布的过程中保障最小的 Pod 数量,而 RS Controller 控制器则是尽快让利用理论的福本数等于预期的正本数,并不能保障利用每时每刻的最小可用正本数。

针对上述场景,Kubernetes 原生提供的 PodDisruptionBudget(PDB)通过限度同时中断 Pod 的数量,来保障利用的高可用性。然而,以后 PDB 的能力并不全面,它只能防护 Pod Eviction 场景(例如:kubectl drain node 驱赶 node 下面的 Pod)。在如下“并发 Pod 更新 / 驱赶 / 删除”场景中,即使有 PDB 防护仍然将会导致业务中断、服务降级:

  • 利用 owner 通过 Deployment 正在进行版本升级,与此同时集群管理员因为机器资源利用率过低正在进行 node 缩容
  • 中间件团队利用 SidecarSet 正在原地降级集群中的 sidecar 版本(例如:ServiceMesh envoy),同时 HPA 正在对同一批利用进行缩容
  • 利用 owner 和中间件团队利用 CloneSet、SidecarSet 原地降级的能力,正在对同一批 Pod 进行降级

PodUnavailableBudget 晋升利用的高可用性

Kubernetes 原生 PDB 为什么只能防护 Pod Eviction 的场景呢?首先,让咱们来看看它的实现原理:PDB 通过 selector 抉择了一批防护的 Pod 列表,minAvailable 则表明最小可用的 Pod 数量,pdb-controller 依据后面两个值以及线上 Pod 的 ready 状态,计算出以后时刻最多容许中断的 Pod 数量 PodDisruptionAllowd。k8s pod evictionRestful API 接口则会依据 pdb PodDisruptionAllowd 来决定接口胜利还是返回 400 报错。到了这里终于水落石出了,pdb 通过 evictionRestful API 接口来实现 pod 的防护能力,所以它只能实用于 Pod Eviction 场景。

OpenKruise PodUnavailableBudget(PUB)平安防护的整体思路与 PDB 其实也大致相同,不过在要害的防护门路下面做了一些调整。Voluntary Disruption(诸如:集群管理员驱赶 Node、并发降级 Pod)被动导致 Pod 不可用的场景其实能够演绎为以下三类:

  • Modification Pod.Spec 定义(CloneSet、SidecarSet 原地降级 container)
  • Delete Pod(Deployment 等控制器滚动降级 Pod、间接 Delete Pod)
  • Eviction API(kubectl drain node 驱赶 Pod)

OpenKruise 基于 Kubernetes Adminssion Webhook 机制增加针对 Pod Update/Delete/Eviction 的 webhook 逻辑,依据 pub 的 PodUnavailableAllowed 来实现更加全面的利用 Pod 平安防护机制,逻辑架构如下:

利用场景

  • 无状态利用:比方想至多有 60% 的正本 Available
    • 解决办法:创立 PUB Object,指定 minAvailable 为 60%,或者 maxUnavailable 为 40%
apiVersion: apps.kruise.io/v1alpha1
kind: PodUnavailableBudget
metadata:
  name: web-server-pub
  namespace: web
spec:
  targetRef:
    apiVersion: apps.kruise.io/v1alpha1
    kind: CloneSet
    name: web-server
  minAvailable: 60%
  • 有状态利用:起码可用的实例数不能少于某个数 N(比方受限于 raft 协定类利用的选举机制)
    • 解决办法:设置 maxUnavailable=1 或者 minAvailable=N,别离容许每次只删除一个实例或每次删除 workload.replicas – minAvailable 个实例
apiVersion: apps.kruise.io/v1alpha1
kind: PodUnavailableBudget
metadata:
  name: etcd-pub
  namespace: etcd
spec:
  targetRef:
    apiVersion: apps.kruise.io/v1alpha1
    kind: StatefulSet
    name: etcd
  maxUnavailable: 1
  • 单实例利用:终止这个实例之前必须提前告诉客户并获得批准
    • 解决办法:创立 PUB Object,并设置 maxUnavailable 为 0,这样 OpenKruise 就会阻止这个实例的删除,而后去告诉并征求用户批准后,再把这个 PUB 删除从而解除这个阻止,而后再去 recreate
apiVersion: apps.kruise.io/v1alpha1
kind: PodUnavailableBudget
metadata:
  name: gameserver-pub
  namespace: game
spec:
  targetRef:
    apiVersion: apps.kruise.io/v1alpha1
    kind: StatefulSet
    name: gameserver
  maxUnavailable: 0

总结

Kubernetes 给用户带来极致弹性调度的同时也给利用的高可用性带来了肯定的考验,PUB 是在 Voluntary Disruption 场景下的一种尝试,同时配合 OpenKruise 提供的防级联删除的能力置信能在肯定水平上晋升线上利用的稳定性。而针对更加辣手 InVoluntary Disruption(诸如:集群 Node 网络脑裂、vk 节点异样)导致 Pod 不可用等升高利用可用性的场景,OpenKruise 将来也会有更多的摸索。与此同时,咱们也欢送更多的同学参加到 OpenKruise 社区来,独特建设一个场景更加丰盛、欠缺的 K8s 利用治理、交付扩大能力,可能面向更加规模化、复杂化、极致性能的场景。

Github:https://github.com/openkruise…
Official:https://openkruise.io/
Slack: Channel in Kubernetes Slack
钉钉交换群:搜寻群号【23330762】可增加~

戳链接(https://github.com/openkruise…),查看 OpenKruise 我的项目 github 主页!!

退出移动版