K8s 学习笔记(八):排错与运维

写在前面

本文是 K8s 学习笔记系列的最后一篇,介绍生产环境的排错方法、监控告警和 Helm 包管理。前置知识:安全与 RBAC(第七篇)。


一、排错方法论

1.1 排错流程

1
2
3
4
5
6
1. 定位问题层级(应用 / K8s / 基础设施)
2. 查看 Pod 状态和事件
3. 查看容器日志
4. 进入容器排查
5. 查看相关资源状态(Service、Ingress、PVC 等)
6. 检查节点状态和资源

1.2 按症状排查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Pod 一直 Pending
  → kubectl describe pod 看 Events
  → 原因:资源不足、PVC 未绑定、镜像拉取失败

Pod CrashLoopBackOff
  → kubectl logs --previous 看崩溃日志
  → 原因:应用启动失败、健康检查失败、OOMKilled

Pod ImagePullBackOff
  → kubectl describe pod 看 Events
  → 原因:镜像名错误、仓库认证失败、网络不通

Service 无法访问
  → kubectl get endpoints 检查是否有后端
  → 原因:selector 不匹配、Pod 不 Ready、端口不对

Ingress 不通
  → kubectl describe ingress 看 Events
  → 原因:Ingress Controller 未安装、规则配置错误、DNS 未解析

Pod 间网络不通
  → 用 debug Pod 测试 DNS 和连通性
  → 原因:DNS 问题、NetworkPolicy 阻断、CNI 插件问题

1.3 排错命令速查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Pod 排错
kubectl describe pod <pod>                       # 看 Events
kubectl logs <pod> -f --tail=100                 # 看日志
kubectl logs <pod> --previous                    # 看上次崩溃日志
kubectl exec -it <pod> -- sh                     # 进入容器
kubectl get events --sort-by=.lastTimestamp       # 看集群事件

# Service 排错
kubectl get endpoints <service>                 # 检查后端 Pod
kubectl describe svc <service>                  # 看 selector 和端口

# 节点排错
kubectl describe node <node>                    # 看条件和资源
kubectl top nodes                               # 看资源使用

# 网络排错
kubectl run debug --image=busybox --rm -it -- sh
# 在 debug Pod 中:
nslookup <service>                             # DNS 测试
wget -qO- http://<service>:<port>              # 连通性测试

二、监控

2.1 监控体系

1
2
3
4
Metrics Server    — K8s 内置指标(CPU/内存)
Prometheus        — 指标采集和存储
Grafana           — 可视化仪表盘
Alertmanager      — 告警通知

2.2 Metrics Server

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 安装
minikube addons enable metrics-server
# 或
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 使用
kubectl top nodes                  # 节点资源
kubectl top pods                    # Pod 资源
kubectl top pods -n dev             # 指定命名空间
kubectl top pods --sort-by=memory   # 按内存排序

2.3 Prometheus + Grafana

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 用 Helm 安装 kube-prometheus-stack(包含 Prometheus + Grafana + Alertmanager)
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install monitoring prometheus-community/kube-prometheus-stack -n monitoring --create-namespace

# 查看
kubectl get pods -n monitoring

# 访问 Grafana
kubectl port-forward svc/monitoring-grafana 3000:80 -n monitoring
# 浏览器访问 http://localhost:3000
# 默认账号:admin / prom-operator

2.4 关键监控指标

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Pod 层面:
  CPU 使用率         → container_cpu_usage_seconds_total
  内存使用率         → container_memory_working_set_bytes
  重启次数           → kube_pod_container_status_restarts_total
  OOMKilled          → kube_pod_container_status_last_terminated_reason

节点层面:
  CPU 使用率         → node_cpu_seconds_total
  内存使用率         → node_memory_MemAvailable_bytes
  磁盘使用           → node_filesystem_avail_bytes
  网络流量           → node_network_transmit_bytes_total

应用层面:
  HTTP 请求量        → 自定义 metrics
  响应时间           → 自定义 metrics
  错误率             → 自定义 metrics

三、日志管理

3.1 日志架构

1
2
3
4
5
6
7
容器 stdout/stderr → 容器运行时收集 → kubelet 存储
                              日志收集 Agent(Fluentd/Filebeat)
                              日志存储(Elasticsearch / Loki)
                              日志查询(Kibana / Grafana)

3.2 应用日志最佳实践

1
2
3
4
5
6
7
// 日志输出到 stdout/stderr(K8s 自动收集)
log.Println("处理请求", "path", r.URL.Path, "status", statusCode)

// 结构化日志(方便日志平台解析)
// 使用 JSON 格式
log.Printf(`{"time":"%s","level":"INFO","msg":"请求处理","path":"%s","status":%d}`,
    time.Now().Format(time.RFC3339), r.URL.Path, statusCode)
1
2
3
4
5
原则:
1. 日志输出到 stdout/stderr
2. 不写文件(或写文件也同步到 stdout)
3. 使用 JSON 格式(方便解析)
4. 包含 trace_id(方便链路追踪)

3.3 查看日志

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 单个 Pod
kubectl logs <pod> -f

# 多副本 Deployment 的所有 Pod
kubectl logs -l app=web-app --all-containers

