CentOS学习KVM笔记-网络篇
网络模型
- 四种网络模型
1、隔离模型:虚拟机之间组建网络,该模式无法与宿主机通信,无法与其他网络通信,相当于虚拟机只是连接到一台交换机上。
2、路由模型:相当于虚拟机连接到一台路由器上,由路由器(物理网卡),统一转发,但是不会改变源地址。
3、NAT模型:在路由模式中,会出现虚拟机可以访问其他主机,但是其他主机的报文无法到达虚拟机,而NAT模式则将源地址转换为路由器(物理网卡)地址,这样其他主机也知道报文来自那个主机,在docker环境中经常被使用。
4、桥接模型:在宿主机中创建一张虚拟网卡作为宿主机的网卡,而物理网卡则作为交换机。
隔离模型
如上图所示,Guest1和Guest2都是在宿主机上创建的虚拟机,虚拟机的网卡分为前半段和后半段,前半段位于虚拟机上,后半段在宿主机上,按照图中所示,前半段就是eth0,它是在虚拟机内部看到的网卡名字,而后半段就是vnet0和vnet1,它们是在宿主机上看到的网卡名字。实际上,在Guest1上所有发往eth0的数据就是直接发往vnet0,是由vnet0进行数据的传送处理。
在隔离模式下,宿主机创建一个虚拟交换机vSwitch,然后把vnet0和vnet1接入到该虚拟交换机,交换机也可以叫做bridge,因为vnet0和vnet1在一个网桥内,所以可以互相通信,而虚拟机的eth0是通过后半段进行数据传输,所以只要虚拟机的前半段ip在一个网段内,就可以互相通信,这就是隔离模式。
路由模型
在隔离模型的基础上,将宿主机的一块虚拟网卡virnet0加入到虚拟网桥中,这样virnet0就可以和虚拟机通信,通过将虚拟机的默认网关设置为virnet0的IP地址,然后在宿主机中打开IP地址转发,使得虚拟机可以访问宿主机。不过此时虚拟机仅仅可以将报文发送到外部网络,因为外部网络没有路由到虚拟机中,所以外部网络无法将报文回传给虚拟机。
NAT模型
NAT模型其实就是SNAT的实现,路由中虚拟机能将报文发送给外部主机,但是外部主机因找不到通往虚拟机的路由因而无法回应请求。但是外部主机能同宿主机通信,所以在宿主机上添加一个NAT转发,从而在外部主机请求虚拟机时,将虚拟机的IP地址转换为宿主机上的某个地址,从而实现外部网络与虚拟机的通信,其实际上只是通过iptables的nat表的POSTROUTING链实现地址转换罢了。
桥接模型
在宿主机中创建一个桥设备,把宿主机的eth0放在桥上,这样Guest1上的eth0将报文发给vnet0,再直接发给宿主机上的eth0,将源地址改为宿主机上的eth0的地址。
当响应报文到达物理机上的eth0时如何判断此响应报文是发给虚拟机的还是物理机自己的?
物理机会先创建一个虚拟网卡,在物理机上打开混杂模式(无论mac地址是不是自己的都将接收响应报文),如果mac地址是自己的则转发给虚拟网卡,如果不是自己的则转发给vnet0,这就是桥接模型,因为物理机的网卡具有桥的功能所以叫做桥接模型。
网络应用
桥接模式
在宿主机上创建一个虚拟网卡br0,并将物理网卡enp8s0
1 | [root@chobon ~]## cd /etc/sysconfig/network-scripts/ |
修改br0
1 | [root@chobon network-scripts]# vim ifcfg-br0 |
修改enp8s0
1 | [root@chobon network-scripts]# vim ifcfg-etp8s0 |
重启网络服务
1 | [root@chobon network-scripts]# service network restart |
如果接网线,插网孔的,这样一般的桥接网络就弄好了。但是如果是宿主机采用wireless上网的这个就行不通。
我一开始奔着桥接模型去整,发现一直网络不通,后来查阅KVM文档,才知道wireless网卡大部分不支持桥接。
NAT模式
NAT模式就比较简单了,因为libvirt安装好的时候就创建好了virbr0这个网卡,就是拿来用NAT用的。
- 查看虚拟网卡
1 | [root@chobon ~]# brctl show |
如果没有default的话,或者需要扩展自己的虚拟网络,可以使用命令重新安装NAT。
virsh net-define /usr/share/libvirt/networks/default.xml
此命令定义一个虚拟网络,default.xml的内容:
1 | <network> |
也可以修改xml,创建自己的虚拟网络。
如果安装的时候没有指定网络,可以在安装后编辑虚拟机xml配置
1 | [root@chobon ~]#vi /etc/libvirt/qemu/linux-xx.xml |
- 新安装的虚拟机在命令里设置网络参数
--network network=default
1 | virt-install \ |
查看虚拟机mac地址
1 | [root@chobon ~]# virsh dumpxml vm1_centos7 | grep 'mac address' |
拷贝mac给新虚拟机配置ip,修改网卡dhcp,在dhcp里增加一条ip绑定mac地址,方便以后管理虚拟机
virsh net-edit default
1 | <network> |
修改后重新加载和激活配置:
virsh net-destroy default
virsh net-start default
或者用
virsh net-update default
1 | virsh net-update default add ip-dhcp-host \ |
然后进入虚拟机里修改网卡eth0配置文件ifcfg-eth0
设置成开机启动ONBOOT=yes
重启虚拟机网络服务就搞定了,不过这样还只能是虚拟机可以访问外部网络。
- 通过端口转发,让外部网络可以访问虚拟机
宿主机Ip为192.168.124.21
,虚拟机的Ip为192.168.122.101
,通过宿主机10122
端口访问虚拟机22
端口
单个端口映射
在iptables
里添加下面命令,达到开机重启配置网络转发规则。
1 | [root@chobon ~]# iptables -A INPUT -p tcp --dport 10122 -j ACCEPT |
加了这三条发现虚拟机的端口还是没有映射出去,结果有了新的学习笔记Iptables学习笔记
端口没有映射成功的原因是KVM初始化的virbr0网卡在filter表里FORWARD
链里创建的一条规则导致,默认virbr0网卡生成的转发规则不带NEW
,而ssh
发起的第一个包就是NEW
,所以死活连不上。
1 | [root@chobon ~]# iptables -nvL FORWARD |
第二条规则RELATED,ESTABLISHED
少了一个NEW
参数,修改保存即可
1 | [root@chobon ~]# iptables -R FORWARD 2 -o virbr0 -d 192.168.122.0/24 -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT |
范围端口映射
映射宿主机10001-19999到hostid为101的虚拟机1-9999端口,记得也要加上filter表转发规则里的NEW,不然ssh是没办法连接的
1 | [root@chobon ~]# iptables -t nat -A PREROUTING -d 192.168.124.21 -p tcp -m tcp --dport 10001:19999 -j DNAT --to-destination 192.168.122.101:10001-19999 |
遇到的问题
网卡br0启动失败
最开始的时候想在wireless上桥接网卡,br0死活启动不来,查看日志发现是NetworkManager管理网络导致br0起不来
NetworkManager和配置的桥接网卡冲突导致问题hdclient错误
dhclient(3108) is already running – exiting
hdclient -r && hdclient
或者kill掉hdclient进程重新启动
常用指令
- 显示节点上的虚拟网络
1 | virsh net-list --all |
- 显示一个虚拟网络的相关信息
1 | virsh net-info net-name |
- 显示一个虚拟网络的XML描述
1 | virsh net-dumpxml net-name |
- 从一个XML描述文件定义一个虚拟网络
1 | virsh net-define network.xml |
- 启动一个已经定义的虚拟网络:
1 | virsh net-start net-name |
- 将一个虚拟网络设置为自动启动:
1 | virsh net-autostart net-name |
- 停用一个虚拟网络
1 | virsh net-destroy net-name |
- 撤销一个虚拟网络
1 | virsh net-undefine net-name |