Kubernetes 使用指南 — 各类场景命令全解

Kubernetes(简称 K8s)是当前业界标准的容器编排平台。无论你是刚入门的学习者,还是日常运维的一线工程师,掌握 kubectl 的核心命令都至关重要。

本文将按照 实际场景 组织命令,告别枯燥的 API 罗列,让你遇到问题时能快速找到对应「武器」。

K8s 架构简览

flowchart LR
subgraph Control Plane
API[API Server]
S[Scheduler]
CM[Controller Manager]
ETCD[(etcd)]
end
subgraph Worker Nodes
K[Kubelet]
P1[Pod A]
P2[Pod B]
end
subgraph Network
SVC[Service]
ING[Ingress]
end

API --> S
API --> CM
API --> K
CM --> P1
CM --> P2
S --> K
K --> P1
K --> P2
P1 -.-> SVC
P2 -.-> SVC
SVC -.-> ING

控制平面(Control Plane)负责决策与调度,工作节点(Worker Node)负责运行容器。本文的命令覆盖两端的常用操作。


一、集群信息与节点管理

# 查看集群信息
kubectl cluster-info

# 查看所有节点及状态
kubectl get nodes

# 查看节点详细信息(IP、资源、OS 等)
kubectl get nodes -o wide

# 查看节点详情(YAML 格式)
kubectl get node <node-name> -o yaml

# 描述节点(含资源使用、条件、事件)
kubectl describe node <node-name>

# 标记节点不可调度(维护用)
kubectl cordon <node-name>

# 恢复节点可调度
kubectl uncordon <node-name>

# 驱逐节点上所有 Pod(节点下线用)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# 查看节点资源占用(需安装 metrics-server)
kubectl top node

场景:节点维护

当需要重启或升级某台服务器时:

# 1. 标记不可调度,防止新 Pod 调度过来
kubectl cordon node-01

# 2. 驱逐已有 Pod(DaemonSet 忽略)
kubectl drain node-01 --ignore-daemonsets --delete-emptydir-data

# 3. 执行维护操作(重启、升级内核等)...

# 4. 恢复调度
kubectl uncordon node-01

二、Pod 管理

Pod 是 K8s 最小的部署单元。

# 创建 Pod(通过 YAML)
kubectl apply -f pod.yaml

# 查看所有命名空间下的 Pod
kubectl get pods --all-namespaces

# 查看当前命名空间 Pod
kubectl get pods

# 查看 Pod 详细信息
kubectl get pods -o wide
kubectl get pods -o yaml

# 查看 Pod 状态变化
kubectl get pods --watch

# 描述 Pod 详情(事件、条件、挂载等)
kubectl describe pod <pod-name>

# 删除 Pod
kubectl delete pod <pod-name>

# 强制删除 Pod(Terminating 卡住时)
kubectl delete pod <pod-name> --force --grace-period=0

# 查看 Pod 日志
kubectl logs <pod-name>

# 实时追踪日志
kubectl logs -f <pod-name>

# 查看前一个容器实例的日志(重启后)
kubectl logs <pod-name> --previous

# 多容器 Pod 指定容器名
kubectl logs <pod-name> -c <container-name>

# 进入 Pod 交互式终端
kubectl exec -it <pod-name> -- /bin/sh
kubectl exec -it <pod-name> -- /bin/bash

# 在 Pod 内执行单条命令
kubectl exec <pod-name> -- cat /etc/config

# 将本地文件拷贝到 Pod
kubectl cp /local/path/file.txt <pod-name>:/remote/path/

# 从 Pod 拷贝到本地
kubectl cp <pod-name>:/remote/path/file.txt /local/path/

# 查看 Pod 资源占用
kubectl top pod
kubectl top pod --containers

场景:Pod 一直 Pending

# 1. 看状态和事件
kubectl describe pod <pod-name>

# 2. 看节点是否有足够资源
kubectl top node

# 3. 检查 PVC 是否绑定
kubectl get pvc

# 4. 检查是否有污点/容忍度不匹配
kubectl describe node <node-name> | findstr Taints

场景:Pod 反复 CrashLoopBackOff

