Kubernetes 操作手册

9 分钟
本页目录

排障先锁定集群和 namespace,再沿 Pod → EndpointSlice → Service → Ingress 的关系缩小范围。状态字段、探针、连通性和业务正确性分别提供不同证据。

当前任务入口
确认操作对象上下文与资源
Pod 不就绪或重启事件与容器日志
应用在跑却访问不到流量与配置对应
发布、回滚与调试操作后验证

固定 context 与 namespace

# 列出 context 与对应集群、用户和默认 namespace
kubectl config get-contexts

星号标识当前选择,kubectl config current-context 只显示该名字。下文将 your-context 替换为已核对的 context,default 替换为目标 namespace;每条命令显式指定,复制某一节也不会依赖前文变量。

# 查看目标 namespace 的工作负载、入口与存储声明
kubectl --context your-context -n default get deploy,svc,ingress,pvc

这些资源回答不同层的配置是否存在;Pod 实际位置用下面的查询。NotFound 先查名称与 namespace,Forbidden 则查授权。

# 取得 Pod 名称、就绪数、重启次数、IP 和节点
kubectl --context your-context -n default get pods -o wide

-o wide 增加 IP 与节点等列。下文 your-pod 从此列表取得;app 是容器名,通过 describe 的 Containers 部分核对。

# 查询集群级节点状态,不受 namespace 限制
kubectl --context your-context get nodes -o wide

Ready 不证明所有工作负载可调度;还要结合资源请求、污点和亲和性。

# 检查当前身份是否有目标范围的 Pod 查询权限
kubectl --context your-context -n default auth can-i get pods

返回 yes / no;只能回答该 verb/resource 的授权,不证明 API 可用或其他操作获准。

将示例 context、namespace 与资源名替换为已核对的目标。查询 Secret 列表不必导出内容;排查 RBAC 时 impersonation 也需要权限,--as 不是绕过授权。

Pod 状态只告诉你停在哪一段

先读事件与各容器状态

# 读取调度事件、探针、挂载和容器状态
kubectl --context your-context -n default describe pod your-pod

区分当前 State 与 Last State,记录退出码、原因、事件时间和重复次数。事件会过期,不能把没有事件当成从未出错。

# 读当前容器实例最近的一百行日志
kubectl --context your-context -n default logs your-pod -c app --tail=100

-c 选择容器而非 Pod;多容器 Pod 应明确名称。持续观察加 -f,按 Ctrl-C 结束日志跟随。

# 读取上一次已退出实例的日志
kubectl --context your-context -n default logs your-pod -c app --previous --tail=100

重启循环时优先查这一份;没有上次实例或日志已丢失会报错,不是让你再重启一次。

# 按事件对象创建时间查看 namespace 内的相关故障
kubectl --context your-context -n default get events --sort-by=.metadata.creationTimestamp

排序不是每次重复发生的精确时间线;结合 describe 的 Last Seen 与计数定位。下表按症状选择下一层。

现象检查
Pending / FailedSchedulingEvents 中的 requests、配额、亲和性、污点、PVC 绑定;不只看 CPU 空闲
ImagePullBackOff镜像名/tag、registry 访问、认证和限流;节点能拉取才有意义
CrashLoopBackOff退出码、lastState、上次实例日志、启动/liveness 探针;这是重试退避状态
Running / 0/1 Readyreadiness、readiness gates、各容器状态;Running 不等于能接流量

让配置字段与流量路径对应起来

正在呈现知识画面
Service 选到了谁,又把流量送到哪里

普通 selector Service 需要标签匹配、Ready 后端和正确 targetPort。Pod Running 或 port-forward 成功不能单独验证 ClusterIP 路径。

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - name: http
      port: 80
      targetPort: 8080

这个 Service 选择同 namespace 内标签 app: web 的 Pod,再连接其 8080。应用必须实际监听 Pod 可达地址的 8080;声明 containerPort 不会打开端口,整数 targetPort 也不要求声明 containerPort。命名 targetPort 则需要对应命名端口。

选择器、端点和端口逐层核对

上面的 YAML 是完整 Service 对象示例,保存为 service.yaml 时仍需按发布流程 dry-run / apply;它本身不会创建 Pod。

# 检查与 Service selector 匹配的 Pod
kubectl --context your-context -n default get pods -l app=web --show-labels

无结果先确认标签与 namespace;不要立即改 Service 端口。

# 查看 web 的实际后端地址、端口和就绪条件
kubectl --context your-context -n default get endpointslice -l kubernetes.io/service-name=web -o yaml

