kuernetes 资源对象分析报错
创始人
2025-06-01 22:21:59

在这里插入图片描述

文章目录

    • 1. pod 状态
      • 1.1 容器启动错误类型
      • 1.2 ImagePullBackOff 错误
      • 1.3 CrashLoopBackOff
      • 1.4 Pending
    • 2. Service 连接状态
    • 3. Ingress 连接状态

1. pod 状态

创建一个 pod-status.yaml


apiVersion: v1
kind: Pod
metadata:name: runninglabels:app: nginx
spec:containers:- name: webimage: nginxports:- name: webcontainerPort: 80protocol: TCP---
apiVersion: v1
kind: Pod
metadata:name: backoff
spec:containers:- name: webimage: nginx:not-exist---
apiVersion: v1
kind: Pod
metadata:name: error
spec:containers:- name: webimage: nginxcommand: ["sleep", "a"]

然后,使用 kubectl apply 命令将它应用到集群内。

$ kubectl apply -f pod-status.yaml
pod/running created
pod/backoff created
pod/error created

接下来,使用 kubectl get pods 查看刚才创建的 3 个 Pod。

NAME                             READY   STATUS             RESTARTS        AGE
backoff                          0/1     ImagePullBackOff   0               50s
error                            0/1     CrashLoopBackOff   1               4s
running                          1/1     Running            0               50s

在这个例子中,我们一共创建了 3 个 Pod,它们的状态包含 ImagePullBackOffCrashLoopBackOffRunning

1.1 容器启动错误类型

  • ErrImagePull
  • ImageInspectError
  • ErrImageNeverPull
  • RegistryUnavailable
  • InvalidImageName

1.2 ImagePullBackOff 错误

原因导致:

  • 镜像名称或者版本错误,在我们刚才创建的 backoff Pod 中,我们指定的镜像为 nginx:not-exist,但是实际上镜像版本 not-exist 并不存在,自然也就会抛出错误。
  • 指定了私有镜像,但又没有提供拉取凭据。

我们可以使用 kubectl describe 命令来查看错误的详情。

$ kubectl describe pod backoff
Events:Type     Reason     Age                  From               Message----     ------     ----                 ----               -------Normal   Scheduled  10m                  default-scheduler  Successfully assigned default/backoff to kind-control-planeNormal   Pulling    8m43s (x4 over 10m)  kubelet            Pulling image "nginx:not-exist"Warning  Failed     8m40s (x4 over 10m)  kubelet            Failed to pull image "nginx:not-exist": rpc error: code = NotFound desc = failed to pull and unpack image "docker.io/library/nginx:not-exist": failed to resolve reference "docker.io/library/nginx:not-exist": docker.io/library/nginx:not-exist: not foundWarning  Failed     8m40s (x4 over 10m)  kubelet            Error: ErrImagePullWarning  Failed     8m11s (x6 over 10m)  kubelet            Error: ImagePullBackOffNormal   BackOff    4s (x42 over 10m)    kubelet            Back-off pulling image "nginx:not-exist"

从返回结果里 Event 事件中的第三行我们可以发现,集群抛出了 nginx:not-exist: not found 的异常,这样我们也就定位到了具体的错误。

1.3 CrashLoopBackOff

CrashLoopBackOff 是一种典型的容器运行阶段的错误。除此之外,你可能还会看到类似的 RunContainerError 错误。出现这个错误的原因主要有下面两个。

  • 容器内的应用程序在启动时出现了错误,例如配置读取失败导致无法启动。
  • 配置出错,例如配置了错误的容器启动命令。

在上面创建的 error Pod 的例子中,我故意错误地配置了容器的启动命令,这样我们也就看到了 CrashLoopBackOff 异常。对于运行阶段的错误,大部分错误都来源于业务本身的启动阶段,所以,我们只需要查看 Pod 的日志一般就能够找到问题所在。比如,我们尝试来查看 error Pod 的日志。

$ kubectl logs error
sleep: invalid time interval 'a'
Try 'sleep --help' for more information.

