K8s运维进阶——监控、日志与故障排查实战

当K8s集群部署完成并运行应用后,运维工作就成为了重中之重。一个稳定的K8s集群,离不开完善的监控、规范的日志管理和高效的故障排查能力。本文将聚焦K8s运维的核心场景,讲解如何搭建监控体系、收集分析日志,以及常见故障的排查方法,帮助你从“会用K8s”提升到“会管K8s”。

### 一、K8s监控体系搭建——Prometheus+Grafana实战

K8s集群的监控核心是“全方位监控”,包括集群节点(CPU、内存、磁盘、网络)、K8s组件(kube-apiserver、etcd、kube-scheduler等)、Pod和容器(CPU使用率、内存占用、网络流量)以及应用本身的监控。目前最主流的监控方案是Prometheus+Grafana,Prometheus负责收集监控数据,Grafana负责可视化展示。

#### 1. 部署Prometheus(数据收集)

Prometheus通过“ exporters ”收集不同组件的监控数据,常用的exporters包括:node-exporter(收集节点监控数据)、kube-state-metrics(收集K8s组件和资源的监控数据)、container-exporter(收集容器监控数据)。

推荐使用Helm(K8s的包管理工具)快速部署Prometheus,步骤如下:

1. 安装Helm:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

2. 添加Prometheus仓库:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

3. 部署Prometheus:

helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespace

部署完成后,执行kubectl get pods -n monitoring,可查看Prometheus相关组件(prometheus-server、node-exporter、kube-state-metrics等)的运行状态。

#### 2. 部署Grafana(可视化展示)

上述Helm部署命令已经包含了Grafana,部署完成后,通过NodePort或PortForward访问Grafana:

1. 查看Grafana Service:kubectl get svc -n monitoring | grep grafana

2. 端口转发(临时访问):kubectl port-forward svc/prometheus-grafana 3000:80 -n monitoring

3. 访问Grafana:浏览器访问http://localhost:3000,默认用户名和密码为admin/prom-operator。

