使用 Admission Webhook 机制实现多集群资源配额控制 (3)

为了解决这个问题,后台服务会定时全局更新每个应用组的 usage 值。这样,如果出现了 验证 阶段增加了 usage 值,但任务实际提交到数据库失败的情况,在全局更新的时候,usage 值最终会重新更新为那个时刻应用组在集群内资源使用的准确值。

但在极少数情况下,全局更新会在这种时刻发生:某最终会成功存入 etcd 持久化 的资源对象创建请求,已经通过 webhook 验证,但尚未完成 持久化 的时刻。这种时刻的存在,导致全局更新依然会带来用户占用 超过 配额的问题。
比如,在之前的例子中,deployment1 更新了 usage 值之后,恰巧发生了全局更新。此时 deployment1 的信息恰好尚未存入 etcd,所以全局更新会把 usage 重新更新为旧值,这样会导致 dployment2 也能被通过,从而超过了配额限制。
但通常,从 验证持久化 的时间很短。低频 的全局更新情况下,此种情况 几乎不会发生。后续,如果有进一步的需求,可以采用更复杂的方案来规避这个问题。

3.2.3 原生 ResourceQuota 的工作方式

K8s 集群中原生的配额管理 ResourceQuota 针对上述 资源申请竞争资源创建失败 问题,采用了类似的解决方案:

即时更新解决申请竞争问题

检查完配额后,即时更新资源用量,K8s 系统自带的乐观锁保证并发的资源控制(详见 K8s 源码中 的实现),解决资源竞争问题。

checkQuotas 中最相关的源码解读:

// now go through and try to issue updates. Things get a little weird here: // 1. check to see if the quota changed. If not, skip. // 2. if the quota changed and the update passes, be happy // 3. if the quota changed and the update fails, add the original to a retry list var updatedFailedQuotas []corev1.ResourceQuota var lastErr error for i := range quotas { newQuota := quotas[i] // if this quota didn't have its status changed, skip it if quota.Equals(originalQuotas[i].Status.Used, newQuota.Status.Used) { continue } if err := e.quotaAccessor.UpdateQuotaStatus(&newQuota); err != nil { updatedFailedQuotas = append(updatedFailedQuotas, newQuota) lastErr = err } }

这里 quotas 是经过校验后的配额信息,其中 newQuota.Status.Used 字段则记录了该配额的资源使用情况。如果针对该配额的资源请求通过了,运行到这段代码时,Used 字段中已经被加上了新申请资源的量。随后,Equals 函数被调用,即如果 Used 字段未变,说明没有新的资源申请。否则,就会运行到 e.quotaAccessor.UpdateQuotaStatus,立刻去把 etcd 中的配额信息按照 newQuota.Status.Used 来更新。

定时全局更新解决创建失败问题

定时全局更新资源使用量(详见 K8s 源码中 的实现),解决可能的资源创建失败问题 。

Run 中最相关的源码解读:

// the timer for how often we do a full recalculation across all quotas go wait.Until(func() { rq.enqueueAll() }, rq.resyncPeriod(), stopCh)

这里 rq 为 ResourceQuota 对象对应 controller 的自引用。这个 Controller 运行 Run 循环,持续地控制所有 ResourceQuota 对象。循环中,不间断定时调用 enqueueAll,即把所有的 ResourceQuota 压入队列中,修改其 Used 值,进行全局更新。

4 参考

Controlling Access to the Kubernetes API

Dynamic Admission Control

A Guide to Kubernetes Admission Controllers

深入理解 Kubernetes Admission Webhook

https://github.com/kubernetes/kubernetes/blob/v1.13.0/test/images/webhook/main.go

Admission Webhooks: Configuration and Debugging Best Practices - Haowei Cai, Google

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

使用 Admission Webhook 机制实现多集群资源配额控制

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxsps.html