# 1. 看日志
kubectl logs <pod-name> --previous

# 2. 看事件
kubectl describe pod <pod-name>

# 3. 进入容器排查
kubectl exec -it <pod-name> -- /bin/sh

三、Deployment 管理

# 创建 Deployment
kubectl create deployment nginx --image=nginx:1.25

# 使用 YAML 创建/更新
kubectl apply -f deployment.yaml

# 查看 Deployment
kubectl get deployments

# 查看详细信息
kubectl get deployment <name> -o wide
kubectl describe deployment <name>

# 查看 Deployment 管理的 ReplicaSet
kubectl get rs

# 扩缩容
kubectl scale deployment <name> --replicas=5

# 自动扩缩容(需 metrics-server)
kubectl autoscale deployment <name> --min=2 --max=10 --cpu-percent=80

# 更新镜像
kubectl set image deployment/<name> nginx=nginx:1.26

# 查看滚动更新状态
kubectl rollout status deployment/<name>

# 查看历史版本
kubectl rollout history deployment/<name>

# 回滚到上一版本
kubectl rollout undo deployment/<name>

# 回滚到指定版本
kubectl rollout undo deployment/<name> --to-revision=2

# 暂停滚动更新(金丝雀发布用)
kubectl rollout pause deployment/<name>

# 恢复滚动更新
kubectl rollout resume deployment/<name>

# 删除 Deployment
kubectl delete deployment <name>

场景:滚动更新策略

spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多超出期望副本数 1 个
maxUnavailable: 0 # 更新期间不可用 Pod 数为 0(零停机)
# 实际更新
kubectl set image deployment/myapp myapp=myapp:v2

# 监控更新
kubectl rollout status deployment/myapp --watch

场景:金丝雀发布

# 1. 先搞一个 90% 版本的 Deployment
kubectl scale deployment myapp-stable --replicas=9

# 2. 再搞一个 10% 新版本的 Deployment
kubectl scale deployment myapp-canary --replicas=1

# 3. 验证无误后,将全部流量切到新版本
kubectl set image deployment/myapp-stable myapp=myapp:v2
kubectl scale deployment/myapp-canary --replicas=0

四、Service 网络管理

# 创建 Service(暴露 Pod)
kubectl expose deployment nginx --port=80 --target-port=80

# 创建 NodePort 类型 Service
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort

# 创建 LoadBalancer 类型 Service(云环境)
kubectl expose deployment nginx --port=80 --target-port=80 --type=LoadBalancer

# 查看 Service
kubectl get services
kubectl get svc -o wide

# 查看 Endpoints(Pod IP 列表)
kubectl get endpoints

# 描述 Service
kubectl describe svc <service-name>

# 删除 Service
kubectl delete svc <service-name>

场景:Service 类型选择

类型 访问方式 适用场景
ClusterIP service-ip:port(仅集群内) 内部服务通信
NodePort 节点IP:NodePort 外部调试 / 本地开发
LoadBalancer 云厂商 LB 提供外网 IP 生产对外服务
ExternalName CNAME 到外部域名 引入外部服务

Headless Service(有状态应用)

apiVersion: v1
kind: Service
metadata:
name: myapp-headless
spec:
clusterIP: None # 关键:设为 None
selector:
app: myapp
ports:
- port: 80

可通过 DNS 直接拿到 Pod IP 列表:

kubectl exec -it pod-shell -- nslookup myapp-headless

五、Ingress 流量接入

# 查看 Ingress
kubectl get ingress

# 查看详细信息
kubectl describe ingress <name>

# 查看 IngressClass
kubectl get ingressclass

常见 Ingress 配置示例

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 8080
# 应用 Ingress
kubectl apply -f ingress.yaml

六、ConfigMap 与 Secret

# 从文件创建 ConfigMap
kubectl create configmap app-config --from-file=config.properties

# 从字面值创建
kubectl create configmap app-config --from-literal=APP_ENV=production --from-literal=LOG_LEVEL=info

# 创建 Secret(Base64 自动编码)
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=s3cret

# 从文件创建 Secret
kubectl create secret generic tls-secret --from-file=tls.crt --from-file=tls.key