从返回的日志来看,sleep 命令抛出了一个异常,也就是参数错误。在生产环境下,我们一般会用 Deoloyment 工作负载来管理 Pod,在 Pod 出现运行阶段异常的情况下,Pod 名称会随着重新启动而出现变化,这时候你可以在查看日志时增加 --previous 参数,以此查看之前的 Pod 日志。

$ kubectl logs pod-name --previous

1.4 Pending

有时候,你可能不会看到启动和运行的错误状态,但查看状态时,会看到 Pod 处于 Pending 状态。你可以尝试将下面的内容保存为 pending-pod.yaml 文件,并通过 kubectl apppy -f 将这个例子部署到集群内。

apiVersion: v1
kind: Pod
metadata:name: pending
spec:containers:- name: webimage: nginxresources:requests:cpu: 32memory: 64Gi

接下来,尝试查看 Pod 的状态。

$ kubectl get pods
NAME                             READY   STATUS             RESTARTS         AGE
pending                          0/1     Pending            0                15s

从返回结果我们会发现,Pod 没有抛出任何异常,但它的状态处于 Pending,同时 READY 0/1 表示 Pod 没有准备好接收外部流量。出现 Pending 状态主要的原因可能有下面三种。

  1. 集群资源不足以调度 Pod。
  2. Pod 正在等待 PVC 持久化存储卷。
  3. Pod 资源用量超过了命名空间的资源配额。

在上面的例子中,我们为 Pod 配置了 32 核 64G 的资源请求配额,这显然超出了集群资源。此时 Pod 会处于 Pending 状态,并且 Kubernetes 会一直尝试调度,一旦加入了新的节点并满足资源要求,Pod 就会被重新启动。Pending 状态其实也算是容器启动异常的一种情况,但它并不能算是错误,只是暂时无法调度。要查明 Pending 状态的具体原因,你可以参考寻找容器启动错误的方法,通过 kubectl describe 命令来查看。

$ kubectl describe pod pending
Events:Type     Reason            Age    From               Message----     ------            ----   ----               -------Warning  FailedScheduling  11m    default-scheduler  0/1 nodes are available: 1 Insufficient cpu, 1 Insufficient memory. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.Warning  FailedScheduling  6m45s  default-scheduler  0/1 nodes are available: 1 Insufficient cpu, 1 Insufficient memory. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.

从返回结果的 Event 事件中我们可以得出结论,Pending 出现的原因是没有符合 CPU 资源条件的 Node 节点,Kubernetes 尝试调度了两次,异常情况相同。

2. Service 连接状态

有时候,即便是 Pod 处于运行且处于就绪状态,我们也无法从外部请求到业务服务。这时候就要关注 Service 的连接状态了。Service 是 Kubernetes 的核心组件,正常情况下它都是可用的。在生产环境下,流量的流向一般是从 Ingress 到 Service 再到 Pod。所以,当无法在外部访问到 Pod 的业务服务时,我们可以先从最内层也就是 Pod 开始检查,最简单的方式就是直连 Pod 并发起请求,查看 Pod 是否能够正常工作。

要在本地访问 Pod,我们可以使用 kubectl port-forward 进行端口转发,以我们刚才创建的 Nginx Pod 为例。

$ kubectl port-forward pod/running 8081:80

如果在本地访问 8081 端口请求能够成功,则代表 Pod 和业务层面是正常的。接下来,我们进一步检查 Service 的连接状态。同样地,最简单的方式也是通过端口转发直连 Service 发起请求。

$ kubectl port-forward service/ local_port:service_pod

如果请求 Service 能够正确返回内容,说明 Service 这一层也是正常的。如果无法返回内容,这时候通常可能有两个原因。

  • Service Selector 选择器没有正确匹配到 Pod。
  • Service 的 Port 和 TargetPort 配置错误。

通过修复这两项配置,你应该就能修复 Service 到 Pod 的连接问题了。

3. Ingress 连接状态

到这里,如果仍然无法从 Ingress 访问业务服务,那么就需要继续排查 Ingress 了。首先,确认 Ingress 控制器的 Pod 是否处于运行状态。

$ kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS        AGE
ingress-nginx-controller-8544b85788-c9m2g   1/1     Running     6 (4h35m ago)   1d

