• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Advanced DaemonSet

武飞扬头像
HrimfaxiYKW
帮助1

阅读本节前请了解 Advanced DaemonSet 的使用和功能

系列专栏: Openkruise

doc :openkruise.io/zh/docs/use…

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 上,创建缺少的,删除多余的。

  1. 每个 node 通过函数 nodesNeedingDaemonPodsOnNode, podsToDeleteOnNode := dsc.podsShouldBeOnNode(node, nodeToDaemonPods, ds, hash) 来判断 pod 是否应该被调度在 node 上并返回两个数组 nodesNeedingDaemonPodsOnNode, podsToDeleteOnNode,其中 nodesNeedingDaemonPodsOnNode 意味着这里面的 pods 应该在本轮 reconcile 中被创建(shouldRun && !exists), podsToDeleteOnNode 意味着这里面的 pods 应该在本轮 reconcile 中被删除

[⚠️注意]:这里面还包含了升级策略为 "RollingUpdate" 且 rollingUpdateType 不为空且配置了 MaxSurge 的情况,具体逻辑可以参考 升级方式

  1. 处理具有分批灰度的情况

    1. 需要重新计算 nodesNeedingDaemonPodsOnNode 数组以保证分批灰度策略的正确性:nodesNeedingDaemonPods = GetNodesNeedingPods(newPodCount, nodesDesireScheduled, int(partition), isDaemonSetCreationProgressively(ds), nodesNeedingDaemonPods)
  2. 创建/删除 pods 在对应的 node 上 : dsc.syncNodes(ds, podsToDelete, nodesNeedingDaemonPods, hash)

    1. 创建不是一次行全部创建好,而是采用一种类似 tcp 慢启动的策略,逐倍调大 batchSize,如果 batchSize 大于最后需要创建的 pod 数量,那么 batchSize 就等于剩余需要创建的 pod 数
    2. batchSize := integer.IntMin(createDiff, kubecontroller.SlowStartInitialBatchSize)
      for pos := 0; createDiff > pos; batchSize, pos = integer.IntMin(2*batchSize, createDiff-(pos batchSize)), pos batchSize
      
    3. 在创建完后进行删除操作,删除是起了多个协程来并行删除,待所有删除任务完成后才返回

滚动升级

前置条件:pod ready 且不处于暂停状态

触发条件:Spec.UpdateStrategy.Type == “OnDelete” or "RollingUpdate"

  1. 通过 nodeToDaemonPods, err := dsc.getNodesToDaemonPods(ds)获取每个 nodes 上对应的 pods,即该 ds 所应管理的所有 <node, pod> pair 对信息

  2. 解析 maxSurge 和 maxUnavailable 参数,这是升级策略的依据

  3. nodeToDaemonPods 数组进行进一步的过滤(filterDaemonPodsToUpdate ==>filterDaemonPodsNodeToUpdate),目的是要找出哪些 node 上有 pod 需要更新,筛选逻辑如下

    1. 首先确定该 node 上的 pod 是否需要更新,如果需要才继续
    2. 如果预先定义了 selector [特性: 标签选择升级],那么根据 selector 选
    3. 如果没有 selector 特性,则该 node 被选中
    4. 默认的 partition = 0,但用户也可能定义了一个大于 0 的值,因此我们需要保留 partition 个 pod 不升级,所以需要对前面已经选中的 nodes 进行截断 maxUpdate := len(allNodeNames) - int(partition);,并返回一个截断后的数组 sorted = sorted[:maxUpdate]
  4. 对于 maxSurge == 0 的情况,我们只是先做删除,在下一次 reconcile 的时候才创建

    1. 首先我们遍历每一个 node 以筛选目标 pods

      1. 通过函数 newPod, oldPod, ok := findUpdatedPodsOnNode(ds, pods, hash) 检查 node 上 pod 的版本,结合 podutil.IsPodAvailable 和 maxUnavailable参数筛选出需要处理的 pods 到两个数组

        1. allowedReplacementPods: 需要更新且不可用的 pod
        2. candidatePodsToDelete: 需要更新且可用的 pod
    2. 优先选取 allowedReplacementPods 再根据 maxUnavailable 添加 candidatePodsToDelete 中的 pods 到 oldPodsToDelete 数组,作为我们要处理的 pods

    3. 对每一个 pod 尝试 inplace 更新 dsc.inPlaceUpdatePods(ds, oldPodsToDelete, curRevision, oldRevisions)

      1.     ⚠️这里 inplace 更新的整体逻辑也是调用的 package inplaceupdate 里的函数,整体实现在 asts 中已经讲过,参考 ASTS原地更新,官方文档 原地升级
    4. 对剩下的 pods 通过 dsc.syncNodes(ds, oldPodsToDelete, nil, hash) 删除剩下的 pods

  5. 对于 maxSurge !=0 时,我们需要先创再删,同样我们也需要遍历每一个 node 以进行筛选分类

    1. 通过 findUpdatedPodsOnNodepodutil.IsPodAvailable函数以及 maxSurge 来进行筛选。(注意:maxSurge 和 maxUnavailable 是矛盾的)
    2. 筛选最后会产生两个数组分别为 oldPodsToDelete 和 newNodesToCreate,代表哪些 pods 可以删除,哪些 pods 应当被创建
    3. 调用 dsc.syncNodes(ds, oldPodsToDelete, newNodesToCreate, hash)

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgaihbe
系列文章
更多 icon
同类精品
更多 icon
继续加载