# 查看 ConfigMap
kubectl get configmaps
kubectl describe configmap <name>
kubectl get configmap <name> -o yaml

# 查看 Secret
kubectl get secrets
kubectl describe secret <name>
kubectl get secret <name> -o yaml

Pod 中挂载 ConfigMap

spec:
containers:
- name: myapp
image: myapp:1.0
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
envFrom:
- configMapRef:
name: app-config
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config

七、存储(PV / PVC)

# 查看 PersistentVolume
kubectl get pv

# 查看 PersistentVolumeClaim
kubectl get pvc

# 查看 StorageClass
kubectl get storageclass

# 删除 PVC
kubectl delete pvc <name>

# 如果 PVC 卡在 Terminating,移除 Finalizer
kubectl patch pvc <name> -p '{"metadata":{"finalizers":[]}}'

动态供应示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
storageClassName: standard
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# Pod 使用 PVC
spec:
containers:
- name: myapp
volumeMounts:
- mountPath: /data
name: data-volume
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: data-pvc

八、命名空间与资源隔离

# 查看所有命名空间
kubectl get namespaces

# 创建命名空间
kubectl create namespace staging

# 切换默认命名空间(临时)
kubectl config set-context --current --namespace=staging

# 在指定命名空间操作(一次性)
kubectl get pods -n staging

# 跨命名空间 Service 访问
# <service-name>.<namespace>.svc.cluster.local
ping web-service.production.svc.cluster.local

# 查看命名空间下所有资源
kubectl api-resources --verbs=list --namespaced -o name | ForEach-Object { kubectl get $_ -n staging }

# 删除命名空间(会删除其下所有资源!)
kubectl delete namespace staging

九、标签与选择器

# 为 Pod 打标签
kubectl label pod my-pod version=v2 env=prod

# 覆盖标签
kubectl label pod my-pod version=v3 --overwrite

# 根据标签查询 Pod
kubectl get pods -l env=prod
kubectl get pods -l 'env=prod,version=v2'
kubectl get pods -l 'env in (prod,staging)'

# 查看 Pod 标签
kubectl get pods --show-labels

# 删除标签
kubectl label pod my-pod version-

# 为节点打标签(控制调度)
kubectl label node node-01 disktype=ssd

节点选择器(Pod 调度到特定节点)

spec:
nodeSelector:
disktype: ssd

十、排错与调试

# 查看集群事件(按时间倒序)
kubectl get events --sort-by='.lastTimestamp'

# 持续监控事件
kubectl get events --watch

# 查看某资源相关事件
kubectl describe pod <name> # 底部 Events 段落

# 查看 API 请求详情(调试用)
kubectl get pods -v=6 # 显示 HTTP 请求
kubectl get pods -v=8 # 显示 HTTP 请求与响应
kubectl get pods -v=9 # 显示全部(最详细)

# DNS 调试(启动一个调试 Pod)
kubectl run -it dns-test --image=busybox --rm -- sh
# 在容器内:nslookup kubernetes.default.svc.cluster.local

# 临时调试 Pod(带网络工具)
kubectl run debug-pod --image=nicolaka/netshoot --rm -it -- /bin/bash

捕获网络流量

# 在指定 Pod 上抓包(需容器内安装 tcpdump)
kubectl exec <pod-name> -- tcpdump -i eth0 -w /tmp/capture.pcap

# 将抓包文件拷贝到本地
kubectl cp <pod-name>:/tmp/capture.pcap ./capture.pcap

端口转发(本地调试)

# 将本地 8080 转发到 Pod 的 80 端口
kubectl port-forward pod/<pod-name> 8080:80

# 将本地 8080 转发到 Service 的 80 端口
kubectl port-forward svc/<service-name> 8080:80

# 转发到 Deployment
kubectl port-forward deployment/<deployment-name> 8080:80

十一、污点与容忍度

# 为节点添加污点
kubectl taint nodes node-01 key=value:NoSchedule

# 查看节点污点
kubectl describe node node-01 | findstr Taints

