kubernetes 部署rollout状态在使用status.conditions时不可靠,

72qzrwbm  于 10个月前  发布在  Kubernetes
关注(0)|答案(5)|浏览(85)

发生了什么?
目前我正在进行一个项目,我们在其中实现了一个Kubernetes操作器,并决定对于某些流程,我们需要等待一些部署完成滚动更新,然后才能继续我们的流程中的其他步骤。
因此,对于旧的部署,我们只需要在pod模板中更新镜像,然后等待更新后的部署完成滚动更新。
如果只考虑status.conditions(如文档中所建议的),那么构建/实现Deployment状态的方式是容易出错且不可靠的。

你期望发生什么?
在更新部署的spec后,当status.ObservedGeneration更改为最新的metadata.Generation时,status.conditions也应该被更新。

我们如何尽可能精确地重现它?
我们发现,如果:

  • 我们从具有status.condition类型为Progressing的Deployment开始,原因为ProgressDeadlineExceeded
  • 更新部署规范(唯一的更改将是来自pod模板容器的图像)
  • 每隔一秒钟启动一个定时器(使用API检索部署并检查状态)

那么,在某些情况下(不是总是这样;这是一个并发/计时问题),第一个status.observedGeneration向新的metadata.generation值的变化,伴随着没有变化(!)的status.conditions(旧条件仍然存在 没有任何单个更改(!))。
根据Kubernetes文档(以及Operator SDK检查此滚动状态的方式),对这些情况的解释将导致说滚动失败,这是不准确的,因为实际的滚动将在几秒钟后开始...
这是一个描述问题的日志示例(请注意,两个块在几毫秒的距离内记录,即使status.conditions相同,status.ObservedGeneration也发生了变化):

  1. # 10:53:18.814 > Metadata.Generation: 2 | Status >> ObservedGeneration: 1, replicas: 1 , readyReplicas: , availableReplicas: , updatedReplicas: 1, unAvailableReplicas: 1
  2. Conditions:
  3. @10-Apr-24 10:53:02 | 10-Apr-24 10:53:02 | Available | False | MinimumReplicasUnavailable | Deployment does not have minimum availability.
  4. @10-Apr-24 10:53:18 | 10-Apr-24 10:53:18 | Progressing | False | ProgressDeadlineExceeded | ReplicaSet "my-deployment-5b8dc498c" has timed out progressing.
  5. => completed: False, failed: False
  6. # 10:53:18.818 > Metadata.Generation: 2 | Status >> ObservedGeneration: 2, replicas: 1 , readyReplicas: , availableReplicas: , updatedReplicas: , unAvailableReplicas: 1
  7. Conditions:
  8. @10-Apr-24 10:53:02 | 10-Apr-24 10:53:02 | Available | False | MinimumReplicasUnavailable | Deployment does not have minimum availability.
  9. @10-Apr-24 10:53:18 | 10-Apr-24 10:53:18 | Progressing | False | ProgressDeadlineExceeded | ReplicaSet "my-deployment-5b8dc498c" has timed out progressing.
  10. => completed: False, failed: True

还有什么我们需要知道的吗?
请告知如何可靠地解释Deployment的滚动状态。

Kubernetes版本

  1. $ kubectl version
  2. Client Version: v1.28.8+k3s1
  3. Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
  4. Server Version: v1.28.8+k3s1

云提供商
无云

操作系统版本

  1. # On Linux:
  2. $ cat /etc/os-release
  3. PRETTY_NAME="K3s v1.28.8+k3s1"
  4. $ uname -a
  5. Linux 3432b46b9978 5.15.0-101-generic #111-Ubuntu SMP Tue Mar 5 20:16:58 UTC 2024 x86_64 GNU/Linux
  6. </details>
  7. ### Install tools
  8. <details>
  9. </details>
  10. ### Container runtime (CRI) and version (if applicable)
  11. <details>
  12. </details>
  13. ### Related plugins (CNI, CSI, ...) and versions (if applicable)
  14. <details>
  15. </details>
ltqd579y

ltqd579y1#

/sig apps

vxf3dgd4

vxf3dgd42#

我正在尝试修复本地环境中的一些单元测试,以测试此修复。以下是我正在尝试做的事情:
修改 updateDeployment 函数,首先通过比较旧的和当前的规范来检查部署的规范是否已更新。如果规范已更新,我们记录更新,更新部署的规范,将 status.ObservedGeneration 设置为当前的 metadata.Generation ,并根据部署的进展情况更新部署的状态条件。最后,我们将部署加入队列以进行进一步处理。

qyuhtwio

qyuhtwio3#

这是我的做法:

  1. func (dc *DeploymentController) updateDeployment(logger klog.Logger, old, cur interface{}) {
  2. oldD := old.(*apps.Deployment)
  3. curD := cur.(*apps.Deployment)
  4. if !reflect.DeepEqual(oldD.Spec, curD.Spec) {
  5. logger.V(4).Info("Updating deployment", "deployment", klog.KObj(oldD))
  6. oldD.Spec = curD.Spec
  7. oldD.Status.ObservedGeneration = curD.ObjectMeta.Generation
  8. if oldD.Status.UpdatedReplicas == *oldD.Spec.Replicas {
  9. oldD.Status.Conditions = []apps.DeploymentCondition{
  10. {
  11. Type: apps.DeploymentAvailable,
  12. Status: corev1.ConditionTrue,
  13. },
  14. }
  15. } else {
  16. oldD.Status.Conditions = []apps.DeploymentCondition{
  17. {
  18. Type: apps.DeploymentAvailable,
  19. Status: corev1.ConditionFalse,
  20. },
  21. }
  22. }
  23. dc.enqueueDeployment(oldD)
  24. }
  25. }
展开查看全部
9q78igpj

9q78igpj4#

  1. /triage accepted
  2. /priority backlog
cnwbcb6i

cnwbcb6i5#

我只能在这个ReplicaSet存在新镜像之前复现这个问题。如果新的ReplicaSet不存在,进度会立即显示出来。

@sicavz
这种情况只发生在你身上吗?你能分享一下复现方法或者你的部署情况吗?
我认为#124558可能会解决这个问题。你可以检查一下是否有所帮助吗?
@harshap804 仅供参考,在事件处理器中修改共享缓存并不是一个好主意。

相关问题