Skip to content

VLAN 网络

Huanyu He edited this page Nov 25, 2022 · 13 revisions

通过创建如下 Network 对象可以生成一个 VLAN 容器网络

apiVersion: networking.alibaba.com/v1
kind: Network
metadata:
  name: network1
spec:
  netID: 0
  type: Underlay                 # type 需要为 Underlay
  mode: VLAN                     # mode 可以不填,Underlay type Network 的 mode 默认为 VLAN
  nodeSelector:
    network: "s1"

在同一 VLAN 网络域下的节点通常需要:每个节点上至少要有一张网卡接入到了相同的二层网络并且节点之间可以通过该二层网络直接通信

在创建了 Network 对象之后,我们需要创建至少一个 Subnet 对象,Pod 才能在这个网络域中创建,需要注意的是 VLAN Subnet 与其所属的 Network 之间的 spec.netID 字段存在一定的约束关系。如果 Network 的 spec.netID 为空,Subnet 的 spec.netID 一定不能为空;如果 Network 的 spec.netID 不为空,Subnet 的 spec.netID 只能为空或者与 Network 的值相同。当 Subnet 的 spec.netID 为空时,会默认自动继承 Network 的 spec.netID

只有当 Subnet 的实际 netID 不为 0 时,hybridnet 才会为容器网络额外创建 “VLAN tag 等于 netID” 的 vlan 子设备。如果 Subnet 的实际 netID 为 0,容器网络和宿主机网络使用同一个 VLAN

apiVersion: networking.alibaba.com/v1
kind: Subnet
metadata:
  name: underlay-subnet1
spec:
  network: underlay-network1
  netID: 0
  range:
    version: "4"
    cidr: "192.168.56.0/24"
    gateway: "192.168.56.1"     # 外部网关地址

每个位于 VLAN 网络域中的 Subnet 都对应了节点二层网络中的实际网段,也就是说用户需要预先做好对该网段的环境配置(通常是进行交换机配置,如果 Subnet 的 netID 不为 0,表示容器网段与宿主机网段不在一个 VLAN,需要将上联交换机端口配置为 trunk;如果是虚拟机的话,也有可能是修改 IaaS 层相关设置),比如“放行对应 VLAN 的流量”、“添加对应网段的路由规则”等等

VLAN 类型的容器网络流量具有如下性质:

  1. 相同 Subnet 中的 Pod 跨节点通信时,会在两 Pod 所在节点之间直接通过二层交换通信(不经过外部网关路由)
  2. 不同 Subnet 之间的 Pod 通信或者 Pod 访问集群外部地址时会通过 spec.range.gateway 表示的外部网关设备进行路由
  3. Pod 所在的 Network/Subnet 一定存在一个不为空的 spec.netID 字段。当该字段不为 0 时,Pod 发送出节点网卡的流量会带有跟该字段相同值的 VLAN tag;当 spec.netID 为 0 时,Pod 发送出节点网卡的流量不会额外添加 VLAN tag
  4. 跨节点报文的 MAC 源/目标地址只会是节点网卡的 MAC 地址

每个 VLAN 网络类型的 Pod 本质上就相当于节点网卡(或者说网卡 vlan 子设备)上的一个新 IP 地址,这个 IP 地址对底层网络直接可见,并且外部可以通过这个 IP 地址直接访问 Pod

VLAN 网络的 Pod 在创建时,hybridnet 会做一些基本的网络环境检查,主要包括

  1. 检查底层网络环境中是否有其他设备在使用跟 Pod 相同的 IP 地址
  2. 检查 Subnet 的 gateway 地址是否二层可达

如果检查失败,Pod 会保持 ContainerCreating 状态,通过 kubectl describe 命令可以查看对应信息

VLAN 网络的数据平面与 hybridnet 控制逻辑解藕,也就是说,就算 hybridnet 组件的 Pod 全部被删除也不影响存量的 VLAN Pod 的网络通信

hybridnet VLAN 模式的网络是使用 Policy Routing + neigh proxy 实现的 “伪二层网络”,实际上每个容器属于独立的广播域,并不共享一个广播域,所以也不存在一个对外部网络直接打通的广播域