K3s Prometheus Grafana 部署排障记录
K3s + Prometheus + Grafana 部署排障记录
一、环境背景
集群架构
本次环境:
K3s Server
|
|-- Prometheus
|-- Grafana
|-- kube-state-metrics
|-- node-exporter
节点:
| 节点 | 角色 | IP |
|---|---|---|
| vm-0-17-ubuntu | control-plane/server | 10.0.0.17 |
| laptop-dhtmdui3 | agent node | 192.168.18.120 |
部署组件:
-
kube-prometheus-stack
-
Prometheus Operator
-
Grafana
-
kube-state-metrics
-
node-exporter
问题一:kube-state-metrics 镜像无法拉取
现象
Pod 状态:
monitoring-kube-state-metrics-xxx
STATUS:
ErrImagePull
ImagePullBackOff
查看:
kubectl describe pod -n monitoring kube-state-metrics-xxx
发现:
Failed to pull image
尝试:
crictl pull registry.aliyuncs.com/google_containers/kube-state-metrics:v2.19.1
结果:
not found
换:
crictl pull quay.io/coreos/kube-state-metrics:v2.19.1
结果:
401 Unauthorized
原因分析
kube-state-metrics 默认镜像:
registry.k8s.io/kube-state-metrics/kube-state-metrics
国内环境访问:
-
registry.k8s.io
-
quay.io
可能存在:
-
网络问题
-
镜像不存在
-
仓库权限问题
解决方案
修改 Helm values:
查看当前:
helm show values prometheus-community/kube-state-metrics
修改:
image:
registry: registry.aliyuncs.com
repository: xxx
或者选择国内镜像源:
例如 DaoCloud 镜像代理。
问题二:Grafana port-forward 无法外部访问
现象
执行:
kubectl port-forward \
-n monitoring \
svc/monitoring-grafana \
3000:80
显示:
Forwarding from 127.0.0.1:3000 -> 3000
但是浏览器:
公网IP:3000
无法访问。
原因
kubectl port-forward 默认监听:
127.0.0.1
只允许本机访问。
查看:
127.0.0.1:3000
而不是:
0.0.0.0:3000
解决方式
使用:
kubectl port-forward \
--address 0.0.0.0 \
-n monitoring \
svc/monitoring-grafana \
3000:80
或者生产环境:
修改 Service:
ClusterIP:
type: ClusterIP
改为:
type: NodePort
例如:
kubectl patch svc monitoring-grafana \
-n monitoring \
-p '{"spec":{"type":"NodePort"}}'
查看:
kubectl get svc -n monitoring
问题三:NodePort端口范围错误
现象
执行:
kubectl patch svc monitoring-grafana \
-p '{"spec":{"type":"NodePort","ports":[{"nodePort":3000}]}}'
错误:
Invalid value: 3000
valid ports:
30000-32767
原理
Kubernetes 默认 NodePort 范围:
30000-32767
所以:
错误:
3000
正确:
30080
例如:
kubectl patch svc monitoring-grafana \
-n monitoring \
-p '{"spec":{"type":"NodePort","ports":[{"name":"http-web","port":80,"targetPort":"grafana","nodePort":30080}]}}'
访问:
http://NodeIP:30080
问题四:node-exporter 启动失败
现象1
Pod:
node-exporter
CrashLoopBackOff
Events:
failed to generate container spec
path "/" is mounted on "/" but it is not a shared or slave mount
原因
node-exporter 默认:
hostNetwork: true
并挂载:
/proc
/sys
/root
用于采集宿主机指标。
但是:
WSL2 环境:
laptop-dhtmdui3
不是标准 Linux:
mount namespace
传播机制不同。
导致:
mount propagation
失败。
解决思路
方案1
不要在 WSL2 节点运行 node-exporter。
让 DaemonSet:
只运行 Linux 云服务器。
方案2
修改:
hostNetwork:false
但是会失去部分宿主机指标。
问题五:node-exporter端口冲突
现象
日志:
listen tcp 0.0.0.0:9100:
bind: address already in use
原因
node-exporter监听:
9100
同一个节点:
只能一个进程监听。
检查:
ss -lntp | grep 9100
或者:
lsof -i :9100
但是没有发现:
说明:
可能是:
-
容器网络 namespace
-
crash container残留
-
hostNetwork冲突
处理
删除Pod:
kubectl delete pod \
-n monitoring \
xxx-node-exporter
让DaemonSet重新创建。
问题六:k3s agent连接server失败
现象
agent日志:
Failed to connect to proxy
dial tcp 10.0.0.17:6443:
connection timed out
同时:
Connecting to proxy
wss://10.0.0.17:6443/v1-k3s/connect
分析过程
第一步:确认网络
agent:
ping 10.0.0.17
失败:
100% packet loss
说明:
agent无法访问server内网IP。
第二步:检查节点IP
server:
kubectl get nodes -o wide
结果:
server:
INTERNAL-IP:
10.0.0.17
agent:
192.168.18.120
发现:
两个节点:
不在同一个网络。
根本原因
初始化agent时:
使用:
K3S_URL=https://10.0.0.17:6443
但是:
10.0.0.17 是server内网地址。
agent:
不在同一内网。
所以:
TCP无法连接。
解决方案
重新加入:
使用公网地址:
例如:
https://124.xxx.xxx.xxx:6443
修改:
/etc/systemd/system/k3s-agent.service.env
设置:
K3S_URL=https://公网IP:6443
问题七:修改K3S_URL后仍连接旧IP
现象
配置:
K3S_URL=https://124.xxx.xxx.xxx:6443
但是日志:
wss://10.0.0.17:6443
原因
k3s agent保存了运行状态。
位置:
/var/lib/rancher/k3s/agent/etc/k3s-agent-load-balancer.json
里面:
{
"server":[
"10.0.0.17:6443"
]
}
这个文件优先级高于环境变量。
解决
停止:
systemctl stop k3s-agent
删除缓存:
rm -f \
/var/lib/rancher/k3s/agent/etc/k3s-agent-load-balancer.json
启动:
systemctl start k3s-agent
验证:
journalctl -u k3s-agent -f
应该看到:
wss://124.xxx.xxx.xxx:6443
Kubernetes排障通用思路总结
1. Pod问题
顺序:
kubectl get pod
↓
kubectl describe pod
↓
Events
↓
kubectl logs
↓
节点日志
不要直接看日志。
Events通常包含:
-
调度失败
-
镜像失败
-
volume失败
-
probe失败
2. 网络问题
检查链路:
Pod
|
Service
|
NodePort
|
Node IP
|
Firewall
|
公网
逐层验证。
工具:
ping
nc -vz IP PORT
curl
ss
3. 配置问题
Kubernetes存在多层状态:
Helm values
↓
Kubernetes对象
↓
Pod spec
↓
Container runtime
↓
节点文件状态
修改上层配置:
不一定覆盖下面状态。
4. k3s特殊注意
k3s不仅依赖:
systemd env
还有:
/var/lib/rancher/k3s/
里面保存:
-
agent状态
-
token
-
load balancer
-
runtime数据
修改配置后:
需要检查:
/var/lib/rancher/k3s/
本次关键经验
- 不要只看配置文件,要看实际运行状态
例如:
配置:
K3S_URL=公网IP
实际:
load-balancer.json=内网IP
- 云服务器节点和本地节点组集群,要优先考虑公网通信
不要使用:
10.x.x.x
192.168.x.x
除非:
VPN/VPC打通。
- DaemonSet类组件需要考虑节点环境
例如:
node-exporter:
依赖:
-
hostNetwork
-
hostPID
-
hostPath
在:
-
WSL
-
Docker Desktop
-
特殊内核环境
容易失败。
- 生产环境不要依赖port-forward
推荐:
Ingress
+
TLS
+
域名
或者:
LoadBalancer
NodePort
这次整个过程其实覆盖了 Kubernetes 运维里非常核心的几个方向:
-
Helm部署
-
镜像管理
-
Service暴露
-
Prometheus监控体系
-
DaemonSet机制
-
k3s节点通信
-
container runtime排障
非常适合作为以后 AIOps / SRE 知识库里的一个完整案例。
