kubernetes 当重启kubelet时,带有initcontainer的pod失败并出现UnexpectedAdmissionError,

pkln4tw6  于 3个月前  发布在  Kubernetes
关注(0)|答案(8)|浏览(52)

发生了什么?
内存管理器有bug,重启kubelet(不要删除任何检查点文件),带有init-container的pod将失败。

你期望发生什么?
Pod A和Pod B仍然在运行。

我们如何尽可能精确地重现它?
我有一个节点有256Gi和2个NUMA节点,其中一个NUMA有128Gi;

  1. 创建Pod A,带有init-container和容器都是100Gi
  2. 创建Pod B,带有init-container和容器都是100Gi
  3. 重启kubelet。
  4. Pod A和Pod B都因UnexpectedAdmissionError而失败。

我们需要了解其他信息吗?
--topology-policy=single-numa-node模式下。
当内存管理器计算拓扑的内存时,它会首先计算init-container,当到达应用程序容器时,它会尽可能地重用init-container的内存,并减少init-container的状态内存,这是预期的;
kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go
第192行 in 9df98f3
| p.updateInitContainersMemoryBlocks(s, pod, container, containerBlocks) |
kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go
第956到965行 in 9df98f3
| ifinitContainerBlock.Size>blockSize { |
| initContainerBlock.Size-=blockSize |
| blockSize=0 |
| } else { |
| blockSize-=initContainerBlock.Size |
| initContainerBlock.Size=0 |
| } |
| } |
| |
| | s.SetMemoryBlocks(podUID, initContainer.Name, initContainerBlocks) |
但是当重启kubelet时,内存管理器将重新计算init-container的内存,如果现在节点没有足够的内存供init-container使用,整个pod将因为Admit失败而失败;

重启kubelet后:

Kubernetes版本:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.17", GitCommit:"a7736eaf34d823d7652415337ac0ad06db9167fc", GitTreeState:"clean", BuildDate:"2022-12-08T11:47:36Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.17", GitCommit:"a7736eaf34d823d7652415337ac0ad06db9167fc", GitTreeState:"clean", BuildDate:"2022-12-08T11:42:04Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}

云提供商:

# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here

操作系统版本:x1a2b1x

dbf7pr2w

dbf7pr2w2#

我认为我们需要通过更改逻辑来修复这个bug:如果init-container已经终止,跳过内存/CPU拓扑计算;
我们仍然不应该在重启kubelet后使任何运行的pod失败。

rqqzpn5f

rqqzpn5f3#

为什么kubelet重启时内存不够?它先计算主容器(100G),然后为初始化容器留下28Gi吗?

zaq34kh6

zaq34kh64#

当kubelet重启时,为什么内存不够?它会先计算主容器(100G),然后为初始化容器留出28Gi吗?

当kubelet重启时,它会再次计算节点上的所有pods,并按照pod中的容器顺序计算初始化容器和应用容器;

因为在检查点中,初始化容器的内存被认为是可以被主容器重用的,所以在检查点文件(/var/lib/kubelet/memory_manager_state)中,初始化容器会被移除。

ghhaqwfi

ghhaqwfi5#

这个是否存在于主分支?

ldfqzlk8

ldfqzlk86#

我们过去也遇到过类似的问题。我会查看并将它们关联起来。我认为这个问题是合理的,需要解决。将优先级设置为低,等待进一步调查。

lbsnaicq

lbsnaicq7#

关于已终止的pods在kubelet重启时重新进行准入,我记得还有一个问题。我认为我们不应该为这些容器进行准入,因为容器已经终止,不会消耗资源,但我们需要非常小心地评估这种更改的影响。
我会尝试找到并链接与此相关的问题:#117955

6tr1vspr

6tr1vspr8#

关于已终止的pods在kubelet重启时重新进行准入,我认为我们不应该为这些容器进行准入,因为容器已经终止,不会消耗资源,但我们需要非常小心地评估这种更改的影响。
我会尝试找到并链接与此相关的问题:#117955
是的,在kubelet重启时,应该跳过已终止的pods或pods中的已终止init-containers的准入。
在我们的情况下,重启kubelet导致pod失败是一个严重的问题。有时我们需要更新kubelet配置,例如更改pidMax或节点的反向资源,在这种情况下,pod失败将对在线服务产生不良影响。

相关问题