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 endpointslice -l kubernetes.io/service-name=<service> 检查是否有后端
  → 原因: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 endpointslice -l kubernetes.io/service-name=<service>  # 检查后端
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    — 可选的轻量 Resource Metrics API 实现(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
13
14
# 用 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;密码从该 Chart 创建的 Secret 中读取,不要依赖网上的固定默认值
kubectl get secret monitoring-grafana -n monitoring \
  -o jsonpath='{.data.admin-password}' | base64 --decode

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(counter,需计算一段时间内的速率)
  内存使用率         → 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
 8
 9
10
11
12
13
14
15
16
package example

import (
    "log"
    "net/http"
    "time"
)

func logRequest(r *http.Request, statusCode int) {
    // stdout/stderr 由容器运行时保留当前日志;长期汇聚需日志后端。
    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 --create-namespace  # 指定并按需创建命名空间
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
入口控制器          — 按所选 Gateway API / Ingress 实现的官方仓库配置

4.5 常用应用安装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# ingress-nginx 已于 2026 年 3 月退役,不再用于新部署。
# 新项目应按所选 Gateway API 实现或仍受维护的 Ingress Controller 官方文档安装。

# 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
# 先列出候选对象并确认命名空间、所有者和保留要求
kubectl get pods -A --field-selector=status.phase=Succeeded
kubectl get pods -A --field-selector=status.phase=Failed
kubectl get jobs -A

# 确认后按名称删除;不要把 grep/awk 结果直接交给 shell 批量执行
kubectl delete pod <pod-name> -n <namespace>
kubectl delete job <job-name> -n <namespace>

Job/CronJob 应优先通过 ttlSecondsAfterFinished 和历史保留字段建立生命周期策略。临时的全命名空间批量删除容易误删仍需取证的失败任务。

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 还有更深的两块——架构与核心组件讲清 apiserver / etcd / scheduler / 插件各是什么,调用链路深挖演示一次 kubectl apply 和一次外部请求在组件间怎么流转。读完那两篇,K8s 的全景才算闭环。

参考资料

Licensed under CC BY-NC-SA 4.0
最后更新于 Thursday, August 20, 2026