一.Linux Bridge :Linux中的网桥
假设宿主机有 1 块与外网连接的物理网卡 eth0,上面跑了 1 个虚机 VM1,现在有个问题是: 如何让 VM1 能够访问外网?
至少有两种方案
- 将物理网卡eth0直接分配给VM1,但随之带来的问题很多: 宿主机就没有网卡,无法访问了; 新的虚机,比如 VM2 也没有网卡。 下面看推荐的方案
- 给 VM1 分配一个虚拟网卡 vnet0,通过 Linux Bridge br0 将 eth0 和 vnet0 连接起来,如下图所示
Linux Bridge 是 Linux 上用来做 TCP/IP 二层协议交换的设备,其功能大家可以简单的理解为是一个二层交换机。多个网络设备可以连接到同一个 Linux Bridge,当某个设备收到数据包时,Linux Bridge 会将数据转发给其他设备。
在上面这个例子中,当有数据到达 eth0 时,br0 会将数据转发给 vnet0,这样 VM1 就能接收到来自外网的数据;
反过来,VM1 发送数据给 vnet0,br0 也会将数据转发到 eth0,从而实现了 VM1 与外网的通信。
现在我们增加一个虚机 VM2,如下图所示
VM2 的虚拟网卡 vnet1 也连接到了 br0 上。
现在 VM1 和 VM2 之间可以通信,同时 VM1 和 VM2 也都可以与外网通信。
网桥实际上相当于一个物理路由器(交换机)。
brctl show 查看网桥信息,br100就是我们在这里搭建的网桥,后面挂接的虚拟机网卡和物理机网卡
virbr0 是 KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能。virbr0 默认分配了一个IP 192.168.122.1,并为连接其上的其他虚拟网卡提供 DHCP 服务。(NAT)
需要说明的是,使用 NAT 的虚机 VM1 可以访问外网,但外网无法直接访问 VM1。 因为 VM1 发出的网络包源地址并不是 192.168.122.6,而是被 NAT 替换为宿主机的 IP 地址了。
每张网卡都有唯一的MAC地址。
二.VLAN
首先搞清楚这几个概念:
LAN:Local Area Network 局域网
我们一般在公司组网,都是组建的LAN网络,用户在局域网里通信、传输文件。
其获取到的是内部IP,LAN 信息交换使用的是交换机。我们可以不连接 WAN 口,把路由器当做普通交换机来使用。
一个 LAN 表示一个广播域:LAN 中的所有成员都会收到任意一个成员发出的广播包。
WAN:Wide Area Network 广域网
WLAN:Wireless LAN 无线局域网。WLAN 利用电磁波在空气中发送和接受数据,而无需线缆介质。
WAN口是对外的接口,和运营商、上级网络打交道。
LAN和WLAN是对内的接口,内部的电脑、手机、PAD,都是接入到LAN或者WLAN。
一般的无线路由器,包含了完整的LAN、WAN、WLAN功能对LAN、WAN、WLAN,要放在一起理解,理解其在网络通信中扮演的角色。
那什么是VLAN呢?
VLAN 表示 Virtual LAN。一个带有 VLAN 功能的物理交换机能够将自己的端口划分出多个 LAN。计算机发出的广播包可以被同一个 LAN 中其他计算机收到,但位于其他 LAN 的计算机则无法收到。简单地说,VLAN 将一个交换机分成了多个交换机,限制了广播的范围,在二层将计算机隔离到不同的 VLAN 中。现在的交换机几乎都是支持 VLAN 的。通常交换机的端口有两种配置模式: Access 和 Trunk。
看下图,实际上是两台交换机,上面是一台,下面是一台。
Access 口:这些端口被打上了 VLAN 的标签,表明该端口属于哪个 VLAN。 Access 口都是直接与计算机网卡相连的,这样从该网卡出来的数据包流入 Access 口后就被打上了所在 VLAN 的标签。
Trunk 口:有两个交换机 A 和 B。 如何让 AB 上相同 VLAN 之间能够通信呢?办法是将 A 和 B 连起来。这样的端口就是Trunk口了。 VLAN1、2、3 的数据包在通过 Trunk 口到达对方交换机的过程中始终带着自己的 VLAN 标签。
物理交换机有VLAN的功能,那么Linux Bridge中又是如何实现VLAN的呢?
该图实际上就是在物理服务器中实现了一个虚拟交换机,该交换机具有VLAN的功能 。凡是连接在brvlan10(网桥)上的虚拟机,共同组建成一个局域网,id为10;凡是连接在brvlan20上的虚拟机,共同组建成一个局域网,id为20。eth0相当于是Trunk口,与外界交换信息。这样,
VM1发出的数据包,会打上tag为10的标签,并且只会在id为10的局域网中产生广播风暴,而不会转发到id为20的局域网中,它们之间是相互隔离开来的。如果现在有多台物理服务器,那么它们之间就通过trunk口相连接,里面的虚拟机,就可以在id相同的局域网中通信了。
Linux Bridge + VLAN = 虚拟交换机
三.Neutron
“软件定义网络(software-defined networking, SDN)”具有的灵活性和自动化优势使其成为云时代网络管理的主流。Neutron 的设计目标是实现“网络即服务(Networking as a Service)”。Neutron 为 OpenStack 的整个环境提供网络支持,包括二层交换,三层路由,负载均衡,防火墙和 VPN 等,Neutron 提供了一个灵活的框架。Neutron有如下几个重要功能:
1.二层交换(Switching):Nova 的 Instance 是通过虚拟交换机构建局域网的。Neutron 支持多种虚拟交换机,包括 Linux 原生的 Linux Bridge 和 OpenvSwitch。 OpenvSwitch(OVS)是一个开源的虚拟交换机,利用 Linux Bridge 和 OVS,Neutron 除了可以创建传统的 VLAN 网络,还可以创建基于隧道技术的 Overlay 网络,比如 VxLAN 和 GRE。
2.三层路由(routing):Instance 可以配置不同网段的 IP,即不同网段的虚拟机实现互相通信。Neutron 的 router(虚拟路由器)实现 instance 跨网段通信。router 通过 IP forwarding,iptables 等技术来实现路由和 NAT。
3.负载均衡:Load-Balancing-as-a-Service(LBaaS),提供了将负载分发到多个 instance 的能力。LBaaS 支持多种负载均衡产品和方案,不同的实现以 Plugin 的形式集成到 Neutron,目前默认的 Plugin 是 HAProxy。
4.要保证物理服务器的安全性,可以配一台防火墙。那么如何保证虚拟机的安全呢?
Neutron 通过下面两种方式来保障 instance 和网络的安全性。
Security Group 安全组:通过 iptables 限制进出 instance 的网络包。
Firewall-as-a-Service:FWaaS,限制进出虚拟路由器的网络包,也是通过 iptables 实现。
Neutron 管理的网络资源包括 Network,subnet 和 port
一个网络可以包含多个子网,一个子网会存在多个端口。port 可以看做虚拟交换机上的一个端口。port 上定义了 MAC 地址和 IP 地址,当 instance 的虚拟网卡 VIF(Virtual Interface) 绑定到 port 时,port 会将 MAC 和 IP 分配给该虚拟网卡。
network 是一个隔离的二层广播域。Neutron 支持多种类型的 network,包括 local, flat, VLAN, VxLAN 和 GRE。
flat:flat 网络是无 vlan tagging 的网络。flat 网络中的 instance 能与位于同一网络的 instance 通信,并且可以跨多个节点。
vlan:vlan 网络是具有 802.1q tagging 的网络。vlan 是一个二层的广播域,同一 vlan 中的 instance 可以通信,不同 vlan 只能通过 router 通信。
subnet 是一个 IPv4 或者 IPv6 地址段。instance 的 IP 从 subnet 中分配。每个 subnet 需要定义 IP 地址的范围和掩码
Neutron的架构:
与 OpenStack 的其他服务的设计思路一样,Neutron 也是采用分布式架构,由多个组件(子服务)共同对外提供网络服务。
Neutron 由如下组件构成:
Neutron Server:对外提供 OpenStack 网络 API,接收请求,并调用 Plugin 处理请求。
Plugin:处理 Neutron Server 发来的请求, 并调用 Agent 去处理请求。plugin 解决的是 What 的问题,即网络要配置成什么样子?而至于如何配置 How 的工作则交由 agent 完成。
Agent:真正的处理 Plugin 的请求,负责在 network provider 上真正实现各种网络功能。
network provider:提供网络服务的虚拟或物理网络设备,例如 Linux Bridge,Open vSwitch
Queue:Neutron Server,Plugin 和 Agent 之间通过 Messaging Queue 通信和调用(解耦)
Database:存放 OpenStack 的网络状态信息,包括 Network, Subnet, Port, Router 等。
以创建一个 VLAN100 的 network 为例,假设 network provider 是 linux bridge, 流程如下:
- Neutron Server 接收到创建 network 的请求,通过 Message Queue(RabbitMQ)通知已注册的 Linux Bridge Plugin。
- Plugin 将要创建的 network 的信息(例如名称、VLAN ID等)保存到数据库中,并通过 Message Queue 通知运行在各节点上的 Agent。
- Agent 收到消息后会在物理节点的网卡(比如 eth0)上创建 VLAN 设备(比如 eth2.100),并创建 bridge (比如 brqXXX) 桥接 VLAN 设备。
plugin,agent 和 network provider 是配套使用的,比如上例中 network provider 是 linux bridge,那么就得使用 linux bridge 的 plugin 和 agent;如果 network provider 换成了 OVS ,plugin 和 agent 也得替换。
plugin 的一个主要的职责是在数据库中维护 Neutron 网络的状态信息,这就造成一个问题:所有 network provider 的 plugin 都要编写一套非常类似的数据库访问代码。为了解决这个问题,Neutron 实现了一个 ML2(Modular Layer 2)plugin,对 plugin 的功能进行抽象和封装。有了 ML2 plugin,各种 network provider 无需开发自己的 plugin,只需要针对 ML2 开发相应的 driver 就可以了,工作量和难度都大大减少。
plugin 按照功能分为两类: core plugin 和 service plugin。core plugin 维护 Neutron 的 netowrk, subnet 和 port 相关资源的信息,与 core plugin 对应的 agent 包括 linux bridge, OVS 等; service plugin 提供 routing, firewall, load balance 等服务。
Management 网络:用于节点之间 message queue 内部通信以及访问 database 服务,所有的节点都需要连接到 management 网络。API 网络:OpenStack 各组件通过该网络向用户暴露 API 服务。Keystone, Nova, Neutron, Glance, Cinder, Horizon 的 endpoints 均配置在 API 网络上。
VM 网络:VM 网络也叫 tenant 网络(租户网络),用于 instance 之间通信。VM 网络可以选择的类型包括 local, flat, vlan, vxlan 和 gre。VM 网络由 Neutron 配置和管理。
External 网络:External 网络指的是 VM 网络之外的网络,该网络不由 Neutron 管理。 Neutron 可以将 router attach 到 External 网络,为 instance 提供访问外部网络的能力。