0、前言
本文将以Openstack在Linux Bridge环境下的应用为例进行阐述。
1、Openstack抽象网络
OpenStack的抽象网络主要包括网络(network)、子网(subnet)、端口(port),路由器(router)。有了这些基础的网络抽象元素,就能够灵活地进行二层或三层的网络组建。
Openstack抽象网络示意
另外,需要特别指出的是,OpenStack的抽象网络是由特定用户(user)在特定项目(project)下创建的。
这意味着OpenStack的抽象网络具有项目(project)属性,也就是租户(Ternant)属性,因为openstack里面的project,其实就是租户的概念,目的是对资源进行隔离(包括计算/网络/存储),相互不可见,但不意味着相互不能通讯。通过设置,不同租户的网络环境是可以互通的,比如通过各自的router或者共享的router互指路由。
Openstack抽象网络具有Project/租户属性示意
Openstack的抽象网络可以被看作是Openstack自己眼中的网络,或者是从租户/用户/项目的视角看到的网络,它是一个相对简单的三层路由和二层交换(L3 routing/L2 switching)环境。
2、Openstack实体网络
OpenStack的实体网络由虚拟网络和物理网络两部分组成。
虚拟网络主要是指在主机(例如控制节点和计算节点)内部,通过虚拟网络技术创建的网络,如Linux bridge和Linux OVS。这里的虚拟网络是指可以通过Openstack借助虚拟网络技术进行创建和管理的部分。
物理网络则涉及主机的网卡(因为主机内的虚机需要和外部通讯,不同主机的虚机之间也需要通讯,这些都需要借助网卡进行)。这里的物理网络是指可以通过Openstack进行控制的部分,比如把一个网卡作为bridge的一个端口。
Openstack实体网络示意
Openstack实体网络可以理解为Openstack抽象网络的具体实现。Openstack实体网络通常对租户/user/project不可见。实体网络通常由Openstack管理员(admin)进行管理和维护。
3、Openstack抽象网络和实体网络的关系
1、OpenStack 负责配置实体网络的参数。
/etc/neutron/plugins/ml2/ml2_conf.ini
是 OpenStack Neutron 网络服务的一个配置文件,用于定义 ML2 插件的行为。ML2 是一个多厂商的网络驱动程序插件,它允许 Neutron 支持多种网络类型。这个文件通常包含以下内容:
- type_drivers : 定义了 Neutron 支持的网络类型,如
flat
,vlan
,gre
,vxlan
等。- tenant_network_types: 定义了租户网络可以使用的网络类型。
- mechanism_drivers : 定义了网络后端的机制驱动程序,如
openvswitch
,linuxbridge
,sriovnicswitch
等。
/etc/neutron/plugins/ml2/linuxbridge_agent.ini
是 OpenStack Neutron 的一个配置文件,用于设置 Linux Bridge 代理的行为。以下是该配置文件中一些常见的配置选项:
- [linux_bridge] 部分包含物理网络接口的映射设置,例如:
physical_interface_mappings
:将物理网络名称映射到代理节点(比如controller node或者compute node)特定的物理网络接口。- [vxlan] 部分包含 VXLAN 网络的配置,例如:
enable_vxlan
:是否启用 VXLAN。local_ip
:本地隧道网络端点的 IP 地址。- [securitygroup] 部分包含安全组的配置,例如:
enable_security_group
:是否启用安全组。firewall_driver
:安全组防火墙的驱动程序。
2、OpenStack 负责创建/编排抽象网络,并根据实体网络的配置,自动构建实体网络(包括虚拟网络和物理网络)。
4、创建Openstack抽象网络,实体网络自动执行相关操作
4.1 创建network
Openstack创建network
这是创建network的例子。user admin在project admin下,创建了一个名称为"provider"的network,这个network是share的,意味着其他project可以使用这个network。这个network关联了物理网络"provider",这个物理网络是在ml2_conf.ini文件中进行了定义,并且在每台主机的linuxbridge_agent.ini中和该主机的网卡进行了映射,说明这个network在每台主机是如何和物理网络进行对接的。
从网络方面看,一个network代表着一个二层的广播域。对应实体网络就是每台主机的一个bridge。这个bridge是按需创建的,单纯的创建一个network,并不会在实体网络中有具体操作。
4.2 创建subnet
创建subnet
在network "provider"之上,创建了一个名称为"provider"的subnet。
从网络方面看,subnet是指IP子网的概念。subnet并没有对应的实体网络。subnet主要限制了主机IP地址之间的通讯方式。
IP地址之间通讯,依赖IP地址,同时还依赖子网掩码。
当一个主机A需要和另一个主机B通讯时,首先会将目的主机B的IP地址和自己的掩码(主机A的掩码)进行计算,得出子网号1。
同时,主机A自己的IP地址和自己的掩码(主机A的掩码)进行计算,得出子网号2。
如果子网号1和子网号2相同,主机A就知道主机B和自己在同一个子网(subnet),此时主机A如果不知道主机B的MAC地址,就发出ARP广播请求(目的地址255.255.255.255),这个ARP请求会封装为二层的广播帧(目的地址FFFF.FFFF.FFFF)。
如果子网1和子网号2不同,主机A就知道主机B和自己不在同一个子网,此时主机A就直接把这个包发给网关(gateway)。此时主机A会把IP包(源地址主机A的IP,目的地址主机B的IP)封装为二层帧(源MAC为主机A的MAC,目的MAC为网关的MAC)。主机A如果只知道网关的IP地址(配置中会指明),不知道网关的MAC地址,也会首先发出ARP请求,查找网关的MAC地址。
举例说明:
1、假设主机A为192.168.1.1,掩码为255.255.255.0,主机B为192.168.1.2,A需要和B通讯,A则将192.168.1.2和255.255.255.0进行计算,得出子网号1(192.168.1.0),同时A将自己的IP地址192.168.1.1和255.255.255.0进行计算,得出子网号2(192.168.1.0),子网号1和子网号2相同,所以A知道B和自己在同一个子网(subnet)。如果A不知道B的MAC地址,发出ARP进行查找。
2、假设主机A为192.168.1.1,掩码为255.255.255.0,主机B为192.168.2.2,A需要和B通讯,A则将192.168.2.2和255.255.255.0进行计算,得出子网号1(192.168.2.0),同时A将自己的IP地址192.168.1.1和255.255.255.0进行计算,得出子网号2(192.168.1.0),子网号1和子网号2不相同,所以A知道B和自己不在同一个子网(subnet),此时IP包(源地址为192.168.1.1,目的地址为192.168.2.2)会封装成二层帧(源地址为A的mac,目的地址为网关的mac),发往网关进行处理。如果A不知道网关的MAC地址,会首先发出ARP进行查找。
这个subnet上的虚机需要dhcp动态分配地址。这就需要在实体网络在进行具体的操作。
在neutron安装中,在controller安装了dhcp agent:
在controller node上会针对"provider" network创建一个network namespace,运行dhcp服务,专门用于这个network的dhcp服务:
同时在controller node针对"provider" network,创建一个bridge,dhcp的netns会连接到这个bridge。
为了给这个subnet提供dhcp服务,在qdhcp-48f2b连接bridge的端口分配了该子网的IP地址:
4.3 创建虚机
首先由nova决定在哪台主机创建虚机,这里是在compute1节点创建了虚机。
同时通过--nic参数指定在network "provider"上创建虚机。
该虚机在正常创建和启动的情况下,在compute1上会针对network "provider"创建一个bridge,虚机连接到该bridge,同时网卡ens35也连接到该bridge上:
这样,虚机在启动过程中,发送dhcp请求就可以到达controller节点上的dhcp server(qdhcp-qdhcp-48f2b)
虚机启动后通过dhcp获取IP地址
通过wireshark在vmnet6抓包,可以观察dhcp数据流:
4.4 port
port是network的一部分。在openstack抽象网络,network代表了一个广播域,可以理解为一个大的虚拟交换机。port就是虚拟交换机的端口。
port可以关联一个或多个安全组,用于控制网络访问。
在本文中,qdhcp、虚机都连接到相应的port上。
root@osclient ~(admin/amdin)# openstack port list
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------+--------+
| ID | Name | MAC Address | Fixed IP Addresses | Status |
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------+--------+
| 2d863922-bc61-4041-a13e-258f629719b2 | | fa:16:3e:60:78:cd | ip_address='203.0.113.125', subnet_id='8279842e-d7c5-4ba6-a037-831e0a72a938' | ACTIVE |
| a51b2fe4-049f-4462-ba5d-9660c4faaca1 | | fa:16:3e:5b:d6:a5 | ip_address='203.0.113.101', subnet_id='8279842e-d7c5-4ba6-a037-831e0a72a938' | ACTIVE |
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------+--------+
root@osclient ~(admin/amdin)# openstack port show a51b2fe4-049f-4462-ba5d-9660c4faaca1
+-------------------------+-------------------------------------------------------------------------------+
| Field | Value |
+-------------------------+-------------------------------------------------------------------------------+
| admin_state_up | UP |
| allowed_address_pairs | |
| binding_host_id | controller |
| binding_profile | |
| binding_vif_details | bound_drivers.0='linuxbridge', connectivity='l2', port_filter='True' |
| binding_vif_type | bridge |
| binding_vnic_type | normal |
| created_at | 2024-09-26T00:19:22Z |
| data_plane_status | None |
| description | |
| device_id | dhcpd3377d3c-a0d1-5d71-9947-f17125c357bb-48f2b88e-7740-4d94-a631-69e2abadf25b |
| device_owner | network:dhcp |
| device_profile | None |
| dns_assignment | None |
| dns_domain | None |
| dns_name | None |
| extra_dhcp_opts | |
| fixed_ips | ip_address='203.0.113.101', subnet_id='8279842e-d7c5-4ba6-a037-831e0a72a938' |
| id | a51b2fe4-049f-4462-ba5d-9660c4faaca1 |
| ip_allocation | None |
| mac_address | fa:16:3e:5b:d6:a5 |
| name | |
| network_id | 48f2b88e-7740-4d94-a631-69e2abadf25b |
| numa_affinity_policy | None |
| port_security_enabled | False |
| project_id | ee65b6c3961747b988ab8bd1cc19fb93 |
| propagate_uplink_status | None |
| qos_network_policy_id | None |
| qos_policy_id | None |
| resource_request | None |
| revision_number | 26 |
| security_group_ids | |
| status | ACTIVE |
| tags | |
| trunk_details | None |
| updated_at | 2024-10-06T22:14:04Z |
+-------------------------+-------------------------------------------------------------------------------+
root@osclient ~(admin/amdin)# openstack port show 2d863922-bc61-4041-a13e-258f629719b2
+-------------------------+------------------------------------------------------------------------------+
| Field | Value |
+-------------------------+------------------------------------------------------------------------------+
| admin_state_up | UP |
| allowed_address_pairs | |
| binding_host_id | compute1 |
| binding_profile | |
| binding_vif_details | bound_drivers.0='linuxbridge', connectivity='l2', port_filter='True' |
| binding_vif_type | bridge |
| binding_vnic_type | normal |
| created_at | 2024-09-28T02:49:21Z |
| data_plane_status | None |
| description | |
| device_id | d2e4bc39-63c8-4c80-b33f-52f4e1891f50 |
| device_owner | compute:nova |
| device_profile | None |
| dns_assignment | None |
| dns_domain | None |
| dns_name | None |
| extra_dhcp_opts | |
| fixed_ips | ip_address='203.0.113.125', subnet_id='8279842e-d7c5-4ba6-a037-831e0a72a938' |
| id | 2d863922-bc61-4041-a13e-258f629719b2 |
| ip_allocation | None |
| mac_address | fa:16:3e:60:78:cd |
| name | |
| network_id | 48f2b88e-7740-4d94-a631-69e2abadf25b |
| numa_affinity_policy | None |
| port_security_enabled | True |
| project_id | f5e75a3f7cc347ad89d20dcfe70dae01 |
| propagate_uplink_status | None |
| qos_network_policy_id | None |
| qos_policy_id | None |
| resource_request | None |
| revision_number | 24 |
| security_group_ids | 15dfe688-d6fc-4231-a670-7b832e08fb9d |
| status | ACTIVE |
| tags | |
| trunk_details | None |
| updated_at | 2024-10-07T03:45:50Z |
+-------------------------+------------------------------------------------------------------------------+
root@osclient ~(admin/amdin)#
4.5 相关操作归纳
|---|------------------|------------------------|------------------------------------------------------|--------------------------------------------------------------------------------|
| | Openstack操作 | 抽象网络 | 实体网络相关操作 ||
| | | | controler节点 | compute1节点 |
| 1 | 创建network | network "provider" | 无操作 | 无操作 |
| 2 | 创建subnet | sbunet "provider" | a.创建bridge b.创建qdhcp netns c. qdhcp、网卡ens34连接到bridge | 无操作 |
| 3 | 创建虚机 | "provider-instance" | 无操作 | a.创建bridge b.创建并启动虚机,连接到bridge c.网卡ens35连接到bridge 注:如果没有虚机连接到该bridge,bridge将删除 |
| 4 | port*(这里是自动创建的)* | 连接qdhcp的port 连接虚机的port | 无操作 | 无操作 |