在 Kubernetes 集群中配置节点间防火墙时,最稳妥的做法是根据角色(Master/Worker)和 CNI 插件类型放行特定协议和端口,而不是直接关闭防火墙。盲目关闭防火墙虽能通但存在严重安全风险,尤其是在生产环境。
先说结论:节点间防火墙配置的核心在于放行 CNI 封装协议和控制平面端口,且需严格区分节点角色。Master 节点需开放 API Server 和 Etcd 端口,Worker 节点仅需开放 kubelet 和 Pod 通信端口。
- 适合:所有生产环境 Kubernetes 集群,尤其是多节点跨网段部署
- 先准备:确认当前使用的 CNI 插件类型(Calico/Flannel/Cilium)及节点角色
- 验收:Pod 间跨节点 ping 通且业务端口可访问,同时通过端口扫描确认未开放多余端口
节点角色与端口策略
防火墙规则应遵循最小权限原则,不同角色节点开放的入站端口不同:
| 端口范围 | 协议 | 适用节点 | 说明 |
|---|---|---|---|
| 6443 | TCP | Master | Kubernetes API Server,Worker 节点只需出站访问 |
| 2379-2380 | TCP | Master | Etcd 集群通信,建议限制源 IP 仅为其他 Master 节点 |
| 10250 | TCP | All | Kubelet API,用于管控平面调度 |
| 30000-32767 | TCP/UDP | All | NodePort 服务端口 |
| IP 协议 4 (IPIP) | IP | All | Calico IPIP 模式必需 |
| 4789 / 8285 | UDP | All | Flannel VXLAN / UDP 模式必需 |
防火墙配置命令(Firewalld)
以下命令基于 firewalld,请在对应角色的节点上执行。注意命令中不要包含 Markdown 反引号。
1. 通用基础规则(所有节点)
sudo firewall-cmd `--permanent` `--add-port`=10250/tcp
sudo firewall-cmd `--permanent` `--add-port`=30000-32767/tcp
sudo firewall-cmd `--permanent` `--add-port`=30000-32767/udp
sudo firewall-cmd `--reload`2. Master 节点专属规则
API Server 端口开放给所有内网节点,Etcd 端口建议限制源 IP:
# 开放 API Server
sudo firewall-cmd `--permanent` `--add-port`=6443/tcp
# 开放 Etcd (建议限制源 IP 为 Master 网段,例如 192.168.1.0/24)
sudo firewall-cmd `--permanent` `--add-port`=2379-2380/tcp
# 若需限制源 IP,使用 `--add-source` 参数
# sudo firewall-cmd `--permanent` `--add-port`=2379-2380/tcp `--add-source`=192.168.1.0/24
sudo firewall-cmd `--reload`3. CNI 插件特定协议
根据实际使用的 CNI 放行封装协议,错误协议名称会导致配置失败:
# Calico IPIP 模式 (协议号 4,firewalld 中通常识别为 ipip)
sudo firewall-cmd `--permanent` `--add-protocol`=ipip
# Flannel VXLAN 模式 (UDP 4789)
sudo firewall-cmd `--permanent` `--add-port`=4789/udp
# Flannel UDP 模式 (UDP 8285)
sudo firewall-cmd `--permanent` `--add-port`=8285/udp
sudo firewall-cmd `--reload`验证与排查
配置完成后,不要只看防火墙状态,要从 Pod 层面验证:
- 跨节点 Pod 连通性:创建两个部署,分别调度到不同节点。
获取 Pod IP 后,在一个 Pod 内 ping 另一个 Pod IP。kubectl run test1 `--image`=busybox `--sleep`=3600 kubectl run test2 `--image`=busybox `--sleep`=3600 - 抓包验证:若不通,在节点网卡使用 tcpdump 观察封装包是否被丢弃。
若看到 ICMP unreachable 或无返回包,检查防火墙日志。sudo tcpdump -i any host <目标 Pod IP> -n - 端口扫描:使用 nmap 从外部扫描节点,确认未意外开放 2379 等敏感端口。
nmap -p 2379,6443,10250 <节点 IP>
应急回滚方案
若配置错误导致节点失联或无法连接,请通过控制台 VNC 或物理终端操作:
- 临时停止防火墙:
sudo systemctl stop firewalld - 进入恐慌模式(阻断所有):若需紧急阻断所有流量。
sudo firewall-cmd `--panic-on` - 重置规则:清除所有自定义规则恢复默认。
sudo firewall-cmd `--reload` sudo firewall-cmd `--runtime-to-permanent`
常见坑
- 云厂商安全组:除了主机防火墙,云实例的安全组规则优先级更高,需同时在控制台放行相应端口和协议。
- iptables 冲突:某些旧版本 CNI 与 firewalld 同时开启可能导致 iptables 链被清空,建议阅读 CNI 兼容性说明,必要时切换为 iptables 直接管理。
- MTU 问题:防火墙通常不影响 MTU,但封装网络会降低有效 MTU,若通信不稳定需检查 MTU 设置而非仅看防火墙。
- 协议名称错误:firewalld 中 IPIP 协议通常识别为
ipip而非ipv4-encap,配置错误会导致跨节点 Pod 流量被拦截。
参考来源
- Kubernetes 官方文档 - 集群组件通信端口 (https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)
- Project Calico 文档 - 防火墙配置指南 (https://docs.tigera.io/calico/latest/about/about-communication)
- Coreos Flannel 文档 - 后端类型说明 (https://github.com/flannel-io/flannel)