K8s学习笔记(二十二) 网络组件 Flannel与Calico
1 为什么需要 Flannel/Calico?
K8s 集群中,每个 Node 会通过 Docker 默认创建一个「网桥(如docker0)」,Pod 的 IP 是从网桥的子网中分配的(如 Node1 的 Pod IP 是10.244.1.0/24,Node2 的是10.244.2.0/24)。
但默认情况下,不同 Node 的网桥是隔离的 ------Node1 的 Pod 无法访问 Node2 的 Pod,因为 Node 之间没有「路由规则」告知 "10.244.2.0/24网段的 Pod 在 Node2 上"。
Flannel/Calico 的核心作用就是:
- 为整个集群分配一个统一的「Pod 网络网段」(如
10.244.0.0/16),并给每个 Node 划分一个子网; - 通过某种技术(如 Overlay 封装、BGP 路由),实现跨 Node 的 Pod IP 互通;
- (部分组件如 Calico)提供「网络策略(Network Policy)」,控制 Pod 间的访问权限。
2 Flannel:简单易用的 "入门级" CNI
Flannel 是 CoreOS 推出的轻量级 CNI 插件,设计目标是「最小化复杂度」,适合新手入门或对网络功能要求不高的场景(如测试环境、简单业务)。
2.1 Flannel 的核心工作原理
Flannel 通过「Overlay 网络(叠加网络)」或「路由模式」实现跨 Node Pod 互通,核心是在 Node 间构建一个虚拟的 "隧道",让 Pod 数据包能跨 Node 传输。
目前 Flannel 支持两种主流模式:vxlan(默认) 和 host-gw,二者的区别如下:
| 模式 | 实现方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| vxlan | 把 Pod 的 IP 数据包封装在「Node 的 IP 数据包」里(类似 "快递套盒子"),通过 Node 网络传输 | 无需网络设备支持,跨网段友好 | 数据包需封装 / 解封装,性能损耗约 10-20% | Node 不在同一网段(如跨机房) |
| host-gw | 直接在每个 Node 的「路由表」中添加规则:"访问 Node X 的 Pod 网段,下一跳是 Node X 的 IP" | 无需封装,性能接近物理网络 | 要求所有 Node 在同一网段(二层互通) | Node 在同一局域网(如同一机房) |
2.2 Flannel 的核心组件
Flannel 的架构非常简单,只有 2 个核心部分:
- flanneld:运行在每个 Node 上的守护进程(DaemonSet),负责:
- 从 etcd 中获取集群的 Pod 网络配置(如总网段
10.244.0.0/16); - 为当前 Node 分配一个子网(如
10.244.1.0/24),并将 "Node IP → 子网" 的映射存入 etcd; - 根据模式(vxlan/host-gw)配置 Node 的路由表或虚拟网卡(如 vxlan 模式下创建
flannel.1网卡)。
- 从 etcd 中获取集群的 Pod 网络配置(如总网段
- etcd:存储 Flannel 的网络配置(如总网段、Node 子网映射),确保所有 Node 的配置一致(K8s 集群若用 etcd 作为 APIServer 后端,可复用 etcd)。
2.3 Flannel 的优缺点
| 优点 | 缺点 |
|---|---|
| 部署极简单(1 条命令搞定) | 不支持「网络策略」(无法控制 Pod 访问) |
| 架构轻量,资源占用少 | vxlan 模式性能有损耗 |
| 对网络环境要求低(跨网段友好) | 功能单一(仅解决互通,无高级特性) |
3 Calico:高性能 + 强管控的 "生产级" CNI
Calico 是 Tigera 推出的企业级 CNI 插件,设计目标是「高性能」和「强网络管控」,核心基于BGP 协议(边界网关协议) 实现路由同步,支持网络策略,适合生产环境(尤其是对性能和安全有要求的场景)。
3.1 Calico 的核心工作原理
Calico 的核心是「不依赖 Overlay 封装,通过 BGP 协议同步 Node 间的路由规则」,实现 Pod 互通。目前支持两种主流模式:BGP 模式(默认) 和 IPIP 模式。
(1)BGP 模式(推荐,无封装)
BGP 是互联网中用于 "路由器之间交换路由信息" 的协议,Calico 将每个 Node 视为一个 "虚拟路由器",通过 BGP 协议让 Node 之间互相告知 "我负责的 Pod 网段":
- 为集群分配总 Pod 网段(如
10.244.0.0/16),每个 Node 分配一个子网(如 Node1:10.244.1.0/24,Node2:10.244.2.0/24); - 每个 Node 上的 Calico 组件(BIRD)会将 "本地 Pod 子网 → 本地 Node IP" 的路由规则,通过 BGP 协议同步给其他所有 Node;
- 当 Node1 的 Pod 要访问 Node2 的 Pod 时,Node1 的路由表已知道 "
10.244.2.0/24的下一跳是 Node2 的 IP",直接将数据包发给 Node2,无需任何封装。
(2)IPIP 模式(Overlay,跨网段兼容)
若 Node 不在同一网段(如跨机房),BGP 协议无法直接同步路由(需网络设备支持 BGP,很多场景不满足),此时 Calico 会用 IPIP 模式:
将 Pod 的 IP 数据包封装在「Node 的 IP 数据包」里(类似 Flannel 的 vxlan),通过 Node 网络传输,本质是 Overlay 网络,性能略低于 BGP 模式,但跨网段友好。
3.2 Calico 的核心组件
Calico 的架构比 Flannel 复杂,但功能更强大,核心组件以 DaemonSet 或 Deployment 形式运行:
| 组件 | 运行位置 | 功能 |
|---|---|---|
| calico-node | 每个 Node | 核心守护进程,包含多个子组件(Felix、BIRD、confd) |
| Felix | 内嵌于 calico-node | 配置 Node 的网络(如路由表、iptables 规则),确保 Pod 互通和网络策略生效 |
| BIRD | 内嵌于 calico-node | BGP 客户端,负责与其他 Node 的 BIRD 交换路由信息(同步 Pod 网段路由) |
| confd | 内嵌于 calico-node | 监听 etcd 中的 Calico 配置,动态生成 BIRD 的配置文件 |
| calico-kube-controllers | 集群中 1 个 Pod | 控制平面组件,负责同步 K8s 资源(如 Node、Namespace)到 Calico,确保网络配置与 K8s 一致 |
| etcd | 集群(可复用 K8s 的 etcd) | 存储 Calico 的网络配置(如 Pod 网段、路由规则、网络策略) |
3.3 Calico 的核心优势:网络策略(Network Policy)
这是 Flannel 完全没有的功能,也是生产环境选择 Calico 的核心原因 ------通过 Network Policy 定义 "哪些 Pod 可以访问哪些 Pod",实现 Pod 级别的访问控制。
例如,可定义如下策略:"只允许default命名空间下的web标签 Pod 访问db命名空间下的mysql标签 Pod(3306 端口)",其他 Pod 无法访问mysql。
yaml
# 示例:只允许web Pod访问mysql Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web-to-mysql
namespace: db
spec:
podSelector:
matchLabels:
app: mysql # 目标Pod(mysql)
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: default # 来源命名空间(default)
podSelector:
matchLabels:
app: web # 来源Pod(web)
ports:
- protocol: TCP
port: 3306 # 允许的端口
3.4 Calico 的优缺点
| 优点 | 缺点 |
|---|---|
| 性能优秀(BGP 模式无封装) | 配置比 Flannel 复杂(需理解 BGP 基础) |
| 支持网络策略(生产级安全管控) | BGP 模式要求 Node 在同一网段(或网络设备支持 BGP) |
| 功能丰富(如流量监控、加密) | 资源占用比 Flannel 略高 |
| 支持跨网段(IPIP 模式) | 学习成本较高 |
4 Flannel vs Calico:核心差异对比
| 对比维度 | Flannel | Calico |
|---|---|---|
| 网络模式 | vxlan(默认,Overlay)、host-gw(路由) | BGP(默认,路由)、IPIP(Overlay) |
| 性能 | 中等(vxlan 有封装损耗) | 优秀(BGP 无封装,接近物理网络) |
| 网络策略 | 不支持 | 支持(核心优势,生产级) |
| 部署复杂度 | 极低(1 条命令) | 中等(需配置网络模式、策略等) |
| 资源占用 | 低(flanneld 进程轻量) | 中等(calico-node 包含多个子组件) |
| 适用场景 | 测试环境、简单业务、新手入门 | 生产环境、高性能需求、安全管控需求 |
| 高级特性 | 无 | 流量监控(Calico Observability)、数据加密(IPsec)、BGP 路由反射器 |
5 实操:部署 Flannel 和 Calico 到 K8s 集群
前提:已搭建好 K8s 集群(至少 1 个 Master + 1 个 Node),kubectl命令可用。
5.1 部署 Flannel(简单版)
-
下载 Flannel 的 CNI 配置文件(官方维护):
bashkubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.22.0/Documentation/kube-flannel.yml -
验证部署:
-
查看
kube-system命名空间下的 Flannel Pod(每个 Node 会有 1 个):bashkubectl get pods -n kube-system -l app=flannel输出类似(
Running表示正常):plaintextNAME READY STATUS RESTARTS AGE kube-flannel-ds-xxxx 1/1 Running 0 5m
-
-
测试 Pod 互通:
- 在 Node1 创建一个 Pod(如
nginx-1),在 Node2 创建一个 Pod(如nginx-2); - 进入
nginx-1,pingnginx-2的 Pod IP,能通则表示 Flannel 生效。
- 在 Node1 创建一个 Pod(如
5.2 部署 Calico(生产级,BGP 模式)
-
下载 Calico 的部署文件(官方推荐,适配 K8s 1.24+):
bashkubectl apply -f https://docs.projectcalico.org/v3.26/manifests/calico.yaml -
验证部署:
-
查看
calico-system命名空间下的 Pod(calico-node是 DaemonSet,每个 Node1 个;calico-kube-controllers是 Deployment,1 个):bashkubectl get pods -n calico-system输出类似(均为
Running表示正常):plaintextNAME READY STATUS RESTARTS AGE calico-kube-controllers-xxxxxxxxx-xxxxx 1/1 Running 0 8m calico-node-xxxx 1/1 Running 0 8m calico-node-yyyy 1/1 Running 0 8m
-
-
测试网络策略(可选):
- 创建前面提到的「allow-web-to-mysql」策略;
- 用非
web标签的 Pod 尝试访问mysqlPod,会被拒绝;用web标签的 Pod 访问,能通则表示策略生效。
6 总结:如何选择?
- 如果需要快速搭建测试环境 ,对网络性能和安全要求不高 → 选Flannel(简单、省心);
- 如果需要生产环境 ,对性能(低延迟) 和安全管控(Pod 访问控制) 有要求 → 选Calico(高性能、支持网络策略);
- 若 Node 跨网段(如跨机房):Flannel 用 vxlan,Calico 用 IPIP,二者均可兼容。