# 指定时间段
kubectl logs <pod> --since=1h

# 多容器 Pod
kubectl logs <pod> -c <container>

# 之前的容器(崩溃后)
kubectl logs <pod> --previous

四、Helm 包管理

Helm 是 K8s 的包管理器,类似 apt/yum,简化应用的部署和管理。

4.1 安装 Helm

1
2
3
4
5
6
7
8
# Windows
winget install Helm.Helm

# macOS
brew install helm

# 验证
helm version

4.2 基本使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 添加仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# 搜索 Chart
helm search repo nginx
helm search repo nginx --versions    # 查看所有版本

# 安装
helm install my-nginx bitnami/nginx              # 默认配置
helm install my-nginx bitnami/nginx -n dev        # 指定命名空间
helm install my-nginx bitnami/nginx -f values.yaml  # 自定义配置

# 查看
helm list                    # 查看已安装的 Release
helm status my-nginx         # 查看 Release 状态
helm history my-nginx        # 查看历史版本

# 更新
helm upgrade my-nginx bitnami/nginx -f values.yaml

# 回滚
helm rollback my-nginx 1     # 回滚到版本1

# 卸载
helm uninstall my-nginx
helm uninstall my-nginx -n dev

4.3 自定义 values

1
2
3
4
5
# 查看 Chart 的默认配置
helm show values bitnami/nginx > values.yaml

# 编辑 values.yaml 后安装
helm install my-nginx bitnami/nginx -f values.yaml

常用 values 示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# values.yaml
replicaCount: 3

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 256Mi

service:
  type: NodePort
  port: 80

ingress:
  enabled: true
  hostname: app.example.com
  tls: true
  tlsSecret: tls-secret

4.4 常用 Helm 仓库

1
2
3
bitnami             — https://charts.bitnami.com/bitnami
prometheus-community — https://prometheus-community.github.io/helm-charts
ingress-nginx       — https://kubernetes.github.io/ingress-nginx

4.5 常用应用安装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Nginx Ingress Controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
  -n ingress-nginx --create-namespace

# Prometheus + Grafana
helm install monitoring prometheus-community/kube-prometheus-stack \
  -n monitoring --create-namespace

# Redis
helm install redis bitnami/redis -n dev

# MySQL
helm install mysql bitnami/mysql -n dev

五、CI/CD 集成

5.1 常用方案

1
2
3
4
GitLab CI + Helm       — 提交代码 → 构建镜像 → helm upgrade
GitHub Actions + kubectl — 推送到 main → 构建镜像 → kubectl apply
ArgoCD                 — GitOps 方式,监控 Git 仓库自动同步到集群
Jenkins + Helm         — 经典方案,适合复杂流水线

5.2 GitOps 模式(推荐)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
1. 开发提交代码到 Git
2. CI 构建镜像并推送镜像仓库
3. 更新 K8s YAML 中的镜像版本
4. ArgoCD 检测到 Git 变更,自动同步到集群

优势:
  - 所有变更都有 Git 记录
  - 配置和代码一起管理
  - 回滚就是 git revert
  - 多环境管理清晰

5.3 开发者工作流

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
开发阶段:
  1. 本地开发(minikube 或 Docker Compose)
  2. 写好 K8s YAML(Deployment + Service + ConfigMap)
  3. 本地测试通过

部署阶段:
  1. 构建镜像推到仓库
  2. 更新 YAML 中的镜像版本
  3. kubectl apply 或 helm upgrade
  4. 验证部署结果

六、运维常用操作

6.1 集群维护

1
2
3
4
5
6
7
8
9
# 节点维护(驱逐 Pod + 标记不可调度)
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data

# 维护完成后恢复
kubectl uncordon <node>

# 查看集群资源总量
kubectl top nodes
kubectl describe nodes | grep -A 5 "Allocated resources"

6.2 清理操作

1
2
3
4
5
6
7
8
9
# 清理 Completed 的 Pod
kubectl delete pods --field-selector=status.phase=Succeeded -A

# 清理 Evicted 的 Pod
kubectl get pods -A | grep Evicted | \
  awk '{print "kubectl delete pod "$2" -n "$1}' | sh

# 清理失败的 Job
kubectl delete jobs --field-selector status.successful!=1 -A

6.3 资源用量分析

1
2
3
4
5
6
7
8
9
# 查看所有 Deployment 的镜像版本和副本数
kubectl get deploy -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,REPLICAS:.spec.replicas,IMAGE:.spec.template.spec.containers[0].image'

# 查看各命名空间的 Pod 数量
kubectl get pods -A --no-headers | awk '{print $1}' | sort | uniq -c | sort -rn

# 查看资源配额使用
kubectl describe resourcequota -n dev
kubectl describe limitrange -n dev

七、小结

本文学习了 K8s 的排错与运维:

  • 排错方法论和常见问题排查
  • 监控体系(Metrics Server、Prometheus、Grafana)
  • 日志管理和最佳实践
  • Helm 包管理
  • CI/CD 集成和 GitOps
  • 运维常用操作

到此 K8s 学习笔记系列全部完成。从集群搭建、Pod 管理、工作负载、网络、存储、调度、安全到运维,覆盖了 K8s 的核心知识。