关于为什么要用OpenStack 管理 vSphere 集群,原因可以有很多,特别是一些传统企业中 VMware 的使用还是很普遍的,用 OpenStack 纳管至少会带来存量VMware环境管理上的便捷性。
1. 部署架构
1.1 vSphere 网络的有关概念
vSphere DVS的架构图:
(图片来源)
VMware 在发布 vSphere 4.0时推出了 vSphere Distributed Switch。 与 vSphere 传统交换机 vSphere Standard Switch (VSS) 相比,VDS 扩展了虚拟网络的特性和功能,同时简化了资源调配以及日常的配置、监控和管理过程。VDS将网络作为一个聚合资源进行处理,减轻了针对每个主机级虚拟交换机配置进行管理的负担。 各个主机级别的虚拟交换机被抽象处理成一个大型的 VDS,此 VDS 跨数据中心级别的多个主机。 在此设计中,数据板保持在每个 VDS 的本地,但管理板采用集中机制,将 vCenter Server 作为所有已配置的 VDS 实例的控制点。
VDS 可以划分为两个逻辑部分,分别是数据面板和管理面板。 数据面板执行实际的数据包交换、筛选、标记等。管理面板是一个控制结构,供操作员用来配置数据板的功能。 而在VSS中每一个标准交换机上都有数据板和管理板。
使用VDS 后,每个 ESXi 主机上的虚拟交换机都会被抽象为一个大的池子。每个 VDS 交换机可以跨一个数据中心之内的多台ESXi 主机。每个 vCenter server 可以管理多大128 个 VDS,每个VDS 最多可以添加到 500 台ESXi 主机上。
几个概念的说明:
- DVS:vSphere 分布式虚拟交换机,如上图中的 vDS_Tanent 和 vDS_SDN。
- PortGroup:端口组。端口组存在于DVS之上,连接到DVS的端口都存在于PG中。
- Port:端口。外部设备通过端口连接到DVS。典型地,包括上联端口,与物理网卡连接,如图中的10G网卡;连接虚机的端口(上图中业务虚机通过端口连接到vDS_Tanent,OVSvAPP虚机通过端口连接到vDS_Tanent 和 vDS_SDN),这是生产网络;VMkernel 端口,这是用于ESXi自己的服务使用的网络。
端口组分类:
- Uplink Port Group:上联端口组成的端口组。可以配置宿主机的物理网络连接,以及failover 和 load balancing 策略等。在宿主机侧,每个物理网卡都连到到一个上联端口,都拥有一个特定ID。
- Distributed Port Group:分布式端口组,包括VMkernel 和 虚机使用的端口组成的组。可以在这种端口组上配置NIC teaming, failover, load balancing, VLAN, security, traffic shaping等功能。
三种端口组:VMkernel、VM、Uplink
VMkernel 端口组:主要用于ESXi 自己的各种功能,比如 管理、HA, FT等
上联端口组:
添加物理网卡:每个 vmnic 是宿主机的一块物理网卡
VM 网络:将虚拟机连接到DVS。这是生产网络。
关于 vSphere 网络的更多资料,可以参考 https://www.altaro.com/vmware/vsphere-networking-basics-part-1/ https://www.altaro.com/vmware/vsphere-networking-basics-part-2/等文章。
1.2在生产环境中的部署架构
节点 | 网卡数 | 网卡用途 |
KVM宿主机 | 4 |
10G:存储网络 10G:SDN网络 1G:管理网络 1G: IPMI网络 |
ESXi 宿主机 | 5 |
HBA:存储网络 10G:SDN网络 10G:vmKernel 网络 1G:管理网络 1G: IPMI网络 |
在一台ESXi 宿主机内的网络连接:
说明:
- vDS_internal 是一个 vSphere分布式交换机。它不绑定宿主机的物理网卡,因此其网络包出不了宿主机。生产虚拟机和OVSvAPP 虚拟机都连接到它上面,其作用是让生产虚拟机出来的网络包流入 OVSvAPP,经过其中的 OVS 处理,然后发到 vDS_SDN 分布式交换机。其中,生产虚拟机按照所在的VLAN 网络,划分到若干个端口组中,每个端口组的VLAN是唯一的。下面的『有趣的环路』部分会有涉及。
- vDS_SDN 是一个vSphere分布式交换机。它的主要作用是让经过 OVSvAPP 虚拟机中处理过的生产虚机的流量留出宿主机。因此它支持两个网络流量:一种是跨ESXI 但同虚拟网络的虚机之间的网络流量,以及在一个 ESXI 内虚机出宿主机的网络流量。因此,它需要跨宿主机通信,所以需要绑定物理网卡。
- vmKernel 网络也需要支持跨宿主机通信,因此也需要绑定物理网卡,用于vMotion之类的vSphere内部服务。
- 另外还需要考虑物理网卡高可用,因此还需要添加更多的网卡。
2.组件
本质上,OpenStack 将 vSphere Cluster 作为一 Nova compute 节点。OpenStack Nova 负责将虚机调度到 vSphere Cluster 上(该调度可以基于AZ),然后 vSphere DRS 负责虚机在集群内部的调度。
备注:OVSvAPP 方案只是多个候选方案中的一种。
2.1 cinder volume 的 vcdriver
使用: volume_driver=cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver
过程:cinder-volume 从MQ 接收到请求后,驱动 vcdriver 连接 vCenter 调用其 API 执行操作。
功能:支持的功能包括:
- Create, delete, attach, and detach volumes.
- Create, list, and delete volume snapshots.
- Create a volume from a snapshot.
- Copy an image to a volume.
- Copy a volume to an image.
- Clone a volume.
- Backup a volume.
- Restore backup to new or existing volume.
- Change the type of a volume.
- Extend a volume
2.2 nova-compute 的 vcdriver
我们使用 compute_driver = vmwareapi.ovsvapp_vc_driver.OVSvAppVCDriver,其配置如下:
[vmware]
host_ip=<vCenter 的IP地址>
host_username=<vCenter admin username>
host_password=<vCenter admin password>
cluster_name=<vSphere Cluster name>
datastore_regex=compute*
wsdl_location=https://<host_ip>/sdk/vimService.wsdl
2.3 镜像处理
我们没有使用 vsphere 作为 glance 的 backend store,而是把镜像放在 ceph 之中。
glance image-show a88a0000--42dd-9b5f-ee0fbf313cf1
+------------------+----------------------------------------------------------------------------------+
| Property | Value |
+------------------+----------------------------------------------------------------------------------+
| checksum | 0000000000000000000000000 |
| container_format | bare |
| created_at | --19T01::33Z |
| direct_url | rbd://6dc80000-2675-4f31-0000-b818f00d178c/pool-0/a88a0000-0000-42dd-9b5f- |
| | ee1fbf313cf1/snap |
| disk_format | vmdk |
| hw_disk_bus | scsi |
| hw_scsi_model | paraVirtual |
| id | a88a0000-0000-42dd-9b5f-ee1fbf313cf1 |
| img_hv_type | vmware |
| min_disk | |
| min_ram | |
| name | debian.vmdk |
| owner | 00000000000000000 |
| protected | False |
| size | |
| status | active |
| tags | [] |
| updated_at | --17T06::48Z |
| virtual_size | None |
| visibility | private |
| vmware_disktype | eagerZeroedThick |
+------------------+----------------------------------------------------------------------------------+
nova-compute 首先从分布式存储中下载镜像文件到本地,然后 nova 的 vmware driver 会通过 HTTP 将镜像传送到 vSphere datastore。相关代码可参考https://github.com/openstack/nova/blob/master/nova/virt/vmwareapi/vmops.py。这么做的好处是可以统一KVM和VMware镜像的管理方式,但是会导致新镜像第一次创建虚机时间较长。
3. 网络
我们采用 OVSvAPP 网络方案,链接在这里https://wiki.openstack.org/wiki/Neutron/Networking-vSphere。 我们采用 VLAN 网络模式。
3.1 架构
3.2 租户网络流向
3.2.1 各场景网络包路线示意图
红线:DVS1 中,OVSvAPP agent 会为每个 network 创建一个全局性 port group,如图中 ESXi 节点1 上的 Port Grp 7。若 VM1 和 VM2 在同一个 vlan 中,两者的通讯会直接在 Port Grp 7 内进行。
紫线:ESXi 2 上,VM2 和 VM3 在两个 vlan 上。网络包从 VM2 出发,首先经过 ESX2 上的 OVSvAPP 虚机,再经过 vDS_SDN 出宿主机,然后经过网络节点做路由交换,再经过 vDS_SDN 返回ESX2 上的 OVSvAPP 虚机,再到达 VM3。图中的紫线其实有点误导,因为它实际上出了ESXI 到了网络节点(Network Node)。
绿线:ESX1 上的 VM3 和 ESXi2 上的 VM2 在同一个 vlan 上,但是分开在两个宿主机上。两者的通讯需要经过 ESX1 上的 OVSvAPP 虚机,再经过 vDS_SDN 分布式交换机,再达到 ESX2 上的OVSvAPP 虚机,再达到 VM2.
黄线:ESXi1 上的 VM2 和 ESXi 2 上的 VM1 在不同的 vlan 上,且分在两个宿主机上。两者的通讯需要经过各自宿主机上的 OVSvAPP 虚机以及网络节点。
3.2.2 br-int 的流表
#这是从端口5(br-ens192) 也就是dVS_SDN 进来的也就是从宿主机外面发过来的网络包,到有物理的 vlan id。修改 vlan id 后,发到端口1 也就是到 br-sec 去,再到 dVS_tenant
n_packets=, n_bytes=, idle_age=, hard_age=, priority=,in_port=,dl_vlan= actions=mod_vlan_vid:,output:1 #把从端口1 也就是 br-sec 进来的包也就是虚机发出的包发到端口5 也就是 br-ens192也就是物理网卡
n_packets=, n_bytes=, idle_age=, hard_age=, priority=,in_port=,dl_vlan= actions=output:
其主要职责是把物理 vlan id (dl_vlan)修改为内部的 vlan id,然后再发到合适的端口。
3.2.3 br-ens192 的流表
hard_age=, priority=,rarp,in_port= actions=NORMAL
hard_age=, priority=,in_port=,dl_vlan= actions=mod_vlan_vid:,output:hard_age=, priority=,in_port=,dl_vlan= actions=mod_vlan_vid:,output:hard_age=, priority=,in_port=,dl_vlan= actions=mod_vlan_vid:,output:hard_age=, priority=,in_port=,dl_vlan= actions=mod_vlan_vid:,output:hard_age=, priority=,in_port=,dl_vlan= actions=mod_vlan_vid:,output:1
priority=0 actions=NORMAL
它负责把内部 vlan id 转换成物理 vlan id 再发到端口1 也就是 SDN 网卡 ens192. 而从物理网卡 ens192 进来的则直接走到 br-int。
3.2.4 br-sec 的流表
dst= actions=fin_timeout(idle_timeout=),output:hard_age=, priority=,tcp,vlan_tci=0x0002/0x0fff,nw_src=10.70.160.191,nw_dst=10.70.16.187,tp_src=,tp_dst= actions=fin_timeout(idle_timeout=),output:hard_age=, priority=,tcp,vlan_tci=0x0002/0x0fff,nw_src=10.70.160.191,nw_dst=10.70.16.187,tp_src=,tp_dst= actions=fin_timeout(idle_timeout=),output:hard_age=, priority=,tcp,vlan_tci=0x0002/0x0fff,nw_src=10.70.160.187,nw_dst=10.70.16.191,tp_src=,tp_dst= actions=fin_timeout(idle_timeout=),output:hard_age=, priority=,tcp,vlan_tci=0x0002/0x0fff,nw_src=10.70.160.187,nw_dst=10.70.16.191,tp_src=,tp_dst= actions=fin_timeout(idle_timeout=),output:hard_age=, priority= actions=drop
hard_age=, priority= actions=drop
它的主要职责是作为安全组和防火墙。Neutron ovs agent 负责将安全组规则转换为OVS 流表,对进出虚机的网络包进行过滤。
3.2.5 DRS 支持
VMware DRS 可以动态地将虚机在 ESX 节点之间迁移。因此,为了支持 DRS,在每个 OVSvAPP 虚机之内,流表都是一样的。这样,不管虚机迁移到哪里,其网络都不会收到影响。当然,这也会造成流表过大。这会导致 CPU 占用增加,以及网络延迟加大。
下图比较了不同数量级流表下的 OVSvAPP 虚机的CPU占用情况。
3.3 VLAN 模式下虚机网卡的处理过程
这里面能看到运行在 OVSvAPP 虚机中的 neutron agent 驱动 vSphere 根据 port 的 vlan id 创建 Port Group 过程。在创建好以后,Nova Compute Proxy 再把port 绑定到虚机,同时创建各种bridge(br-int,br-sec,br-ex)的流表。为了实现这逻辑,社区提供了 nova 的 OVSvAppVCDriver 驱动。
3.4 网络性能
3.4.1 官方建议网络配置
DVS 的 Uplink 网卡以及 Trunk 口的 MTU 设置为 9000
OVSvAPP 虚机里面的 br-int, br-sec 和 br-ex 的 MTU 设置为 8900
虚机的 MTU 设置为 8900
ESX 的物理 uplink 网卡的MTU 设置为 9000
3.4.2 OVSvAPP 方案对虚机的吞吐性能影响较小
3.4.3 但是对延迟影响还是蛮严重的,毕竟网络路径大大延长了。
3.5 VMware 虚机和KVM 虚机通讯
4. 有趣的网络环路
在我们的环境中,运维不小心将一个 ESXI 上的 OVSvAPP 虚机迁移到了另一个ESXI 上,结果造成网络大面积抖动。经排查,原因是因为两个 OVSvAPP 虚机形成了环路,造成到 10G 网口上的广播包风暴。下图中的紫线表示了这个环路:
因为两个 OVSvAPP 虚机连接 vDS_tanent 和 vDS_SDN 的端口都是 trunk模式,因此环路得以形成。为了验证该环路,将第二个 OVSvAPP 虚机连接 vDS_tanent 的网卡禁用后,网络恢复正常,因为环路被破坏了。
最简单的处理方式是,在任何时候都不要把两个 OVSvAPP 虚机放在同一个 ESXI 上,并且不能将vDS_tanent 连接到物理网卡上将它打通,否则不同ESXI上的 OVSvaAPP 会形成环路。
而为什么当两个 OVSvAPP 虚机在两个 ESXI 上没有形成环路呢?这是因为 vDS_tanent 这个分布式交换机其实不是跨 ESXI 相通的,因为它没有绑定物理网卡。
5. 一些局限
OVSvAPP 方案是一个比较不错的方案,包括:
- 支持neutron,支持VLAN 和 VXLAN
- 支持安全组
- 支持 DRS
但是也存在一些局限,包括但不限于:
- 增加了单点故障风险,比如 OVSvAPP 虚机自身的单点故障,以及 Proxy VM 的单点故障
- 网络路径太长,造成网络延迟大大增加
- OVSvAPP 内的流表数目会随着集群规模的增加而成倍增加。一方面这会限制集群规模,也会进一步增加网络延迟以及资源消耗。
- 同一个ESX宿主机上的同一个网络之间的虚机之间没有安全组,因为没有经过 OVSvAPP 虚机。
- VDS 功能有限,本质上只是一个 OVS。相比 NSX,只能支持基本的网络功能。
(来源:VIO VDS 和 NSX 方案对比)
参考链接: