Advanced DaemonSet
阅读本节前请了解 Advanced DaemonSet 的使用和功能
系列专栏: Openkruise
api: apis/apps/v1alpha1/daemonset_types.go
controller: pkg/controller/daemonset/
⚠️ demonset 保证的是在对应 node 有且仅有一个 pod 运行
Reconcile
准备阶段
采用 k8s informer 机制,内置多种 informer 对象 Listener,用于获取集群中对应的资源
// 拿到对应的 ds
ds, err := dsc.dsLister.DaemonSets(request.Namespace).Get(request.Name)
// 获取所有的 node 信息
nodeList, err := dsc.nodeLister.List(labels.Everything())
调整 pod 分布
这一步通过函数 dsc.manage(ds, nodeList, hash)
完成,其中 hash 是该 ds 最新 revision 的hash 值,用于保证版本的一致性。 该函数的目的是让 pod 在它应该在的 node 上,创建缺少的,删除多余的。
- 每个 node 通过函数
nodesNeedingDaemonPodsOnNode, podsToDeleteOnNode := dsc.podsShouldBeOnNode(node, nodeToDaemonPods, ds, hash)
来判断 pod 是否应该被调度在 node 上并返回两个数组nodesNeedingDaemonPodsOnNode, podsToDeleteOnNode
,其中nodesNeedingDaemonPodsOnNode
意味着这里面的 pods 应该在本轮 reconcile 中被创建(shouldRun && !exists),podsToDeleteOnNode
意味着这里面的 pods 应该在本轮 reconcile 中被删除
[⚠️注意]:这里面还包含了升级策略为 "RollingUpdate" 且 rollingUpdateType 不为空且配置了 MaxSurge 的情况,具体逻辑可以参考 升级方式
-
处理具有分批灰度的情况
- 需要重新计算
nodesNeedingDaemonPodsOnNode
数组以保证分批灰度策略的正确性:nodesNeedingDaemonPods = GetNodesNeedingPods(newPodCount, nodesDesireScheduled, int(partition), isDaemonSetCreationProgressively(ds), nodesNeedingDaemonPods)
- 需要重新计算
-
创建/删除 pods 在对应的 node 上 :
dsc.syncNodes(ds, podsToDelete, nodesNeedingDaemonPods, hash)
- 创建不是一次行全部创建好,而是采用一种类似 tcp 慢启动的策略,逐倍调大 batchSize,如果 batchSize 大于最后需要创建的 pod 数量,那么 batchSize 就等于剩余需要创建的 pod 数
-
batchSize := integer.IntMin(createDiff, kubecontroller.SlowStartInitialBatchSize) for pos := 0; createDiff > pos; batchSize, pos = integer.IntMin(2*batchSize, createDiff-(pos batchSize)), pos batchSize
- 在创建完后进行删除操作,删除是起了多个协程来并行删除,待所有删除任务完成后才返回
滚动升级
前置条件:pod ready 且不处于暂停状态
触发条件:Spec.UpdateStrategy.Type == “OnDelete” or "RollingUpdate"
-
通过
nodeToDaemonPods, err := dsc.getNodesToDaemonPods(ds)
获取每个 nodes 上对应的 pods,即该 ds 所应管理的所有 <node, pod> pair 对信息 -
解析 maxSurge 和 maxUnavailable 参数,这是升级策略的依据
-
对
nodeToDaemonPods
数组进行进一步的过滤(filterDaemonPodsToUpdate ==>filterDaemonPodsNodeToUpdate
),目的是要找出哪些 node 上有 pod 需要更新,筛选逻辑如下- 首先确定该 node 上的 pod 是否需要更新,如果需要才继续
- 如果预先定义了 selector [特性: 标签选择升级],那么根据 selector 选
- 如果没有 selector 特性,则该 node 被选中
- 默认的 partition = 0,但用户也可能定义了一个大于 0 的值,因此我们需要保留 partition 个 pod 不升级,所以需要对前面已经选中的 nodes 进行截断
maxUpdate := len(allNodeNames) - int(partition);
,并返回一个截断后的数组sorted = sorted[:maxUpdate]
-
对于 maxSurge == 0 的情况,我们只是先做删除,在下一次 reconcile 的时候才创建
-
首先我们遍历每一个 node 以筛选目标 pods
-
通过函数
newPod, oldPod, ok := findUpdatedPodsOnNode(ds, pods, hash)
检查 node 上 pod 的版本,结合podutil.IsPodAvailable
和 maxUnavailable参数筛选出需要处理的 pods 到两个数组- allowedReplacementPods: 需要更新且不可用的 pod
- candidatePodsToDelete: 需要更新且可用的 pod
-
-
优先选取 allowedReplacementPods 再根据 maxUnavailable 添加 candidatePodsToDelete 中的 pods 到 oldPodsToDelete 数组,作为我们要处理的 pods
-
对每一个 pod 尝试 inplace 更新
dsc.inPlaceUpdatePods(ds, oldPodsToDelete, curRevision, oldRevisions)
-
对剩下的 pods 通过
dsc.syncNodes(ds, oldPodsToDelete, nil, hash)
删除剩下的 pods
-
-
对于 maxSurge !=0 时,我们需要先创再删,同样我们也需要遍历每一个 node 以进行筛选分类
- 通过
findUpdatedPodsOnNode
和podutil.IsPodAvailable
函数以及 maxSurge 来进行筛选。(注意:maxSurge 和 maxUnavailable 是矛盾的) - 筛选最后会产生两个数组分别为 oldPodsToDelete 和 newNodesToCreate,代表哪些 pods 可以删除,哪些 pods 应当被创建
- 调用
dsc.syncNodes(ds, oldPodsToDelete, newNodesToCreate, hash)
- 通过
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgaihbe
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01