在确认 Ingress 控制器并无异常之后,基本上可以确认是 Ingress 策略配置错误导致的故障了。你可以通过 kubectl describe ingress 命令来查看 Ingress 策略。

$ kubectl describe ingress ingress_name
Name:             ingress_name
Namespace:        default
Rules:Host        Path  Backends----        ----  --------/     running-service:80 ()

相关内容

热门资讯

【实验报告】实验一 图像的... 实验目的熟悉Matlab图像运算的基础——矩阵运算;熟悉图像矩阵的显示方法࿰...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
大模型落地比趋势更重要,NLP... 全球很多人都开始相信,以ChatGPT为代表的大模型,将带来一场NLP领...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
kuernetes 资源对象分... 文章目录1. pod 状态1.1 容器启动错误类型1.2 ImagePullBackOff 错误1....
STM32实战项目-数码管 程序实现功能: 1、上电后,数码管间隔50ms计数; 2、...
TM1638和TM1639差异... TM1638和TM1639差异说明 ✨本文不涉及具体的单片机代码驱动内容,值针对芯...
Qt+MySql开发笔记:Qt... 若该文为原创文章,转载请注明原文出处 本文章博客地址:https://h...
Java内存模型中的happe... 第29讲 | Java内存模型中的happen-before是什么? Java 语言...
《扬帆优配》算力概念股大爆发,... 3月22日,9股封单金额超亿元,工业富联、鸿博股份、鹏鼎控股分别为3.0...
CF1763D Valid B... CF1763D Valid Bitonic Permutations 题目大意 拱形排列࿰...
SQL语法 DDL、DML、D... 文章目录1 SQL通用语法2 SQL分类3 DDL 数据定义语言3.1 数据库操作3.2 表操作3....
文心一言 VS ChatGPT... 3月16号,百度正式发布了『文心一言』,这是国内公司第一次发布类Chat...
CentOS8提高篇5:磁盘分...        首先需要在虚拟机中模拟添加一块新的硬盘设备,然后进行分区、格式化、挂载等...
Linux防火墙——SNAT、... 目录 NAT 一、SNAT策略及作用 1、概述 SNAT应用环境 SNAT原理 SNAT转换前提条...
部署+使用集群的算力跑CPU密... 我先在开头做一个总结,表达我最终要做的事情和最终环境是如何的,然后我会一...
Uploadifive 批量文... Uploadifive 批量文件上传_uploadifive 多个上传按钮_asing1elife的...
C++入门语法基础 文章目录:1. 什么是C++2. 命名空间2.1 域的概念2.2 命名...
2023年全国DAMA-CDG... DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义...
php实现助记词转TRX,ET... TRX助记词转地址网上都是Java,js或其他语言开发的示例,一个简单的...
【分割数据集操作集锦】毕设记录 1. 按要求将CSV文件转成json文件 有时候一些网络模型的源码会有data.json这样的文件里...
Postman接口测试之断言 如果你看文字部分还是不太理解的话,可以看看这个视频,详细介绍postma...
前端学习第三阶段-第4章 jQ... 4-1 jQuery介绍及常用API导读 01-jQuery入门导读 02-JavaScri...
4、linux初级——Linu... 目录 一、用CRT连接开发板 1、安装CRT调试工具 2、连接开发板 3、开机后ctrl+c...
Urban Radiance ... Urban Radiance Fields:城市辐射场 摘要:这项工作的目标是根据扫描...
天干地支(Java) 题目描述 古代中国使用天干地支来记录当前的年份。 天干一共有十个,分别为:...
SpringBoot雪花ID长... Long类型精度丢失 最近项目中使用雪花ID作为主键,雪花ID是19位Long类型数...
对JSP文件的理解 JSP是java程序。(JSP本质还是一个Servlet) JSP是&#...
【03173】2021年4月高... 一、单向填空题1、大量应用软件开发工具,开始于A、20世纪70年代B、20世纪 80年...
LeetCode5.最长回文子... 目录题目链接题目分析解题思路暴力中心向两边拓展搜索 题目链接 链接 题目分析 简单来说࿰...