Calico ➕ KubeOVN —— 为 KubeVirt VMs 提供受限的 underlay 网络访问
Contents
背景
租户应用通过内网访问云服务可以做到带宽成本趋近零 (一般免费)。内网线路的带宽上限要比公网线路高得多。
阿里云等大的云厂商,其云服务通常兼具外网域名和内网域名。虚拟机使用内网域名发送请求时,流量会通过内网线路到达云服务。 阿里云对象存储 OSS 即在此例,参见 OSS内网域名与VIP网段对照表。
背后原理应该是默认对客户 VPC 和云服务 VPC 做了 JOIN,使得 OSS 在客户 VPC 可达 (via 100.64.0.0/10)。
在 Kubernetes 之上,搭配使用 KubeVirt 和 KubeOVN,小厂商可以快速获得虚拟机 (virtual machine, VM) 和软件定义网络 (Software-Defined Networking, SDN)。同样地,租户亦有使用内网访问云服务的需求。
虽然 KubeOVN 支持 VPC 互通,但并不支持自定义 VPC 和物理节点互通。如果某项云服务跑在物理机上,仅使用 KubeOVN 则意味着流量需要在同机房的外网线路兜一圈。带宽上限会比较低。
可行的解决方式是使用 Multus-CNI 为虚拟机提供多张网卡,由不同网卡提供不同能力
- KubeOVN 网卡提供 VPC, SecurityGroup 等 SDN 能力
- Calico 网卡提供节点网络访问能力。访问权限必须是安全受限的。这一点可以由 Calico network policy 达成。
下文分小节展示具体细节。
Multus 配置
虚拟机相关 CNI 配置均通过 NetworkAttachmentDefinition 管理,直接自 /etc/cni/net.d/
目录拷贝即可。
|
|
|
|
KubeVirt VirtualMachine 声明及注意点
KubeVirt VirtualMachine spec.networks
所有类型为均为 multus。
这样做较为灵活。注意,有 pod 类型网络存在时,无法指定 multus 类型网络为默认。
|
|
这里 Calico PodCIDR 为 10.199.0.0/16
。注解 cni.projectcalico.org/ipAddrs
表示向 Calico 申请固定 IP。为避免 IP 冲突,可以专门为 VM 预留一批 IP。具体参见 Use a specific IP address with a pod。
KubeVirt 会将网络转换为 Pod 注解 v1.multus-cni.io/default-network
和 k8s.v1.cni.cncf.io/networks
v1.multus-cni.io/default-network: default/calico
声明第主网卡为 calicok8s.v1.cni.cncf.io/networks: '[{"interface":"pod16367aacb67","name":"kubeovn","namespace":"default"}]'
声明额外的 KubeOVN 网卡
Multus 读取到 annotation 之后,会读取集群 NetworkAttachmentDefinition,接着按照声明为 VM Pod 创建网卡。
更通顺的逻辑是第主网卡使用 KubeOVN,次网络使用 Calico。但 Calico 在检测到 Pod network namespace 设置过 default 路由时,会报错并无法分配网卡,详见 Calico issue 5199。
处理方式是在 Calico CNI 插件之后增加一个路由处理插件 x-calico-route
,删除 Calico 设置的默认路由,并增加 underlay 网络路由 (10.199/16 为 Calico PodCIDR, 10.50/16 为 Node CIDR)。
|
|
KubeOVN 作为次要网络时,不会设置默认路由,有两种解决方式:一是使用类似 x-calico-route
的路由插件自动插入,二是在使用 KubeVirt 提供的 cloud-init Network configuration。
这里 OVN Subnet/Switch CIDR 为 10.0.1.0/24,网关为 10.0.1.1。
以下是 Network configuration v1,适用于 CentOS 7 等内核版本较低的情况。
|
|
以下是 Network configuration v2,适用于 Ubuntu 18.04, 20.04, 22.04 等。
|
|
这里的方案使用了 cloud-init,且没有 dhcp 匹配设置。
如果只能使用 CNI,默认的 cloud-init v2 版配置会按照 macaddress 分配 IP。
|
|
这时可以考虑使用 Kubemacpool 之类的方案固定 Calico 网卡 Mac 地址。
underlay 网络策略
参照 Get started with Calico network policy 为 VM 设置 underlay 网络策略,以下示例为只允许虚拟机 testvm
访问 IP 10.50.31.21
的 80 端口
和 443 端口
。
|
|
总结
通过 Calico 和 KubeOVN 双网卡,本文实现了一种向 KubeVirt 虚拟机租户提供了可控的内网访问方式。
K8s 平台方可以考虑采用这种方式,向不受信任的租户提供内网服务访问。
你可以点击查阅 过程脚本,并使用 KinD 集群验证本文提出的方法。
⚠️⚠️⚠️ 注意
前文提及,为避免 IP 冲突,项目可以使用 Calico IPReservation 为 VMs 预留一批 IP 地址。
为实现规模化,可以基于 K8s mutating admission webhook server 来实现全局 IP 分配服务。
该服务会拦截 VMs 创建请求,自请求获取 VM 对象,并向资源池发起 IP 分配请求,最后将获分配 IP 写入 template 注解 cni.projectcalico.org/ipAddrs
中。
如果采用CNI 插件方式,如 x-calico-route
,进行路由定制,可以将其打包在容器镜像中,并通过 DaemonSet 分发到所有节点目录 /opt/cni/bin
中。
如果采用 cloud-init Network configuration 定制路由,也可以通过 mutating admission webhook server 对新创建的 VMs 进行动态修改。
Author Zeng Xu
LastMod 2023-08-15 00:05
License 本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可,转载时请注明原文链接。