即使在高成熟度级别 Kubernetes 集群中 pod pending 也是无处不在。
创新互联建站是一家朝气蓬勃的网站建设公司。公司专注于为企业提供信息化建设解决方案。从事网站开发,网站制作,网站设计,网站模板,微信公众号开发,软件开发,小程序设计,十载建站对轻质隔墙板等多个行业,拥有多年的网站设计经验。
如果您随机询问任何使用 Kubernetes DevOps 工程师来确定折磨他们噩梦的最常见错误,pod pending 可能是非常常见的问题(可能仅次于 CrashLoopBackOff)。
尝试推送更新并看到它卡住会使 DevOps 紧张。即使解决方案相当简单,找到 pod 挂起的原因并了解您需要应用的更改也很重要(Kubernetes 故障排除很少是微不足道的)。
在本文中,我们将阐明导致此问题的不同情况,让 DevOps 团队能够快速找到解决方案,最重要的是,尽可能避免它。
Kubernetes 中的 Pod 的生命周期由几个不同的阶段组成:
大多数 pod 只需要几秒钟就可以从 Pending 到 Running 并在该状态下度过大部分时间。
至此,Pod 已被 Kubernetes 集群接受。但是一个或多个容器尚未准备好对外提供服务。这包括 Pod 等待调度所花费的时间以及通过网络下载容器镜像所花费的时间。
当 pod 无法从 PendingtoRunning 阶段前进时,生命周期将停止并保留 pod,直到阻止它前进的问题得到修复。
如果我们使用 kubectl 列出 pod,我们将看到显示 Kubernetes pod 挂起情况的输出:
$ kubectl -n troubleshooting get pods
NAME READY STATUS RESTARTS AGE
stress-6d6cbc8b9d-s4sbh 0/1 Pending 0 17s
除非我们解决问题,否则 pod 被卡住并且不会运行。
有几个原因可以阻止 Pod 运行,但我们将描述三个主要问题:
第一个是最常见的,最后一个很少见。让我们详细说明每种情况。
创建 Pod 后,Kubernetes 集群做的第一件事就是尝试调度 Pod 在其中一个节点上运行。这个过程通常非常快,并且 pod 被快速分配给具有足够资源来运行它的节点。
为了放置它,集群中的 Pod 被分配给具有更多未请求资源的节点,并继续其快乐而美好的生活,其中充满了对请求的符合 SLO 的回复。
但是,如果此过程每次都有效,有几个因素可能导致集群无法分配 pod。
让我们回顾一下最常见的。
Kubernetes 使用调度请求来决定fits节点中是否有 pod。资源的真正使用无关紧要,只有其他 pod 已经请求的资源。
effective requests当一个 pod 有足够的可请求资源来参与该 pod 的内存和 CPU 时,它将被调度到一个节点中。并且节点必须没有达到它可以运行的最大 pod 数。
当没有任何节点满足 pod 的所有要求时,它将保持在 Kubernetes pod 挂起状态,直到释放一些资源。
由于不同的问题(节点压力)或人为行为(节点封锁),节点可能会变为不可调度的状态。这些节点在状态发生变化之前不会调度任何 pod。
污点是 Kubernetes 的一种机制,它允许我们限制可以分配给不同节点的 pod。当节点具有 taint 时,只有匹配容忍度的 pod 才能在该节点中运行。
这种机制允许 Kubernetes 的特殊用途,例如为不同的工作负载使用不同类型的节点(具有 GPU 的节点,具有不同的 CPU/内存比率等)。
即使我们分别描述每个原因,调度问题也往往是由这些问题的组合引起的。通常,您无法调度,因为某些节点已满而其他节点已被污染,或者某个节点可能由于内存压力而无法调度。
为了找出调度问题是什么,您需要查看调度程序生成的关于 pod 的事件,其中将详细描述阻止节点分配的原因。我们可以使用 kubectl describe 查看事件,例如:
$ kubectl -n troubleshooting describe pod stress-6d6cbc8b9d-s4sbh
Name: stress-6d6cbc8b9d-s4sbh
Namespace: troubleshooting
Priority: 0
Node:
Labels: app=stress
pod-template-hash=6d6cbc8b9d
Annotations:
Status: Pending
IP:
IPs:
Controlled By: ReplicaSet/stress-6d6cbc8b9d
Containers:
stress:
Image: progrium/stress
Port:
Host Port:
Args:
--cpu
1
--vm
2
--vm-bytes
150M
Limits:
cpu: 300m
memory: 120000Mi
Requests:
cpu: 200m
memory: 100000Mi
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-snrww (ro)
Conditions:
Type Status
PodScheduled False
Volumes:
kube-api-access-snrww:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional:
DownwardAPI: true
QoS Class: Burstable
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 4m17s (x41 over 34m) default-scheduler 0/5 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 4 Insufficient memory.
我们可以在输出中看到消息中的确切原因:
0/5 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 4 Insufficient memory.
为了解决这个问题,我们有两个选择:
如果要更新当前运行的工作负载,还需要考虑另一个重要因素:升级策略。
由于此策略,Kubernetes 可以允许工作负载在更新过程中创建比平时更多的 Pod,在创建新 Pod 时保留旧 Pod 一段时间。这意味着工作负载可能会在一段时间内请求比预期更多的资源。如果集群没有足够的备用资源,更新将被阻塞,留下一些 pod 待处理,直到进程被解除阻塞(或回滚超时停止更新)。
一旦在一个节点中分配了 pod,kubelet就会尝试启动 pod 中的所有容器。为此,它将尝试下载镜像并运行它。
有几个错误会阻止镜像被下载:
在 pod 启动之前,kubelet将尝试检查与其他 Kubernetes 元素的所有依赖关系。如果无法满足这些依赖项之一,则 pod 将保持挂起状态,直到满足依赖项。
在这种情况下,kubectl 将像这样显示 pod:
$ kubectl -n mysql get pods
NAME READY STATUS RESTARTS AGE
mysql-0 0/1 ContainerCreating 0 97s
在事件中,我们可以看到如下内容:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m19s default-scheduler Successfully assigned mysql/mysql-0 to ip-172-20-38-115.eu-west-1.compute.internal
Warning FailedMount 76s kubelet Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[kube-api-access-gxjf8 data config]: timed out waiting for the condition
Warning FailedMount 71s (x9 over 3m19s) kubelet MountVolume.SetUp failed for volume "config" : configmap "mysql" not found
该 Message 列将为您提供足够的信息,以便能够查明缺失的元素。常见的原因有:
了解 pod 保持在该 Pending 阶段的原因是在 Kubernetes 中安全部署和更新工作负载的关键。能够快速定位问题并加快部署进度将为您省去一些麻烦并减少停机时间。
文章题目:彻底搞懂K8SPodPending故障原因及解决方案
网页URL:http://www.36103.cn/qtweb/news25/27575.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联