# 删除污点
kubectl taint nodes node-01 key:NoSchedule-
kubectl taint nodes node-01 key=value:NoSchedule-

# 污点效果:
# NoSchedule - 不能调度新 Pod
# PreferNoSchedule - 尽量不调度
# NoExecute - 不能调度 + 驱逐已有 Pod

Pod 通过 tolerations 容忍污点:

spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"

十二、RBAC 权限控制

# 查看角色(Role / ClusterRole)
kubectl get roles --all-namespaces
kubectl get clusterroles

# 查看绑定
kubectl get rolebindings --all-namespaces
kubectl get clusterrolebindings

# 查看当前用户/ServiceAccount 权限
kubectl auth can-i create pods
kubectl auth can-i delete deployments --as system:serviceaccount:default:my-sa

# 创建 ServiceAccount
kubectl create serviceaccount deployer

# 查看 ServiceAccount 的 Secret Token
kubectl describe serviceaccount deployer

常见 RBAC 配置

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: pod-reader-binding
subjects:
- kind: ServiceAccount
name: deployer
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

十三、常用 YAML 速查

最小 Pod

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80

完整 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "mysql-service"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

Service + Deployment 完整示例

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: ClusterIP

十四、Job 与 CronJob

# 一次性任务
kubectl create job my-job --image=busybox -- echo "hello"

# 查看 Job
kubectl get jobs

# 定时任务
kubectl create cronjob backup --image=busybox --schedule="0 2 * * *" -- dump

# 查看 CronJob
kubectl get cronjobs

# 手动触发 CronJob
kubectl create job --from=cronjob/backup manual-backup-001

十五、K8s 常用别名与快捷键

在 shell 中配置别名能极大提升效率:

# 配置 kubectl 别名(建议加入 ~/.bashrc 或 ~/.zshrc)
alias k='kubectl'
alias kg='kubectl get'
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kd='kubectl describe'
alias kdp='kubectl describe pod'
alias kaf='kubectl apply -f'
alias kdf='kubectl delete -f'
alias kl='kubectl logs'
alias klf='kubectl logs -f'
alias kex='kubectl exec -it'
alias kpf='kubectl port-forward'
alias kgn='kubectl get nodes'
alias ke='kubectl get events --sort-by=.lastTimestamp'

# 开启 kubectl 自动补全
# Bash
source <(kubectl completion bash)

# Zsh
# source <(kubectl completion zsh)

# PowerShell
kubectl completion powershell | Out-String | Invoke-Expression

# 快速切换命名空间
alias kns='kubectl config set-context --current --namespace'

十六、集群外 kubectl 配置

# 查看当前配置
kubectl config view

# 查看当前上下文
kubectl config current-context

# 切换上下文
kubectl config use-context <context-name>

# 设置新集群
kubectl config set-cluster my-cluster --server=https://1.2.3.4:6443 --certificate-authority=ca.crt

# 设置凭据
kubectl config set-credentials my-user --client-certificate=client.crt --client-key=client.key

# 创建上下文
kubectl config set-context my-context --cluster=my-cluster --user=my-user

# 合并多个 kubeconfig
export KUBECONFIG=~/.kube/config:~/.kube/config-prod
kubectl config view --flatten > ~/.kube/config-merged

总结

场景 关键命令
查看集群 kubectl cluster-info / kubectl get nodes
部署应用 kubectl apply -f deployment.yaml
查看 Pod kubectl get pods -o wide
排查问题 kubectl describe pod / kubectl logs -f
扩缩容 kubectl scale deployment --replicas=N
滚动更新 kubectl set image deployment
暴露服务 kubectl expose deployment --type=NodePort
本地调试 kubectl port-forward pod/xxx 8080:80
进入容器 kubectl exec -it pod -- /bin/sh
配置管理 kubectl create configmap/secret
权限控制 kubectl auth can-i / kubectl create serviceaccount

小提示:加 --help 是学习 kubectl 最好的方式。例如 kubectl run --help 会列出所有参数与示例,比任何文档都更快。

掌握以上命令,你就能应对日常 90% 以上的 K8s 运维场景。建议收藏本文,需要时快速查阅 🐦