kubectl 排障实战:jsonpath 精准取值、custom-columns、events 排序与 top 速查

kubectl 排障实战:jsonpath 精准取值、custom-columns、events 排序与 top 速查

线上 Pod 出问题,别一上来就 kubectl get pods 然后一堆 describe 翻半天。kubectl 本身带了一套很强的查询和排障能力,用好了定位问题能快好几倍。这篇不讲怎么装、怎么创建资源,只讲出问题时最该会的那几招命令:精准取字段、自定义列、按时间看事件、看谁在吃资源。全是能直接抄进终端的。

events 一定要按时间排序,默认顺序会误导你

排障第一反应是看事件,但很多人直接 kubectl get events,结果事件是乱序的(默认按资源名之类排,不是按时间),你根本看不出「先发生了什么、后发生了什么」。

正确姿势永远带排序:

bash 复制代码
# 按事件最后发生时间排序,最新的在最下面
kubectl get events --sort-by='.lastTimestamp'

# 只看某个命名空间,并且盯着实时刷新
kubectl get events -n prod --sort-by='.lastTimestamp' -w

# 只看某个 Pod 相关的事件(排障单个 Pod 时最有用)
kubectl get events --field-selector involvedObject.name=my-pod-xxxx \
    --sort-by='.lastTimestamp'

--field-selector involvedObject.name=<pod> 这招很多人不知道,能直接过滤出跟某个对象相关的事件,不用在几百条 events 里大海捞针。

kubectl top:先看谁在吃 CPU/内存

Pod 被 OOMKilled、节点负载高,先用 top 看实际用量(需要集群装了 metrics-server):

bash 复制代码
# 看各节点资源用量
kubectl top nodes

# 看某命名空间 Pod 用量,按内存倒序,一眼看出内存大户
kubectl top pods -n prod --sort-by=memory

# 按 CPU 排序
kubectl top pods -n prod --sort-by=cpu

# 看某个 Pod 内每个容器分别用了多少(多容器 Pod 排障必备)
kubectl top pod my-pod-xxxx --containers

--sort-by=memory 排完,排最前面的往往就是内存泄漏或配置不当的那个。配合下面的 jsonpath 看它的 limits,就能判断是不是快撞上限了。

jsonpath:从一坨 YAML 里精准抠出你要的那个字段

kubectl get pod -o yaml 输出几百行,你其实只想知道「这个 Pod 的镜像是啥」「它调度到哪个节点了」「重启了几次」。用 -o jsonpath 直接抠:

bash 复制代码
# 取某个 Pod 的镜像
kubectl get pod my-pod -o jsonpath='{.spec.containers[0].image}'

# 取它被调度到的节点
kubectl get pod my-pod -o jsonpath='{.spec.nodeName}'

# 取容器重启次数(排查 CrashLoop 时看这个)
kubectl get pod my-pod -o jsonpath='{.status.containerStatuses[0].restartCount}'

# 取上次退出的原因和 exit code(OOMKilled 就在这)
kubectl get pod my-pod \
    -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'

批量场景更能体现价值。比如「列出所有 Pod 用到的镜像去重」------排查某个坏镜像影响面时特别有用:

bash 复制代码
# range 遍历所有 Pod 的所有容器,打印镜像,再排序去重
kubectl get pods -A -o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' \
    | sort -u

再比如「找出所有没配 resources.limits 的 Pod」------这种 Pod 是节点被打爆的隐患:

bash 复制代码
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.containers[*].resources.limits}{"\n"}{end}' \
    | grep -vE 'map\[.+\]'   # 过滤掉 limits 非空的,剩下的就是没配 limits 的

jsonpath 语法几个要点:.items[*] 遍历列表,{range}...{end} 做循环,{"\n"}{"\t"} 插入换行和制表符方便后续处理。

custom-columns:把关心的字段拉成一张表

jsonpath 适合抠单个值,但要同时看多个字段并排成表格 ,用 custom-columns 更清爽。比如一眼看全部 Pod 的「名字 / 节点 / 状态 / 重启次数」:

bash 复制代码
kubectl get pods -o custom-columns=\
'NAME:.metadata.name,'\
'NODE:.spec.nodeName,'\
'STATUS:.status.phase,'\
'RESTARTS:.status.containerStatuses[0].restartCount'

输出直接是对齐的表格:

复制代码
NAME              NODE       STATUS    RESTARTS
web-5d8f-abcde    node-1     Running   0
web-5d8f-fghij    node-2     Running   7
api-7c9-klmno     node-1     Running   0

