kubernetes 守护进程集更新了NumberScheduled状态,但在滚动更新时不正确,

t8e9dugd  于 4个月前  发布在  Kubernetes
关注(0)|答案(7)|浏览(62)

发生了什么?
具有更新策略的DaemonSet,在节点上终止旧Pod(surge > 0)之前创建新Pod,不会将同一节点上的已调度更新Pod计入"UpdatedNumberScheduled"状态,直到该节点上的旧Pod被终止。

你期望会发生什么?
使用滚动更新时,"UpdatedNumberScheduled"应该在调度后计算一次更新后的Pod,而不是被同一节点上的旧Pod阻塞。

我们如何尽可能精确地重现它?

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-daemonset
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: busybox
        command: ["/bin/sh"]
        args: ["-c", "trap 'sleep 30' TERM; while true; do sleep 1; done"]
  updateStrategy:
    type: RollingUpdate                                                                                                                                                                                                 
    rollingUpdate:                                                                                                                                                                                               
      maxSurge: 1                                                                                                                                                                                        
      maxUnavailable: 0
  • 使用上述规范创建一个DaemonSet。
  • 更新/重启DaemonSet以触发滚动更新。
  • 在新Pod被调度并在旧Pod被终止之前检查此DaemonSet的"UpdatedNumberScheduled"状态。

我们需要了解其他任何信息吗?
根本原因应该是状态更新仅检查每个节点上最旧的pod,这在surge>0的滚动更新中不应该是这样吗?

Kubernetes版本:1.28.2
云提供商:Docker Desktop
操作系统版本:无响应
安装工具:无响应
容器运行时(CRI)和版本(如适用):无响应
相关插件(CNI,CSI等)和版本(如适用):无响应

syqv5f0l

syqv5f0l2#

我认为这似乎是正常的逻辑。这是我复制的过程,我使用了minikube k8s服务器1.27.4,有3个节点。
daemonset.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-daemonset
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: busybox
        command: ["/bin/sh"]
        args: ["-c", "trap 'sleep 30' TERM; while true; do sleep 1; done"]

kubectl rollout restart ds my-daemonset
观察到的情况是:
首先删除节点上的Pod,然后再创建。
当Pod处于“terminating”状态时,“UpdatedNumberScheduled”不会改变。只有当Pod处于“creating”状态时,它才会增加。
请查看文档,https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/

我相信这个描述与实际执行的逻辑是一致的。

qpgpyjmq

qpgpyjmq3#

你好,@Ithrael,感谢回复。
我在复现步骤中遗漏了"RollingUpdate as the updateStrategy",对此表示抱歉(已在编辑中添加)。
请尝试以下内容并查看问题所在。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-daemonset
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: busybox
        command: ["/bin/sh"]
        args: ["-c", "trap 'sleep 30' TERM; while true; do sleep 1; done"]
  updateStrategy:
    type: RollingUpdate                                                                                                                                                                                                 
    rollingUpdate:                                                                                                                                                                                               
      maxSurge: 1                                                                                                                                                                                        
      maxUnavailable: 0

编辑:为了更准确地说,我应该说"使用在节点上终止旧Pod之前创建新Pod的RollingUpdate策略"。

wsewodh2

wsewodh24#

你好,shihaohems,感谢你的回复。
我现在可以复现这个问题了。

rollingUpdate:                                                                                                                                                                                               
      maxSurge: 1                                                                                                                                                                                        
      maxUnavailable: 0

在滚动更新过程中,这个配置会首先创建一个新的Pod版本,然后删除旧的Pod版本。这将导致新旧Pod版本共存一段时间。由于sort.Sort(podByCreationTimestampAndPhase(daemonPods))行的排序操作,pod := daemonPods[0]行的代码只会检查最旧的Pod。这意味着只有在删除旧版本的Pod后,才会开始检查新版本的Pod。
/assign

bkkx9g8r

bkkx9g8r5#

Kubernetes项目目前缺乏足够的贡献者来充分应对所有问题。
此机器人根据以下规则对未分类的问题进行分级处理:

  • lifecycle/stale应用后的90天不活动后,将应用lifecycle/stale
  • lifecycle/stale应用后的30天不活动后,将应用lifecycle/rotten
  • lifecycle/rotten应用后的30天不活动后,该问题将被关闭

您可以:

  • 将此问题标记为新鲜的/remove-lifecycle stale
  • 使用/close关闭此问题
  • 提供帮助,请使用Issue Triage

请将反馈发送至sig-contributor-experience@kubernetes/community
/lifecycle stale

km0tfn4u

km0tfn4u6#

/triage accepted
/priority important-longterm
/remove-lifecycle stale
ercv8c1e

ercv8c1e7#

在修复此问题时,应考虑以下几点:#122587(评论)

相关问题