kubectl —— Kubernetes 命令行

运维工具手册 06-容器与编排 8.5 KB 原文

kubectl —— Kubernetes 命令行

分类:06 容器与编排 适用:K8s 1.2x ~ 1.3x(kubectl 与集群版本差不超过 ±1 个小版本) 一句话:查询、排障、变更、调试,K8s 日常运维 90% 的时间都在这条命令上。

1. 它解决什么问题

  • Pod 为什么起不来、为什么重启、为什么调度不上去。
  • 快速看某个服务的副本、镜像、资源限制、事件。
  • 改副本数、滚更新、回滚、扩缩容。
  • 临时把 Pod 端口映射到本地调试。

2. 配置与上下文

kubectl config view                          # 查看配置
kubectl config get-contexts                  # 所有上下文
kubectl config current-context
kubectl config use-context prod              # 切换
kubectl config set-context --current --namespace=myapp   # 设默认 ns
kubectl config rename-context old new

临时指定:

kubectl --context prod -n myapp get pods
kubectl --kubeconfig ~/.kube/prod.yaml get nodes

装补全(强烈建议):

source <(kubectl completion bash)
echo 'source <(kubectl completion bash)' >> ~/.bashrc

# 常用别名
alias k=kubectl
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kdp='kubectl describe pod'
alias kl='kubectl logs'

3. 查看资源

kubectl get nodes -o wide
kubectl get pods
kubectl get pods -A                          # 所有命名空间
kubectl get pods -o wide                     # 带 IP、节点
kubectl get pods -w                          # watch 实时变化
kubectl get pods --show-labels
kubectl get pods -l app=web                  # 标签筛选
kubectl get pods -l 'env in (prod,staging)'
kubectl get pods --field-selector status.phase!=Running
kubectl get all                              # 常用资源合集
kubectl get all -n myapp
kubectl api-resources                        # 所有资源类型与简称
kubectl explain deployment.spec.template     # 字段文档(离线)

输出格式(排障核心技能):

kubectl get pod web-xxx -o yaml
kubectl get pod web-xxx -o json | jq '.status'
kubectl get pods -o custom-columns='NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName'
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
kubectl get svc -o jsonpath='{.items[*].spec.clusterIP}'

常用简写:po pods、svc services、deploy deployments、sts statefulsets、ds daemonsets、cm configmaps、sec secrets、ns namespaces、no nodes、pv/pvc、ing ingress、ep endpoints。

4. 排障四件套

kubectl get pod <pod> -o wide            # 1. 状态、重启次数、节点
kubectl describe pod <pod>               # 2. Events(最关键)
kubectl logs <pod>                       # 3. 应用日志
kubectl logs <pod> --previous            # 4. 上次崩溃前的日志
kubectl logs <pod> -c <container>        # 多容器指定
kubectl logs -f --tail=100 <pod>
kubectl logs <pod> --since=10m

describe 重点看什么

Status:       Running
Containers:
  app:
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137
    Restart Count:  7
Events:
  Type     Reason     Age   From     Message
  Warning  BackOff    10s   kubelet  Back-off restarting failed container
  Warning  FailedScheduling 2m  scheduler  0/3 nodes are available: 3 Insufficient memory.
现象 常见原因
Pending + Insufficient cpu/memory 资源不足,调 requests 或扩容
Pending + node(s) had taint 污点未容忍
Pending + unbound PVC 存储没绑上
ImagePullBackOff 镜像名错、无 pull secret、网络不通
CrashLoopBackOff 应用启动失败,看 logs --previous 与 Exit Code
OOMKilled(137) 内存超 limits
CreateContainerConfigError ConfigMap/Secret 缺失
Evicted 节点资源压力驱逐
Terminating 卡住 finalizer 或节点失联

5. 变更操作

kubectl apply -f deploy.yaml
kubectl apply -f ./manifests/            # 整个目录
kubectl apply -f https://example.com/x.yaml
kubectl replace -f deploy.yaml
kubectl delete -f deploy.yaml
kubectl delete pod <pod>                 # 删除后由控制器重建
kubectl delete pod <pod> --force --grace-period=0   # 卡死时强制
kubectl edit deploy web                  # 在线编辑(谨慎)
kubectl diff -f deploy.yaml              # 预览差异(apply 前必做)

滚动更新与回滚

kubectl set image deploy/web app=registry/app:1.2.3
kubectl rollout status deploy/web
kubectl rollout history deploy/web
kubectl rollout history deploy/web --revision=2
kubectl rollout undo deploy/web                     # 回上一版
kubectl rollout undo deploy/web --to-revision=3
kubectl rollout restart deploy/web                  # 触发重建(不改配置)
kubectl rollout pause / resume deploy/web           # 金丝雀分批

扩缩容

kubectl scale deploy/web --replicas=5
kubectl scale --replicas=3 -f deploy.yaml
kubectl autoscale deploy/web --min=2 --max=10 --cpu-percent=70
kubectl get hpa

标签与注解

kubectl label pod <pod> env=prod --overwrite
kubectl label nodes node1 disk=ssd
kubectl annotate deploy/web note="release 1.2.3"

6. 调试

