Overlay 网络封装网卡选择¶
在一些场景下,用户希望容器 Overlay 网络使用主机不同的网卡进行 tunnel 封装,从而实现:
- 存储网络分离:存储流量走专用高速网卡,业务流量走普通网卡。
- 业务网络隔离:不同业务子网使用不同物理网卡,实现物理层面的网络隔离。
- 网络带宽控制:通过物理网卡分离实现带宽隔离,避免业务流量相互干扰。
默认封装网卡选择¶
在节点存在多块网卡的情况下,Kube-OVN 默认会选择 Kubernetes Node IP 对应的网卡作为容器间跨节点通信的网卡并建立对应的隧道。
如果需要选择其他的网卡建立容器隧道,可以在安装脚本中修改:
IFACE=eth1
该选项支持以逗号分隔的正则表达式,例如 ens[a-z0-9]*,eth[a-z0-9]*。
安装后也可通过修改 kube-ovn-cni DaemonSet 的参数进行调整:
args:
- --iface=eth1
如果每台机器的网卡名均不同,且没有固定规律,可以使用节点 annotation ovn.kubernetes.io/tunnel_interface 进行每个节点的逐一配置,拥有该 annotation 节点会覆盖 iface 的配置,优先使用 annotation。
kubectl annotate node no1 ovn.kubernetes.io/tunnel_interface=ethx
为不同子网指定封装网卡¶
除了全局默认的封装网卡配置外,Kube-OVN 还支持为不同子网指定使用主机不同的网卡 IP 进行 tunnel 封装,从而实现容器网络通过主机不同网卡进行转发。
前提条件¶
- 主机需要配置多块网卡,且各网卡均已配置 IP 地址。
- 各网卡对应的网络需要能够互通(同一网络平面内的主机之间)。
- 该功能仅支持 Overlay 类型子网。
工作原理¶
- 用户在 Node 上通过注解声明多个网络平面及其对应的封装 IP。
- 在 Subnet 中通过
nodeNetwork字段指定该子网使用哪个网络平面。 - kube-ovn-daemon 监听节点注解变化,将所有封装 IP 设置到 OVS。
- 当 Pod 创建时,如果其所属子网配置了
nodeNetwork,则会为该 Pod 的 OVS 端口设置对应的封装 IP。
配置节点网络¶
在需要配置多网络平面的节点上,添加 ovn.kubernetes.io/node_networks 注解。注解值为 JSON 格式,key 为网络名称,value 为该网络对应的封装 IP。
kubectl annotate node <node-name> ovn.kubernetes.io/node_networks='{"storage": "192.168.100.10", "app": "172.16.0.10"}'
上述命令定义了两个网络平面:
storage:使用 IP192.168.100.10(假设该 IP 配置在高速存储网卡上)app:使用 IP172.16.0.10(假设该 IP 配置在业务网卡上)
对于多节点集群,需要在每个节点上配置对应的网络注解,确保同一网络名称在不同节点上使用的是同一网络平面的 IP。
配置子网¶
创建子网时,通过 spec.nodeNetwork 字段指定该子网使用的网络平面:
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
name: storage-subnet
spec:
protocol: IPv4
cidrBlock: 10.100.0.0/16
gateway: 10.100.0.1
nodeNetwork: storage
该配置表示 storage-subnet 子网下的 Pod 将使用 storage 网络平面进行 tunnel 封装。
如果不配置 nodeNetwork 字段,子网将使用默认的封装 IP(由 IFACE 参数指定的网卡 IP)。
验证配置¶
检查 OVS 封装 IP 配置¶
在节点上执行以下命令,查看 OVS 配置的封装 IP:
ovs-vsctl get open . external-ids:ovn-encap-ip
输出应包含所有配置的封装 IP,例如:
"192.168.1.10,192.168.100.10,172.16.0.10"
查看默认封装 IP:
ovs-vsctl get open . external-ids:ovn-encap-ip-default
检查 Pod 端口的封装 IP¶
创建 Pod 后,可以检查 Pod 对应 OVS 端口的封装 IP 设置:
ovs-vsctl --columns=external_ids find interface external-ids:iface-id="<pod-name>.<namespace>"
如果子网配置了 nodeNetwork,输出中应包含 encap-ip 字段:
external_ids : {encap-ip="192.168.100.10", iface-id="test-pod.default", ...}
使用示例¶
以下是一个完整的存储网络分离示例:
1. 配置节点网络注解¶
假设集群有两个节点,每个节点都有两块网卡:
eth0:业务网卡,IP 分别为192.168.1.10和192.168.1.11eth1:存储网卡,IP 分别为10.10.10.10和10.10.10.11
kubectl annotate node node1 ovn.kubernetes.io/node_networks='{"storage": "10.10.10.10"}'
kubectl annotate node node2 ovn.kubernetes.io/node_networks='{"storage": "10.10.10.11"}'
2. 创建存储子网¶
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
name: storage-net
spec:
protocol: IPv4
cidrBlock: 10.200.0.0/16
gateway: 10.200.0.1
nodeNetwork: storage
namespaces:
- storage-namespace
3. 创建使用存储网络的 Pod¶
apiVersion: v1
kind: Pod
metadata:
name: storage-pod
namespace: storage-namespace
spec:
containers:
- name: app
image: docker.io/library/nginx:alpine
该 Pod 的网络流量将通过存储网卡(eth1)进行转发。
注意事项¶
- 确保同一网络平面内的所有节点之间网络互通。
- 节点注解中配置的 IP 必须是该节点上实际存在的有效 IP 地址。
- 该功能仅适用于 Overlay 类型子网,Underlay 子网不支持此配置。如需配置 Underlay 网络,请参考 Underlay 网络安装。
- 如果子网未配置
nodeNetwork,或配置的网络名称在节点上不存在,将使用默认封装 IP。 - 如果 Pod 调度到的节点上不存在子网指定的
nodeNetwork对应的注解,Pod 将会运行失败。请确保所有可能调度到的节点都配置了相应的网络注解。 - 在进行节点增加或节点网络调整时,需要及时更新对应节点的
ovn.kubernetes.io/node_networks注解,避免 Pod 运行失败。