Cloud Computing and OpenStack
在众多虚拟机上添加一个管理层,在上层形成一个统一的界面,也就形成了最初的云计算,云就是对底层虚拟机进行资源统一管理、分配形成的一个系统,实现资源的弹性分配。
对于多虚拟机来说,除了CPU的虚拟化与管理、内存的虚拟化与管理、存储的虚拟化与管理外,IO的虚拟化,特别是IO中的网络虚拟化的管理与配置是非常重要和复杂的一项工作。多台虚拟机组成一个系统,涉及虚拟机之间的通信、虚拟机与宿主机的通信、虚拟机与外部网络的通信等,其网络虚拟化及其管理,类似现实物理网络的软件化。这里要单独对网络虚拟化进行学习。
网络虚拟化:前面xen与kvm中都有涉及
桥接模型、隔离模型、路由模型、NAT模型
在同一台物理主机上实现多个虚拟机,其网络模型实现解决还算简单,但是如果虚拟机跨越了物理主机,这时网络配置就会很复杂。
众多虚拟机之间的网络连接,就与现实中的众多主机互联是一样的。现实中的主机组网,是借助于各种网络设备,主要是交换机、路由器、网桥等设备,交换机又可以有普通二层交换机,支持VLAN技术的二层交换机,三层交换机等。在网络虚拟化技术中,也要将这些设备虚拟化,并借助这些虚拟化的网络设备完成组网。
在前面已经接触的有网桥,使用brctl addbr命令增加桥设备,还有veth设备,是成对出现的虚拟以太网卡设备,还有tun/tap设备。brctl添加的桥设备,不支持VLAN技术,另一个开源的著名的网络虚拟化技术:OVS ------ OpenVSwitch,虚拟交换机,支持VLAN、QoS等众多功能。
另一种重要网络设备,路由器,路由器的功能之一主要是实现网络隔离功能,对不同的局域网实行隔离。
一般的虚拟机群的网络划分三部分:

对于局域网的隔离,可以使用路由器,也可以使用VLAN技术。
linux内核启动模块8021q,即可支持VLAN。

配置VLAN,一般使用vconfig。

局域网或VLAN,实现的是广播报文的隔离。局域网(或VLAN)之间通信,需要通过路由器。

云计算的几个层次:
IaaS:Infrastructure as a Service
PaaS:Platform as a Service
SaaS:Software as a Service
通过上面的图示,虚拟化技术中,最重要的一点是实现资源之间的隔离与通信。同一台物理机上的多台虚拟机,如何实现资源的隔离?不同的虚拟机是属于不同的公司的资产,其上保存和运行着不同公司的信息,这些信息不能被其他人访问,虚拟机要像一台物理机保存在本公司一样,保证其上信息与程序的安全,保证其上信息与资源的隔离。
Linux内核借助namespace和cgroups实现资源的隔离与资源的分配:
namespace ,名称空间:资源的空间隔离;
文件系统隔离;
网络隔离,主要用于实现网络资源的隔离,包括网络设备、IP地址、IP路由表、防火墙、/proc/net、/sys/class/net以及套接字等;
IPC隔离,跨名称空间的进程间不能通信;
用户和用户组隔离;
PID隔离,对名称空间内的PID重新标号,两个不同的名称空间可以使用相同的PID;
UTS隔离,Unix Time-sharing System,提供主机名称和域名的隔离;
cgroups,control groups:完成资源的分配,实现对系统资源进行精细化管控,用于实现限制被各namespace隔离起来的资源,还可以为资源设置权重 、计算使用量、完成各种所需的管理任务等;
网络名称空间:Linux Network NameSpace

如上图,一台物理主机中启动了四台虚拟机,两个网桥,形成两个局域网,现在,局域网是相互隔离的,现在想给两个局域网中的虚拟机使用dhcp分配地址,那么启动的dhcp如何确定给哪个局域网使用?如果又配置了路由功能和路由表,如何区分是给哪个局域网的路由?
创建网络名称空间,将dhcp和route绑定到不同的空间,即可实现网络的隔离。
使用ip命令的netns管理网络名称空间。
注意:netns在内核实现,其控制功能由iproute所提供的netns这个OBJECT来提供;CentOS6.6提供的iproute不具有此OBJECT,需要依赖于OpenStack Icehouse的EPEL源来提供;

