- 网络
- 云原生
- 网络安全
【免费下载链接】calico
Cloud native networking and network security
Calico(本项目 networking-calico 子项目)在 OpenStack/Neutron 云环境中的核心实现思路是:放弃桥接与隧道模拟 L2,转而使用标准 Linux 路由转发 VM 流量,用 iptables 施加安全策略,并用 BGP(BIRD)在计算节点之间扩散路由。本文基于 networking-calico 实现笔记 展开,结合仓库源码说明默认地址作用域下的连通性机制、路由表象、DHCP 服务的实现细节,以及与之配套的 Calico DHCP Agent 的整体架构。读完本文,你将能理解 Calico 作为 Neutron 后端时"不做二层、只做三层"的具体落地方式,以及其 DHCP agent 如何从 etcd 拉取数据、复用 Dnsmasq 完成地址下发。
与 Neutron 其他后端的关键差异
Calico 与大多数 Neutron 后端(依赖 Linux bridge、Open vSwitch 或隧道封装来模拟 L2 连通性)的根本不同,是它直接在L3 层工作。networking-calico 的文档索引页(networking-calico/doc/source/index.rst)明确列出了这一选择带来的三方面 API 语义约束:
- 单一扁平地址空间:Calico 只支持一个扁平 IP 地址空间,不支持网段重叠(overlapping IP ranges)或 BYOIP("bring your own addressing")。在 Neutron API 术语中,所有 Calico 网络子网必须属于同一个地址作用域(address scope)。
- 无 L2 邻接:即使在同一 Neutron 子网内,Calico 也不提供二层邻接,因此裸二层协议和广播流量无法工作。在 Neutron API 术语中,所有 Calico 网络的
l2_adjacency必须为False。 - 默认跨网络互联:Calico 默认提供不同网络之间的连通性,网络隔离与细粒度安全限制依赖 security group 配置与策略实现。这意味着 Calico 网络要么是外部 provider 网络,要么是通过 Neutron 路由器连接到外部网络的租户网络。
这三条约束直接决定了实现笔记中描述的数据通路:既然不做二层,VM 之间的数据转发自然落到 Linux 路由层。
默认地址作用域下的连通性实现
从 TAP 到路由:宿主机上的数据通路
对默认地址作用域的 endpoint,所有转发都发生在计算节点的默认网络命名空间(default namespace)中,由标准 Linux 路由转发 VM 数据,由 iptables 实现配置的安全策略。具体过程如下:
- VM 通过宿主上的TAP 设备接入,TAP 的宿主端不做桥接、不配置任何 IP 地址(仅保留 link-local IPv6)。
- 宿主机被配置为通过该 TAP响应任何 ARP 或 NDP 请求,且应答自己的 MAC 地址。因此经 TAP 到达的数据在 L2 层总是以宿主机为目的地址,随后被交给 Linux 路由层处理——这正是"以 L3 方式接管 L2 流量"的关键技巧。
- 对每个本地 VM,宿主机编程一条指向对应 TAP 设备的路由,目标为该 VM 的 IP 地址。
- 宿主机运行BGP 客户端(BIRD),将这些路由导出给其他计算节点,同时也从其他节点学习远端 VM 的路由。
计算节点上的路由表形态
文档给出了一张计算节点路由表的真实样例(命令route -n的输出):
user@host02:~$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.18.203.1 0.0.0.0 UG 0 0 0 eth0 10.65.0.21 172.18.203.126 255.255.255.255 UGH 0 0 0 eth0 10.65.0.22 172.18.203.129 255.255.255.255 UGH 0 0 0 eth0 10.65.0.23 172.18.203.129 255.255.255.255 UGH 0 0 0 eth0 10.65.0.24 0.0.0.0 255.255.255.255 UH 0 0 0 tapa429fb36-04 172.18.203.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0这张表直观展示了 Calico 的路由模型:
- 本机 VM
10.65.0.24的路由是UH(主机路由,经 TAP),下一跳为空(直接连接),出口设备为tapa429fb36-04; - 远端三台 VM(
.21、.22、.23)分别落在两台计算节点(172.18.203.126与.129)上,路由表现为UGH(经网关的主机路由),出口为 eth0——这些路由正是由 BIRD 通过 BGP 从其他计算节点学习而来; - 每台远端 VM 都是一条独立的
/32主机路由,而不是聚合网段路由,这体现了 Calico"每 endpoint 一条路由"的精确路由风格。
对比典型的 Neutron 后端(如 VXLAN + Linux bridge / OVS),这里没有 br-int、没有 VXLAN 隧道接口、没有 namespace 隔离,所有流量直接走宿主 eth0 转发。
DHCP 服务:在路由网络里如何下发地址
在无桥接、无 namespace 的路由式网络里,DHCP 服务不能沿用 Neutron 的默认设计。实现笔记明确指出:DHCP 服务由运行在每个计算节点上的 DHCP agent 提供,agent 调用Dnsmasq 并使用其--bridge-interface选项。
--bridge-interface的语义
该选项的效果是:Dnsmasq 把所有 TAP 接口当作ns-XXX接口(Dnsmasq 的 DHCP 上下文定义所在的接口)的别名,具体表现为两个行为:
- 若在某个 TAP 接口上收到 DHCP(v4 或 v6)或 Router Solicit 报文,Dnsmasq按在
ns-XXX接口上收到一样处理,然后把应答报文从对应的 TAP 发回; - 当 Dnsmasq 平时会在
ns-XXX接口上主动发送无请求的路由通告(unsolicited Router Advertisement)时,此时改为在全部 TAP 接口上发送。
网关 IP 复用而非独立分配
为了适配路由式网络,DHCP agent 使用一个 Calico 特有的接口驱动,其行为与标准 Neutron DHCP agent 有本质区别:
- 它把
ns-XXX创建为Linux dummy 接口(而不是桥接接口); - 它使用子网网关 IP 作为
ns-XXX的 IP 地址,而不是从 Neutron 为每个 DHCP 端口分配一个独立的 IP。
这样做的直接后果是:DHCP 端口不再占用 Neutron 数据库中的独立 IP 地址,从而消除了大规模部署中 IP 分配与端口同步的巨大开销。实现笔记还提到,支持该行为的补丁已分别合入Dnsmasq 2.73 之前的版本和Neutron Liberty 之前的版本。
源码佐证:驱动与 Dnsmasq 配置的落地实现
RoutedInterfaceDriver:创建 dummy 接口
文档描述的"Calico 特有接口驱动"在仓库中对应 networking_calico/agent/linux/interface.py 的RoutedInterfaceDriver:
use_gateway_ips属性返回True:注释说明路由式网络不跨计算节点或网络节点桥接,因此 DHCP 端口可以使用每个子网的网关 IP 地址,而不必申请新的 Neutron 分配地址;plug_new()通过ip_lib.IPWrapper().add_dummy(device_name)创建 dummy 接口(位于默认命名空间),并设置 MAC、可选 MTU 后将其 up;init_l3()在超类逻辑之外,删除 Linux 自动为该 CIDR 创建的子网路由(device.route.delete_onlink_route)——这是路由式 DHCP 的关键修正,避免 dummy 接口上的网关地址引入多余的直接路由;bridged属性为False。
DnsmasqRouted:组装桥接式 Dnsmasq 命令行
Dnsmasq 驱动在 networking_calico/agent/linux/dhcp.py 的DnsmasqRouted中实现,它组合出与实现笔记完全对应的命令行参数:
dnsmasq --no-hosts --except-interface=lo --pid-file=... \ --dhcp-hostsfile=... --addn-hosts=... --dhcp-optsfile=... \ --dhcp-leasefile=... --dhcp-match=set:ipxe,175 \ --bind-dynamic --interface=<ns-XXX> \ --interface=tap* --bridge-interface=<ns-XXX>,tap*关键点在于--bridge-interface=<ns-XXX>,tap*与--bind-dynamic的组合:前者正是文档所述"把 TAP 当作 ns-XXX 别名"的机制,后者使 Dnsmasq 动态绑定各 TAP 接口,从而避免在计算节点上创建额外的桥接 namespace。文件开头的注释还说明其使用 Calico 自己的CalicoDeviceManager。
配套组件:Calico DHCP Agent 架构与 etcd 数据模型
实现笔记侧重"宿主如何转发数据",而 DHCP agent 的详细设计收录在同目录的 networking-calico/doc/source/dhcp-agent.rst 中,两者共同构成完整的实现图景。
复用 Neutron 架构、避免 RPC 风暴
Calico DHCP agent 大量复用现有 Neutron DHCP agent 架构(包括 Dnsmasq 的使用),但剔除掉导致 Neutron server 在 DHCP agent 超过数百个时负载过高的部分。改动集中在两点:
- 移除
DhcpAgentWithStateReport——它原本向 Neutron server 上报本 agent 的存在,导致 server 向其扇出(fan out)端口更新; CalicoDhcpAgent替换DhcpAgent.run()——Neutron 的run()会在启动时及之后周期性地向 Neutron server 询问端口信息,Calico 版本直接停止这一行为。
作为替代,agent 通过 etcd 监视/calico/v1/host/<hostname>/workload子树中本主机的 endpoint 数据变化,把当前 endpoint 数据集转换为 Neutron DHCP 驱动期望的NetworkCache格式后交给 dhcp_driver。这一点在源码 networking_calico/agent/dhcp_agent.py 中得到印证:CalicoDhcpAgent继承 Neutron 的DhcpAgent,在__init__中强制enable_isolated_metadata=False、use_namespaces=False,将interface_driver覆盖为RoutedInterfaceDriver、将dhcp_driver_cls覆盖为DnsmasqRouted,并把 RPC 插件替换为本地FakePlugin(提供create_dhcp_port/release_dhcp_port/get_ports存根,MAC 使用硬编码的本地管理地址02:00:00:00:00:00,不占用 Neutron 数据库端口)。其run()直接启动CalicoEtcdWatcher完成 etcd 数据驱动。
etcd 数据模型扩展
为了从 etcd 供数给 DHCP agent,文档给出了在 Felix 已消费的数据之外新增的数据模型:
/calico/dhcp/v1:DHCP agent 所需信息的新子树;/calico/dhcp/v1/subnet:子网信息目录;/calico/dhcp/v1/subnet/<subnet-id>:JSON dict 形式的内容:
{ 'cidr': <cidr>, # Mandatory. For example: "192.168.1.0/24". 'gateway_ip': <gateway IP>, # Mandatory. For example: "192.168.1.1". 'dns_servers': [ <ip1>, <ip2>, ... ] # Optional. For example: [ '172.18.10.55', '172.18.10.74' ] }- 每个 endpoint 的 JSON dict 中新增字段:
{ 'ipv4_subnet_ids': [ <subnet-id>, ... ] # Subnet IDs for each corresponding IPv4 address in 'ipv4_nets'. 'ipv6_subnet_ids': [ <subnet-id>, ... ] # Subnet IDs for each corresponding IPv6 address in 'ipv6_nets'. 'fqdn': <fqdn> # Optional. E.g. 'calico-vm17.datcon.co.uk' }当前仓库源码中,子网路径与注解键的实现在 datamodel_v1.py(SUBNET_DIR)与 datamodel_v3.py(注解键openstack.projectcalico.org/fqdn、openstack.projectcalico.org/network-id)中可查。
两个关键细节
- 子网前缀长度必须正确:对每个子网,网关 IP 与前缀长度会以
ifconfig <device> <gateway IP>/<prefix length>的形式配置在 Dnsmasq 监听的 Linux 接口上;且 Dnsmasq 只会在关联 Linux 接口定义的子网范围内下发 IP。若前缀长度错误,Dnsmasq 将无法下发地址。 - VM 主机名(fqdn):Neutron 通过端口字段
dns_name(可写,简单名如calico-vm17)与dns_assignment(服务端生成的只读字段,形如{'hostname': 'calico-vm17', 'ip_address': '10.65.0.4', 'fqdn': 'calico-vm17.datcon.co.uk'})向 DHCP agent 传递主机名信息;agent 将其交给 dhcp_driver 并写入 Dnsmasq 配置。在 Calico 模型中,endpoint 数据只新增单个fqdn字段,hostname由在第一个.处拆分派生。从源码看,CalicoEtcdWatcher.on_endpoint_set正是从 endpoint 注解读取 fqdn、按fqdn.split(".")[0]得到 hostname,并组装进dns_assignment。
调用方式
DHCP agent 的调用方式与标准 Neutron DHCP agent 相同,使用 neutron 配置文件;区别在于 Calico agent 额外消费calicooption group下的设置(例如 etcd 集群连接信息)。一个典型调用示例:
calico-dhcp-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini由于 calico ml2 插件配置文件已包含全部所需设置,它本身也可作为该 option group 的配置来源。源码入口见 dhcp_agent_main.py(setup.py中注册的calico-dhcp-agent命令入口,负责在导入模块前完成 eventlet monkey_patch)。
总结:一条贯穿数据面与控制面的完整链路
把实现笔记与配套文档、源码合起来看,Calico 在 OpenStack 中的实现是一条清晰的链路:
- 数据面:VM 经无桥接 TAP 接入宿主默认命名空间 → 宿主应答 ARP/NDP 把流量引入路由层 → 本地 VM 走 TAP 主机路由、远端 VM 走 BGP 学习到的
/32主机路由(见 实现笔记 中的路由表示例); - 策略面:iptables 承载 security group 等安全策略,不做 L2 隔离;
- 控制面:BIRD(BGP)负责计算节点间路由扩散;Calico DHCP agent 以 etcd 为数据源(
/calico/v1/host/<hostname>/workload与/calico/dhcp/v1/subnet),复用RoutedInterfaceDriver+DnsmasqRouted完成基于网关 IP 的 DHCP 地址下发,同时彻底绕开 Neutron server 的 RPC 扇出与端口 IP 分配负担。
理解这一实现,也就理解了为什么 Calico 要求 Neutron 网络满足"单一地址作用域、l2_adjacency False、网络默认互通"这三项约束——它们不是限制,而是整个三层路由方案的直接推论。
- 网络
- 云原生
- 网络安全
【免费下载链接】calico
Cloud native networking and network security
相关推荐
Calico OpenStack 集成指南:networking-calico 的路由连通性与 DHCP Agent 架构解析
Calico OpenStack 集成指南:networking calico 的路由连通性与 DHCP Agent 架构解析 networking calic
网络云原生网络安全Calico DHCP 代理:基于 etcd 数据驱动的 OpenStack Neutron DHCP 架构改造
Calico DHCP 代理:基于 etcd 数据驱动的 OpenStack Neutron DHCP 架构改造 Calico DHCP 代理(Calico D
网络云原生网络安全golang-jwt/jwt/v5 完全指南:Go 语言 JWT 签发、解析与安全校验的权威实现
golang jwt/jwt/v5 完全指南:Go 语言 JWT 签发、解析与安全校验的权威实现 本指南以本仓库中 vendor 的 golang jwt/jw
云原生操作系统容器编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考