📋 问题背景
在 Kubernetes 集群维护过程中,发现节点网络异常,Calico 节点 Pod 持续重启(CrashLoopBackOff状态)。经过排查,确定问题根源为 calico-node服务账户缺少必要的 RBAC 权限,导致无法访问所需的 API 资源。
🔍 故障现象
初始状态检查
# 检查 Calico Pod 状态
kubectl get pods -n kube-system -l k8s-app=calico-node
# 异常输出:
# NAME READY STATUS RESTARTS AGE
# calico-node-xxxxx 0/1 CrashLoopBackOff 6 43h
# calico-node-yyyyy 1/1 Running 0 21d
# calico-node-zzzzz 1/1 Running 0 21d
关键错误日志
# 查看故障 Pod 日志
kubectl logs -n kube-system calico-node-xxxxx -c calico-node --previous
# 错误信息显示:
# Unable to fetch IP pool list error=connection is unauthorized:
# ippools.crd.projectcalico.org is forbidden:
# User "system:serviceaccount:kube-system:calico-node" cannot list resource "ippools"
# in API group "crd.projectcalico.org" at the cluster scope
🧩 根本原因分析
Calico 需要访问多种 Kubernetes 资源来正常工作,包括:
-
Calico CRD 资源 :
ippools,bgpconfigurations,networkpolicies等 -
Kubernetes 核心资源 :
services,endpoints,nodes,serviceaccounts等 -
发现 API 资源 :
endpointslices -
网络 API 资源 :
networkpolicies.networking.k8s.io
当 calico-node服务账户缺少对这些资源的访问权限时,Calico 组件无法正常启动和工作。
🛠️ 解决方案:RBAC 权限修复
1. 检查现有 ClusterRole 配置
kubectl get clusterrole calico-node -o yaml
2. 添加缺失的 Calico CRD 权限
kubectl patch clusterrole calico-node --type='json' -p='[
{
"op": "add",
"path": "/rules/-",
"value": {
"apiGroups": ["crd.projectcalico.org"],
"resources": [
"ippools", "ipamblocks", "blockaffinities",
"ipamhandles", "ipamconfigs", "felixconfigurations",
"bgppeers", "bgpfilters", "clusterinformations",
"hostendpoints", "globalnetworksets", "networksets",
"globalnetworkpolicies", "caliconodestatuses"
],
"verbs": ["get", "list", "watch"]
}
}
]'
3. 添加 Kubernetes 核心资源权限
kubectl patch clusterrole calico-node --type='json' -p='[
{
"op": "add",
"path": "/rules/-",
"value": {
"apiGroups": [""],
"resources": ["services", "endpoints", "nodes", "serviceaccounts"],
"verbs": ["get", "list", "watch"]
}
}
]'
4. 添加发现 API 权限
kubectl patch clusterrole calico-node --type='json' -p='[
{
"op": "add",
"path": "/rules/-",
"value": {
"apiGroups": ["discovery.k8s.io"],
"resources": ["endpointslices"],
"verbs": ["get", "list", "watch"]
}
}
]'
5. 添加网络 API 权限
kubectl patch clusterrole calico-node --type='json' -p='[
{
"op": "add",
"path": "/rules/-",
"value": {
"apiGroups": ["networking.k8s.io"],
"resources": ["networkpolicies"],
"verbs": ["get", "list", "watch"]
}
}
]'
6. 触发 Pod 重建
# 删除故障 Pod,DaemonSet 会自动重建
kubectl delete pods -n kube-system -l k8s-app=calico-node
# 观察重建过程
watch -n 2 'kubectl get pods -n kube-system -l k8s-app=calico-node'
✅ 验证修复结果
1. 基础状态检查
# 检查所有 Calico Pod 状态(应全部为 Ready)
kubectl get pods -n kube-system -l k8s-app=calico-node
# 检查所有节点状态(应全部为 Ready)
kubectl get nodes
# 检查 CoreDNS 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
2. 网络连通性测试
# 创建测试 Pod
kubectl run network-test --image=busybox --rm -it --restart=Never -- sh
# 在 Pod 内执行测试:
# DNS 解析测试
nslookup kubernetes.default.svc.cluster.local
# 服务访问测试
wget -q -O- http://kubernetes.default.svc.cluster.local
# 互联网连通性测试
ping -c 3 8.8.8.8
3. 跨节点通信测试
# 在不同节点上创建测试 Pod
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-pod-node01
spec:
nodeName: <节点1名称>
containers:
- name: test
image: busybox
command: ["sleep", "3600"]
restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod-node02
spec:
nodeName: <节点2名称>
containers:
- name: test
image: busybox
command: ["sleep", "3600"]
restartPolicy: Never
EOF
# 测试跨节点通信
POD1_IP=$(kubectl get pod test-pod-node01 -o jsonpath='{.status.podIP}')
POD2_IP=$(kubectl get pod test-pod-node02 -o jsonpath='{.status.podIP}')
kubectl exec test-pod-node01 -- ping -c 3 $POD2_IP
kubectl exec test-pod-node02 -- ping -c 3 $POD1_IP
# 清理测试资源
kubectl delete pod test-pod-node01 test-pod-node02
📝 完整修复脚本
为避免手动操作错误,可以创建并执行以下修复脚本
#!/bin/bash
# calico-rbac-fix.sh
echo "开始修复 Calico RBAC 权限问题..."
# 备份当前配置
echo "备份当前 ClusterRole 配置..."
kubectl get clusterrole calico-node -o yaml > calico-node-backup.yaml
# 删除现有配置
echo "删除现有 RBAC 配置..."
kubectl delete clusterrole calico-node
kubectl delete clusterrolebinding calico-node
# 应用官方完整 RBAC 配置
echo "应用官方 RBAC 配置..."
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico-rbac.yaml
# 重启 Calico Pod
echo "重启 Calico Pod..."
kubectl delete pods -n kube-system -l k8s-app=calico-node
echo "修复完成,请观察 Pod 启动状态..."
watch -n 2 'kubectl get pods -n kube-system -l k8s-app=calico-node'
🔧 预防措施
-
定期检查 RBAC 配置
kubectl describe clusterrole calico-node kubectl describe clusterrolebinding calico-node -
版本升级注意事项
-
升级 Calico 时,注意检查 RBAC 需求变化
-
参考官方文档的版本更新说明
-
-
监控与告警
-
监控 Calico Pod 状态和重启次数
-
设置网络连通性定期检测告警
-
💡 经验总结
-
排查方法论:
-
先检查 Pod 状态和日志,定位具体错误
-
RBAC 问题通常表现为 "is forbidden" 错误
-
按需逐步添加权限,避免过度授权
-
-
常见权限需求:
-
Calico 需要
get、list、watch权限监控资源变化 -
需要
create、update、patch权限管理资源状态 -
需要
delete权限清理旧资源
-
-
故障恢复时间:
-
RBAC 权限更新立即生效
-
Pod 重启和初始化需要 1-3 分钟
-
网络完全恢复需要额外 1-2 分钟
-