ip netns list 显示已有的名称空间
ip netns add 添加一个网络名称空间
ip netsns delete 删除一个网络名称空间
ip netns exec name cmd 在指定的名称空间运行命令,相当于将资源绑定到名称空间


如上,就创建了r1和r2两个名称空间,然后,创建一个veth虚拟网络设备,即创建一对相互连接的虚拟网卡:

将这一对设备分别绑定到不同的网络名称空间:
ip link set veth1.0 netns r1
ip link set veth1.1 netns r2
ip link show

绑定以后,在宿主机中就看不到这两个网络接口了。然后,分别在r1和r2名称空间中查看:
ip netns exec r1 ifconfig -a
ip netns exec r2 ifconfig -a

在两个名称空间中看到了相应的网络接口,配置这个两个接口:
ip netns exec r1 ip link set veth1.0 name eth0 #修改r1中网络接口的名称,与正常主机网卡命名一致:

配置IP地址:

测试联通性:

此时,两个名称空间的网络可以互相访问。
总结一下:
- 创建名称空间,就相当于创建了一个虚拟机,其与宿主机以及其他虚拟机是相互隔离的;
- 宿主机其实也相当于一个名称空间;
- 宿主机中创建veth设备,两个虚拟接口属于宿主机,当使用ip命令将其绑定到不同的名称空间时,在宿主机中就看不到了,只能在其所属的名称空间才能看到;
- 因为veth设备相当于被网线相互连接起来的两个网卡设备,当其绑定到不同的名称空间时。就相当于两个名称空间通过此网卡进行了互联,类似两台主机,各自加了一块网卡,而网卡又通过网络联通了,两台主机即可通信,两个名称空间即可通信。

类比:

三台主机是相互独立,相互隔离的。
之所以将命名空间起名为r1,这个r是router的意思,即路由器,因为大部分名称空间的作用,都是类似一台实现路由器功能的虚拟主机,在其上实现网络的隔离(二层隔离),网络的联通(通过路由),提供独立且隔离的dhcp服务,NAT服务等等。
从本质上看,其实网桥设备也算是一个名称空间,不同的网桥之间是相互隔离的,其上连接的虚拟机,即使是同一个网段的IP地址,也无法互相访问,只有用网络连接起来,即创建veth设备,将两个接口分别添加到不同的网桥中,才能实现互通。
一个组网测试:拓扑图
宿主机中启动两台虚拟机VM1和VM2,其网卡前端名称为eth0,后端名称分别为vif1.0和vif2.0,分别加入网桥br-in中,名称意思:br代表网桥设备,in代表内部用网桥;创建veth设备,一端名vinb,加入到br-in网桥中,另一端vinr/eth0加入到名称空间r1中,名称意思:v代表veth设备,in代表内部连接用,b代表网桥,即加入网桥的一端,r代表router,eth0表示在r1中被重命名为eth0,代表加入名称空间r1的一端。创建第二个veth设备,一端名vexb,加入到br-ex网桥中,另一端vexr加入到名称空间r1中,ex代表访问外部网络的网桥,eth1代表vexr在名称空间中被重命名为eth1。
1)当前的网络环境:


2)创建网桥设备br-in和br-ex
brctl addbr br-in
brctl addbr br-ex

ip link set br-in up
ip link set br-ex up
3)创建脚本文件/etc/qemu-ifup,在创建虚拟机时自动将接口加入对应的网桥:
bash
#!/bin/bash
#
bridge=br-in
if [ -n "$1" ]; then
ip link set $1 up
# ip link set $1 master $bridge
brctl addif $bridge $1
[ $? -eq 0 ] && exit || exit 1
else
echo "Error: no interface specified."
exit 1
fi
4)创建两台虚拟机VM1和VM2
qemu-kvm -name VM1 -m 128 -smp 1 -drive file=/images/kvm/cirros-0.3.6-x86_64-disk-vm1.img,if=virtio,media=disk -bios /usr/share/qemu-kvm/bios.bin -net nic,macaddr=54:52:00:aa:bb:cc -net tap,ifname=vif1.0 -vnc 192.168.147.140:0
qemu-kvm -name VM2 -m 128 -smp 1 -drive file=/images/kvm/cirros-0.3.6-x86_64-disk-vm2.img,if=virtio,media=disk -bios /usr/share/qemu-kvm/bios.bin -net nic,macaddr=54:52:00:aa:bb:dd -net tap,ifname=vif2.0 -vnc 192.168.147.140:1
此时,后半段网卡加入网桥br-in:

