写在前面
本文是 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 的全景才算闭环。
参考资料