kubectl exec -it <pod> -- sh
kubectl exec -it <pod> -c <container> -- bash
kubectl exec <pod> -- env
kubectl exec <pod> -- cat /etc/config/app.yaml
kubectl cp <pod>:/var/log/app.log ./app.log
kubectl cp ./conf <pod>:/tmp/conf

kubectl port-forward pod/<pod> 8080:8080
kubectl port-forward svc/web 8080:80
kubectl port-forward deploy/web 8080:8080

kubectl top nodes
kubectl top pods -A --sort-by=memory

kubectl debug -it <pod> --image=nicolaka/netshoot --target=<container>
kubectl debug node/<node> -it --image=busybox
kubectl run tmp --rm -it --image=busybox --restart=Never -- sh

kubectl debug 是排查"镜像里没工具"的标准做法,--target 共享目标容器的进程命名空间。

7. 事件与审计

kubectl get events --sort-by=.lastTimestamp
kubectl get events -A --field-selector type=Warning
kubectl get events -w
kubectl get events --field-selector involvedObject.name=<pod>

kubectl auth can-i create pods
kubectl auth can-i --list -n myapp
kubectl auth whoami

8. 节点维护

kubectl cordon node1                 # 标记不可调度
kubectl drain node1 --ignore-daemonsets --delete-emptydir-data
kubectl uncordon node1
kubectl taint nodes node1 maintenance=true:NoSchedule
kubectl taint nodes node1 maintenance=true:NoSchedule-   # 去掉
kubectl describe node node1 | grep -A5 'Allocated resources'

drain 会驱逐 Pod,先确认有 PDB 保护和副本冗余。

9. 实战场景

9.1 Pod 起不来标准流程

kubectl get pod <pod> -o wide
kubectl describe pod <pod> | tail -30
kubectl logs <pod> --previous --tail=100
kubectl get events --field-selector involvedObject.name=<pod> --sort-by=.lastTimestamp

按状态对照第 4 节的表格判断。

9.2 找出重启最多的 Pod

kubectl get pods -A --sort-by='.status.containerStatuses[0].restartCount' \
  -o custom-columns='NS:.metadata.namespace,NAME:.metadata.name,RESTARTS:.status.containerStatuses[0].restartCount,STATUS:.status.phase' \
  | tail -20

9.3 批量看所有镜像

kubectl get pods -A -o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' \
  | sort | uniq -c | sort -nr

9.4 验证资源配置是否缺失

kubectl get pods -A -o json \
  | jq -r '.items[] | select(any(.spec.containers[]; .resources.limits == null)) | "\(.metadata.namespace)/\(.metadata.name)"'

9.5 发版失败回滚

kubectl set image deploy/web app=registry/app:1.2.4
kubectl rollout status deploy/web --timeout=120s || kubectl rollout undo deploy/web

9.6 临时在集群内排查网络

kubectl run nettest --rm -it --image=nicolaka/netshoot --restart=Never -- bash
# 容器内
nslookup kubernetes.default
curl -sv http://web.myapp.svc.cluster.local:8080/healthz

10. 常见坑

  1. 忘了 -n:默认 namespace 是 default,找不到资源时先确认命名空间或加 -A。
  2. kubectl logs 空:容器已崩溃重启,加 --previous;或日志写文件不在 stdout。
  3. describe 的 Events 只有最近 1 小时:过期事件会消失,重要问题及时留证。
  4. apply 与 create 混用:create 已存在会报错,统一用 apply。
  5. delete pod 会重建:控制器管理的 Pod 删了会回来,要停服务得改 Deployment 副本数或删控制器。
  6. edit 与 Git 冲突:手改的内容下次 apply 会被覆盖,生产禁用 edit。
  7. rollout undo 只回滚 Deployment 模板:ConfigMap/Secret 变更不会回滚。
  8. kubectl cp 需要 tar:目标镜像没有 tar 会失败(distroless 常见)。
  9. port-forward 断线即失效:长时间调试用 kubectl proxy 或 Service。
  10. --force --grace-period=0:可能留下孤儿容器,需节点上 crictl rm 清理。
  11. top pods 无数据:metrics-server 未装或未就绪。
  12. 大集群 get pods -A 很慢:加 -l、--field-selector 缩小范围。
  13. 别名掩盖参数:alias k=kubectl 后补全可能失效,配置 complete -F __start_kubectl k。
  14. kubectl 版本偏差:与集群差 2 个以上小版本会出现字段不识别。

11. 速查表

kubectl get pods -A -o wide
kubectl describe pod <pod>
kubectl logs <pod> --previous --tail=100
kubectl logs -f -c <container> <pod>
kubectl get events -A --sort-by=.lastTimestamp
kubectl apply -f x.yaml
kubectl diff -f x.yaml
kubectl delete -f x.yaml
kubectl set image deploy/web app=img:tag
kubectl rollout status/undo/history/restart deploy/web
kubectl scale deploy/web --replicas=5
kubectl exec -it <pod> -- sh
kubectl cp <pod>:/path ./
kubectl port-forward svc/web 8080:80
kubectl top pods -A --sort-by=memory
kubectl debug -it <pod> --image=nicolaka/netshoot --target=<c>
kubectl auth can-i --list -n <ns>
kubectl cordon/drain/uncordon <node>
kubectl config use-context <ctx>
kubectl get <res> -o yaml / jsonpath / custom-columns
kubectl —— Kubernetes 命令行 - 知识库 - 起航社区