启动的两台虚拟机:

5)添加网络名称空间(路由器)r1,再创建veth设备,接口分别为vinb和vinr
ip netns add r1


ip link add vinb type veth peer name vinr

6)将vinb加入br-in网桥,将vinr加入名称空间r1,并重命名为eth0
brctl addif br-in vinb
ip link set vinr netns r1
ip netns exec ip link set vinr name eth0

设置eth0地址为172.16.0.254/24
ip netns exec r1 ifconfig eth0 172.16.0.254/24 up

7)配置两台虚拟机的IP,VM1为172.16.0.1/24,VM2为172.16.0.2/24

测试连通性:

与宿主机之间是不通的:宿主机192.168.147.140

添加路由:route add default gw 172.16.0.254

8)再增加一个veth设备,vexb和vexr/eth1
ip link add vexb type veth peer name vexr
ip link set vexb up
brctl addif br-ex vexb
ip link set vexr netns r1
ip netns exec r1 ip link set vexr name eth1



设置eth1地址为192.168.147.66/24,与宿主机在同一网段

此时,虚拟机是可以ping通192.168.147.66的:

9)将物理网卡桥接到外部网桥br-ex上,同时拆除物理网卡上的地址,将其配置到此网桥上:
ip addr del 192.168.147.140/24 dev ens33;ip addr add 192.168.147.140/24 dev br-ex;brctl addif br-ex ens33;

此时,r1中可以ping通192.168.147.140

但是虚拟机无法ping通

在vexb接口上抓包:

数据包已经到达了147.140,但是宿主机响应包无法返回,因为宿主机上没有相应的路由

10)最好的解决方法是在eth1上做SNAT:
先看一看名称空间r1中的NAT情况:是空表

添加SNAT:
ip netns exec r1 iptables -t nat -A POSTROUTING -s 172.16.0.0/24 ! -d 172.16.0.0/24 -j SNAT --to-source 192.168.147.66

此时,在VM1上ping宿主机147.140,已经互通了。

在不同的接口上抓包:能看到不同的源地址




ping其他主机也是通的:

11)在名称空间r1中运行dhcp,为虚拟机分配IP:
使用dnsmasq软件:
ip netns exec r1 dnsmasq --interface=eth0 --bind-interfaces --dhcp-range=172.16.0.50,172.16.0.58,12h --dhcp-option=3,172.16.0.254

在cirros中,使用cirros-dhcpc取代udhcpc



dhcp服务就为r1名称空间的eth0接口所在网络分配IP。
关于dnsmasq的简单用法:
dnsmasq \
--interface=eth0 \
--bind-interfaces \
--dhcp-range=192.168.1.50,192.168.1.150,12h \
--dhcp-option=3,192.168.1.1 \
--dhcp-option=6,192.168.1.1 \
--log-queries
参数详细解析
--interface=eth0 :指定 dnsmasq 仅在 eth0 网络接口上监听 DNS 和 DHCP 请求。
--bind-interfaces :重要安全选项。强制 dnsmasq 绑定到指定接口的具体 IP,而不是监听所有接口(0.0.0.0)。这能防止服务意外暴露在公网或其他不安全的网络平面上。
--dhcp-range=192.168.1.50,192.168.1.150,12h :启用 DHCP 服务。
地址池范围:192.168.1.50 到 192.168.1.150。
租期时间:12h(12小时)。 注意:请根据你实际的网络规划修改 IP 段。
--dhcp-option=3,192.168.1.1 :配置默认路由(网关)。
DHCP 选项 3 代表路由器/网关地址。
192.168.1.1 应替换为你局域网中实际的路由器或网关 IP 地址(通常是运行 dnsmasq 的那台机器在该网段的 IP,或者上游路由器的 IP)。
--dhcp-option=6,192.168.1.1 :配置 DNS 服务器地址。
DHCP 选项 6 代表 DNS 服务器。这里设置为 dnsmasq 本机 IP,以便客户端通过 dnsmasq 进行域名解析和缓存。
--log-queries (可选) :开启查询日志,方便调试,查看是否有客户端成功获取 IP 和发起 DNS 请求。日志通常输出到 /var/log/syslog 或 /var/log/messages。