4. 配置数据源:登录Grafana后,添加Prometheus数据源,填写Prometheus的Service地址(如http://prometheus-kube-prometheus-prometheus.monitoring:9090),保存即可。

5. 导入监控面板:Grafana官方提供了很多现成的K8s监控面板(如面板ID:1860,用于节点监控;ID:7249,用于K8s集群监控),导入后即可看到完整的监控图表。

#### 3. 监控核心指标

- 节点指标:CPU使用率、内存使用率、磁盘使用率、网络入/出流量;

- K8s组件指标:kube-apiserver请求量、etcd存储使用率、kube-scheduler调度成功率;

- Pod/容器指标:CPU使用率、内存占用、重启次数、网络流量、容器健康状态;

- 应用指标:应用响应时间、请求成功率、错误率(需要应用自身暴露Prometheus指标)。

### 二、K8s日志管理——集中化收集与分析

K8s集群中,Pod和容器的日志分散在各个节点上,手动查看日志效率低下,因此需要搭建集中化日志管理系统,将所有日志收集到一起,便于查询、分析和排查问题。目前主流的日志方案是ELK Stack(Elasticsearch+Logstash+Kibana)或EFK Stack(Elasticsearch+Fluentd+Kibana),其中EFK在K8s环境中更常用(Fluentd更轻量,适合容器环境)。

#### 1. 日志收集流程

1. Fluentd:部署在每个工作节点上,通过DaemonSet模式运行,负责收集节点上的容器日志(默认路径/var/log/containers/);

2. Elasticsearch:负责存储收集到的日志数据,提供全文检索能力;

3. Kibana:提供日志可视化查询界面,支持按Pod、容器、时间范围等条件查询日志,以及日志分析和可视化展示。

#### 2. 快速部署EFK Stack

同样可以使用Helm部署EFK Stack,步骤如下:

1. 添加EFK仓库:

helm repo add elastic https://helm.elastic.co

2. 部署Elasticsearch:

helm install elasticsearch elastic/elasticsearch --namespace logging --create-namespace --set replicas=1 --set resources.requests.cpu=1 --set resources.requests.memory=1Gi

3. 部署Kibana:

helm install kibana elastic/kibana --namespace logging

4. 部署Fluentd:

helm repo add fluent https://fluent.github.io/helm-charts

helm install fluentd fluent/fluentd --namespace logging

部署完成后,通过Kibana的Web界面(端口转发或NodePort访问),配置Elasticsearch数据源,即可查询和分析集群中的所有容器日志。

#### 3. 日志管理最佳实践

- 规范日志格式:应用日志建议使用JSON格式,包含时间戳、日志级别、Pod名称、容器名称、日志内容等关键信息,便于后续分析;

- 日志轮转:配置容器日志轮转,避免日志文件过大占用节点磁盘空间(可通过Docker日志驱动或Fluentd配置实现);

- 日志留存:根据业务需求,配置Elasticsearch日志留存时间,定期清理过期日志,节省存储资源。

### 三、K8s常见故障排查实战

K8s集群的故障类型多样,常见的故障包括节点故障、Pod故障、Service故障、网络故障等,排查故障的核心思路是“从现象出发,逐层排查,定位根因”。

#### 1. 节点故障排查

现象:节点状态为NotReady,Pod无法调度到该节点。

排查步骤:

1. 查看节点详情:kubectl describe node <节点名称>,查看“Conditions”字段,判断节点故障原因(如内存不足、磁盘满、网络异常);

2. 登录节点,查看kubelet状态:systemctl status kubelet,若kubelet未运行,启动kubelet(systemctl start kubelet),并查看日志(journalctl -u kubelet)排查启动失败原因;

3. 检查节点资源:free -m(查看内存)、df -h(查看磁盘),若资源不足,清理无用资源(如停止无用容器、删除日志文件);

4. 检查网络:ping控制平面节点IP,查看是否能正常通信,若网络异常,检查防火墙或网络配置。

#### 2. Pod故障排查

现象:Pod状态为Pending、CrashLoopBackOff、Error等,无法正常运行。

排查步骤:

1. 查看Pod状态:kubectl get pods,确认Pod的异常状态;

2. 查看Pod详情:kubectl describe pod <Pod名称>,重点查看“Events”字段,获取故障提示(如镜像拉取失败、资源不足、端口冲突);

3. 查看Pod日志:kubectl logs <Pod名称>(若Pod已启动但异常),或kubectl logs <Pod名称> -p(查看上一次启动的日志);

4. 常见故障解决:

- Pending:资源不足(扩容节点或调整Pod资源请求)、节点亲和性配置错误(修改Deployment配置);

- CrashLoopBackOff:容器启动后立即退出(检查应用配置、日志,排查应用本身问题);

- ImagePullBackOff:镜像拉取失败(检查镜像名称、标签是否正确,镜像仓库是否可访问)。

#### 3. Service故障排查

现象:无法通过Service访问Pod,或访问超时。

排查步骤:

1. 查看Service详情:kubectl describe svc <Service名称>,确认Service的selector是否与Pod标签匹配;

2. 查看Service关联的Pod:kubectl get endpoints <Service名称>,确认是否有Pod被关联(若为空,说明selector匹配错误);

3. 测试Pod直接访问:kubectl exec -it <Pod名称> -- curl <Pod IP:端口>,确认Pod本身是否正常提供服务;

4. 测试Service访问:在集群内其他Pod中,curl <Service ClusterIP:端口>,若无法访问,检查kube-proxy状态(systemctl status kube-proxy)。

#### 4. 网络故障排查

现象:Pod之间无法通信,或Pod无法访问外部网络。

排查步骤:

1. 检查网络插件:kubectl get pods -n kube-system,确认网络插件(如flannel、calico)是否正常运行;

2. 检查Pod网络:kubectl exec -it <Pod名称> -- ping <其他Pod IP>,确认Pod之间是否能通信;

3. 检查节点网络:登录节点,ping其他节点IP,确认节点之间网络通畅;

4. 检查DNS:kubectl exec -it <Pod名称> -- nslookup <Service名称>,确认DNS解析是否正常(若解析失败,检查CoreDNS组件)。

### 总结

K8s运维的核心是“预防为主,快速排查”:通过Prometheus+Grafana搭建完善的监控体系,提前发现集群异常;通过EFK Stack实现日志集中化管理,为故障排查提供依据;掌握常见故障的排查思路和方法,能够快速定位并解决问题。随着K8s的不断发展,运维工作也在不断升级,后续还可以学习自动扩缩容、集群备份与恢复、安全加固等进阶内容,进一步提升K8s集群的稳定性和可靠性。

更多推荐