一眼就看出 web-5d8f-fghij 重启了 7 次,有问题。再比如排查「哪些 Pod 调度在哪些节点、用的什么镜像」:

bash 复制代码
kubectl get pods -A -o custom-columns=\
'NS:.metadata.namespace,'\
'POD:.metadata.name,'\
'NODE:.spec.nodeName,'\
'IMAGE:.spec.containers[0].image'

custom-columns 和 jsonpath 的区别:前者出表格适合人看多字段,后者出裸值适合抠单值喂给脚本。

看日志的几个实用姿势

bash 复制代码
# 看崩溃前的日志(容器已重启,当前实例的日志看不到问题了)
kubectl logs my-pod --previous

# 多容器 Pod 指定容器
kubectl logs my-pod -c sidecar

# 按标签一次看一组 Pod 的日志(比如一个 Deployment 的所有副本)
kubectl logs -l app=web --tail=50 --prefix

# 只看最近 5 分钟
kubectl logs my-pod --since=5m

--previous 是排查 CrashLoopBackOff 的关键:容器崩了会重启,当前实例的日志是重启后的、往往看不出崩溃原因,--previous 才能看到上一个挂掉的实例留下的日志。

kubectl explain:忘了字段怎么写就查它,别翻网页

写 YAML 记不清某个字段的层级和类型,不用去翻官网文档,本地就能查:

bash 复制代码
# 查 Pod spec 下有哪些字段
kubectl explain pod.spec

# 深入查某个字段的子字段和含义
kubectl explain pod.spec.containers.resources

# 递归展开整棵字段树
kubectl explain pod.spec.containers --recursive

它读的是你集群当前 API server 的 schema,所以查出来的字段和你集群版本一定对得上,比搜到的旧文档靠谱。

一个组合拳:快速定位「集群里最不健康的 Pod」

把上面几招串起来,一行找出所有非 Running 且重启多的 Pod:

bash 复制代码
# 列出所有 Pod,过滤掉 Running 的,再看谁重启次数高
kubectl get pods -A -o custom-columns=\
'NS:.metadata.namespace,POD:.metadata.name,STATUS:.status.phase,'\
'RESTARTS:.status.containerStatuses[0].restartCount' \
    | grep -v Running

# 或者直接用 field-selector 只捞非 Running 的(server 端过滤,更快)
kubectl get pods -A --field-selector status.phase!=Running

--field-selector 是在 API server 端过滤的,比拉全量再本地 grep 快,尤其大集群。注意它支持的字段有限(主要是 status.phasespec.nodeNamemetadata.name 这些),不是所有字段都能用。

小结

  • 看事件永远带 --sort-by='.lastTimestamp' ,默认乱序会误导时间线;定位单对象加 --field-selector involvedObject.name=<pod>
  • kubectl top nodes/pods --sort-by=memory 快速揪出资源大户,多容器加 --containers
  • jsonpath 抠单值 (镜像、节点、重启次数、退出原因),配 {range}{end} 做批量;custom-columns 拉多字段表格给人看。
  • 排 CrashLoop 用 kubectl logs --previous 看崩溃前日志;按组看日志用 -l 标签 --prefix
  • 忘字段用 kubectl explain,读的是当前集群 schema 最靠谱;非 Running 快筛用 --field-selector status.phase!=Running

一句话记忆点:排障别只会 get 和 describe------events 要排序、字段用 jsonpath/custom-columns 精准取、崩溃日志加 --previous,这几招能把定位时间砍一半。

相关推荐
Doraemomo15 分钟前
Linux编程-epoll多路IO复用
linux·运维·服务器
wtblszn19 分钟前
城市二供泵站远程监控运维系统物联网方案
运维·物联网
李昊哲小课20 分钟前
Spring Boot 4 旅游主题实战教程 阶段二:Web 开发基础
前端·spring boot·旅游
白猫不黑29 分钟前
运维如何转安全(个人经验篇)
运维·学习·安全·web安全·网络安全·信息安全
Tanner_SL37 分钟前
Linux笔记之PATH, LD_LIBRARY_PATH和LIBRARY_PATH的区别
linux·运维·笔记
是稻香啊1 小时前
HarmonyOS7 国际化适配:i18n 让你的 App 走向全球
运维·服务器·国际化·arkts·arkui·harmonyos7
ITmaster07311 小时前
从零到一!前端搭建本地轻量化 RAG 问答系统
前端
無法複制1 小时前
Windows10安装配置Docker Desktop教程
运维·docker·容器
AI智图坊1 小时前
宠物用品电商视觉内容生产的技术难点与自动化方案分析
大数据·运维·人工智能·ai作画·自动化·aigc