核对 endpoints.addresses、conditions.ready、ports.port;EndpointSlice 可能有多个。端点存在仍需检查网络策略、CNI 与应用监听。

# 核对 Service 的 selector、port 与 targetPort
kubectl --context your-context -n default describe service web

请求 Service 使用 port;最终应用应监听 targetPort。命名端口需能解析到 Pod 中同名容器端口。

端口转发只验证它经过的路径

# 在 kubectl 客户端开放本地调试端口
kubectl --context your-context -n default port-forward service/web 8080:80

保持此终端运行,在客户端另一终端 curl -v http://127.0.0.1:8080/;Ctrl-C 结束转发。选中的 Pod 结束后可能需要重新建立连接。

# 从实际业务客户端 Pod 测试 Service 路径
kubectl --context your-context -n default exec client-pod -c app -- curl -v http://web.default.svc.cluster.local/

client-pod/app 换成被允许访问且带 curl 的客户端;default 与 cluster.local 换成实际 namespace 和集群域。该检查覆盖客户端身份下的 DNS 与 Service 路径,再从外部单独测 Ingress。

EndpointSlice 无目标先查 selector 和命名空间;有地址但不就绪查 readiness。端口转发通过 API 通道直达选中的 Pod,⁠不会验证 ClusterIP 的转发、集群 DNS 或 Ingress。验证 Service 要从合适的集群客户端访问 Service DNS/ClusterIP,再单独检查 Ingress 的 host/path/backend、控制器与外部入口。

发布与调试都要验证作用范围

审阅清单、验证 API,再实际应用

# 比较审阅过的清单与当前 API 对象
kubectl --context your-context -n default diff -f manifest.yaml

manifest.yaml 是本次完整变更文件;检查其中 namespace 与集群级对象的实际范围。返回 0 表示无差异,1 表示有差异,其他错误先处理。

# 请求服务器校验与默认化,但不持久保存对象
kubectl --context your-context -n default apply --dry-run=server -f manifest.yaml

会访问 API 与 admission,错误需修复;成功也不证明镜像能拉取或业务可用。

# 写入已审阅并验证的资源声明
kubectl --context your-context -n default apply -f manifest.yaml

根据输出确认 created/configured/unchanged 的对象与预期一致,再观察 rollout。

# 等待 Deployment 的发布状态完成或超时
kubectl --context your-context -n default rollout status deployment/web --timeout=120s

超时先查新 ReplicaSet、Pod Events 与日志;成功后仍需实际请求。不要把等待超时误当成自动回滚。

先确认目标 revision,再回滚

# 列出可用的 Deployment 模板历史
kubectl --context your-context -n default rollout history deployment/web

以 rollout history deployment/web --revision=2 查看候选;2 必须换成已核对的 revision。

# 将工作负载模板恢复到已审阅的 revision
kubectl --context your-context -n default rollout undo deployment/web --to-revision=2

接着重新观察 rollout status、Pod 与请求。数据库、外部系统和独立 ConfigMap 的内容不随之恢复。

diff 返回 1 通常表示存在差异,不是命令执行故障;server dry-run 会访问 API/admission。rollout 成功后仍需检查实际请求。rollout undo 只恢复工作负载模板历史,不回滚数据库;rollout restart 触发新 Pod,不修改镜像标签内容。

容器有工具时直接 exec

# 在目标容器内启动交互 shell
kubectl --context your-context -n default exec -it your-pod -c app -- sh

-- 后是容器内命令,-i 保持输入,-t 分配终端。这里只是运行新进程,不更换主进程;退出 shell 不删除 Pod。

精简镜像缺工具时选择临时调试容器

# 向现有 Pod 添加临时调试容器
kubectl --context your-context -n default debug -it your-pod --image=busybox:1.37 --target=app

这是 exec 的替代诊断路径,需权限及策略允许;镜像替换为项目批准的版本。退出后记录仍属于该 Pod,不能单独删除临时容器字段。

复制文件时明确方向与容器

# 将诊断文件复制到客户端当前目录
kubectl --context your-context -n default cp your-pod:/tmp/report.txt ./report.txt -c app

先确认目标文件不会被覆盖,并验证文件内容/大小。反向复制会写入容器;kubectl cp 通常要求容器内有 tar,失败先读报错。

kubectl debug 在已有 Pod 中添加临时调试容器,需要集群策略允许;运行时决定 target 进程可见性。kubectl run debug ... 是另建 Pod,网络身份与策略可能不同。kubectl cp 通常依赖容器内 tar;镜像精简时不要误判成网络故障。删除受 Deployment 管理的 Pod 会被重建,排障先保存日志和事件。

Debug Services · Debug Pods · EndpointSlices