Kubernetes Calico 网络故障排查与修复:RBAC 权限问题完整解决记录

📋 问题背景

在 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 资源来正常工作,包括:

  1. Calico CRD 资源 ​:ippools, bgpconfigurations, networkpolicies

  2. Kubernetes 核心资源 ​:services, endpoints, nodes, serviceaccounts

  3. 发现 API 资源 ​:endpointslices

  4. 网络 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'

🔧 预防措施

  1. 定期检查 RBAC 配置

    复制代码
    kubectl describe clusterrole calico-node
    kubectl describe clusterrolebinding calico-node
  2. 版本升级注意事项

    • 升级 Calico 时,注意检查 RBAC 需求变化

    • 参考官方文档的版本更新说明

  3. 监控与告警

    • 监控 Calico Pod 状态和重启次数

    • 设置网络连通性定期检测告警

💡 经验总结

  1. 排查方法论​:

    • 先检查 Pod 状态和日志,定位具体错误

    • RBAC 问题通常表现为 "is forbidden" 错误

    • 按需逐步添加权限,避免过度授权

  2. 常见权限需求​:

    • Calico 需要 getlistwatch权限监控资源变化

    • 需要 createupdatepatch权限管理资源状态

    • 需要 delete权限清理旧资源

  3. 故障恢复时间​:

    • RBAC 权限更新立即生效

    • Pod 重启和初始化需要 1-3 分钟

    • 网络完全恢复需要额外 1-2 分钟

相关推荐
Mr.Jessy7 小时前
JavaScript学习第六天:函数
开发语言·前端·javascript·学习·html·1024程序员节
LEEBELOVED7 小时前
R语言高效数据处理-变量批量统计检验
1024程序员节·r语言高效处理数据
源来猿往7 小时前
基于window/ubuntu安装rknn-toolkit2【docker】
docker·1024程序员节·rknn-toolkit2
千禧皓月7 小时前
【Diffusion Model】发展历程
人工智能·深度学习·diffusion model·1024程序员节
shandianchengzi7 小时前
【工具】Scrcpy|安卓投屏电脑的开源工具Scrcpy的安装及看电视注意事项
安卓·1024程序员节·投屏·电视·scrcpy
趙小贞7 小时前
UART 串口协议详解与 STM32 实战实现
stm32·单片机·嵌入式硬件·通信协议·1024程序员节
不惑_7 小时前
如何在 CentOS 9 Stream 服务器上安装 MySQL?
1024程序员节
今天背单词了吗9807 小时前
Spring Boot+RabbitMQ 实战:4 种交换机模式(Work/Fanout/Direct/Topic)保姆级实现
java·spring·中间件·rabbitmq·1024程序员节