以上是关于防级联删除的介绍,大家应该将防级联删除理解成安全防护最基础的一个策略,因为级联删除是 Kubernetes 中非常危险的一个面向终态的能力。
2. 防护实践 – Pod 删除流控 & 熔断
针对 Pod 删除流控 & 熔断的策略,指的是用户调用、或用控制器用 K8s 去做 Pod 驱逐时,一旦出现误操作或者出现逻辑异常,很可能导致在整个 K8s 集群范围内出现 Pod 大规模删除的情况。针对这种情况做了 Pod 删除留空策略,或者说是一个 CRD。这个 CRD 用户可以定义在一个集群中,不同的时间窗口内,最多有多少 Pod 允许被删除。
apiVersion: policy.kruise.io/v1alpha1kind: PodDeletionFlowControlmetadata: # ...spec: limitRules: - interval: 10m limit: 100 - interval: 1h limit: 500 - interval: 24h limit: 5000 whiteListSelector: matchExpressions: - key: xxx operator: In value: foo如上面这个例子,10 分钟之内最多允许 100 个 Pod 被删除,1 小时之内最多允许 500 个 Pod 被删除,24 小时内最多允许 5000 个 Pod 被删除。当然也可以定义一些白名单,比如有些测试应用,每天频繁地巡检、测试,频繁删除会影响整个流控,可以提供一个白名单,符合白名单的应用不计算在窗口内。
除了白名单之外,可能 90% 的常规应用或者核心应用,是受到删除流控保护的。一旦存在规模性误删除操作,就会被删除流控以及熔断机制保护。包括在保护之后或者触发阈值之后,最好提供这种报警机制、监控机制,让集群的管理者能快速的感知到线上出现的熔断事件。还包括帮助管理者去判断熔断事件是一个正常的事件,还是一个异常的事件。
如果在这段时间内,需要存在很多删除请求,可以把对应策略值相应放大。如果真的是一些误删除,拦截到之后,及时根据请求来源做溯源,及时在搜索层面做熔断,拒绝这些请求。
3. 防护实践 - 应用维度不可用数量保护
对应用维度不可用数量保护,对于 K8s 原生,原生的 Kubernetes 提供了 PDB(PodDisruptionBudge) 策略,但是 PDB 只能拦截 Pod eviction 驱逐操作,也就是 Pod 驱逐操作。
apiVersion: policy/v1beta1kind: PodDisruptionBudgetmetadata: name: xxxspec: minAvailable: 2 selector: matchLabels: app: xxx上面的这个例子,假设其中有 5 个 Pod,这时定义了 minAvailable=2,就保证最少有 2 个 Pod 处于可用。一旦有 3 个 Pod 不可用,还剩下 2 个 Pod 可用,这时候如果 Pod eviction 针对存量 2 个 Pod 做驱逐,这个时候 PDB 会保护 Pod 可用性,拒绝这次驱逐操作。但是相应的如果对存量 2 个 Pod 做删除或者原地升级,或者去做其他导致 Pod 不可用的事情,PDB 是没有办法拦截,尤其是针对 Pod 删除请求,比 Pod 驱逐更为常见,但是 PDB 是没办法拦截删除等请求。
对于这些问题,阿里巴巴做了 PodUnavailableBudget 拦截操作,也就是 PUB。这里的 Unavailable 能做的操作就更多了,基本上所有可能导致 Pod 不可用的操作,都在 PodUnavailableBudget 保护范围内,包括了驱逐请求、Pod 删除请求,应用原地升级、Sidecar 原地升级、容器重启等,所有导致应用不可用的操作都会被 PUB 拦截。
如下面这个例子:
apiVersion: policy.kruise.io/v1alpha1kind: PodUnavailableBudgetspec: #selector: # app: xxx targetRef: apiVersion: apps.kruise.io kind: CloneSet name: app-xxx maxUnavailable: 25% # minAvailable: 15status: deletedPods: pod-uid-xxx: "116894821" unavailablePods: pod-name-xxx: "116893007" unavailableAllowed: 2 currentAvailable: 17 desiredAvailable: 15 totalReplicas: 20定义了一个 PUB,这个 PUB 可以像原生 PDB 一样写一个 selector 范围,也可以通过 targetRef 直接关联到某一个 Workload,保护范围就是在 Workload 底下的所有 Pod,同样也可以定义最大不可用数量,以及最小可用数量。
假设对于 CloneSet 底下总共 20 个 Pod,当定义了 maxUnavailable:25% 时,一定要保证至少有 15 个 Pod 处于可用状态。也就是说,PUB 会保证这 20 个 Pod 中最多有 5 个处于不可用状态。回到我们之前在“危机”部分讲到的一个例子,如果这 20 个 Pod 同时在被 Cloneset 发布,以及被 Kubelet 驱逐,或是人工手动删除,一旦 Pod 不可用数量超过 5 个,不管是 Kubelet 对剩余 15 个 Pod 做驱逐,还是人为手动删除剩余的某些 Pod,这些操作都会被 PUB 所拦截,这种策略能完全保证应用在部署过程中的可用性。PUB 可以保护的范围比 PDB 大很多,包括在实际使用过程中预期之外的一些删除请求、升级请求,从而保证整个应用在运行时的稳定性和可用性。
4. 防护实践 - PUB/PDB 自动生成