CentOS8_debian11_远程ssh连接在线安装KVM_虚拟化嵌套_安装客户机openwrt_NAT端口映射
转载注明来源: 本文链接 来自osnosn的博客,写于 2022-06-27.
参考
- 【Linux中KVM的部署安装,管理及VNC的使用】
- 【在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机】
- 【在CentOS 8上安装 KVM / QEMU 进行虚拟化】
- 【Centos8搭建KVM】
- 【如何在CentOS 8服务器上安装KVM】
- 【如何在CentOS 8上安装KVM以及如何在物理服务器上安装和管理虚拟机】
- 【CentOS 8.1 安装部署KVM虚拟机】
【CentOS 8.1 KVM网桥的配置】
【CentOS 8.1下VNC安装与配置】 - 【Linux 桌面玩家指南:07. Linux 中的 Qemu、KVM、VirtualBox、Xen 虚拟机体验】
Centos8 最简安装 KVM
- 使用 Centos8,(2022-8月测试)。
- 环境是: 不使用本地 console。使用 ssh 远程连接服务器,在线安装 kvm。
先 ssh 登录服务器,然后运行 tmux 防止意外掉线。 lscpu | egrep 'vmx|svm'
检查cpu支持虚拟化。
vmx 是 Intel的,svm 是 AMD的。lsmod | grep kvm
内核是否加载 kvm 模块。
如无,则modprobe kvm
加载。yum install virt-install
vm客户机的命令行安装工具。
download size: 12MB, 装完占55MB (32 packages)virt-host-validate
环境检查。输出一堆 PASS。- 这个时候,
ip addr
显示2个设备: lo, ens33。没有 bridge。 yum module install virt
安装 KVM 服务端环境。
download size: 91MB, 装完占330MB (154 packages)- 如要,更简的安装,就只装
yum install libvirt
,就有 libvirt-daemon 包了。
download size: 26MB (70 packages) 我没有使用这种极简的方式安装。
- 如要,更简的安装,就只装
systemctl start libvirtd
启动daemon。systemctl enable libvirtd
激活开机启动。- 这个时候,
ip addr
显示4个: lo, ens33, virbr0, virbr0-nic 。
virbr0 就是NAT网络。vm客户机可以访问外网,有dnsmasq。 virsh net-list
只看到一个名称 default。virsh net-info default
显示这个 default 使用的是 virbr0。- 如果要修改 default网络(virbr0) 的 IP 和 网段。
virsh net-edit default
, 其实就是修改/etc/libvirt/qemu/networks/default.xml
。- 重启这个default网络。
virsh net-destroy default; virsh net-start default
生效。
- 创建网络,见下文。
nmcli device
见到 virbr0是bridge, vribr0-nic 是tun设备。DEVICE TYPE STATE CONNECTION ens33 ethernet connected ens33 virbr0 bridge connected (externally) virbr0 lo loopback unmanaged -- virbr0-nic tun unmanaged --
nmtui
中看到一个物理网卡,一个 bridge。不要在 nmtui 中修改 virbr0 的配置。- 到此,kvm安装完成。创建vm客户机,不能使用"桥接模式"。
因为没有为本机的物理网口创建网桥。后面用到"桥接"再说。
网桥设置参考: 【CentOS 8.1 KVM网桥的配置】 - 其他的包:
yum install virt-manager
管理vm客户机的 GUI工具。yum install virt-viewer
用于连接vm客户机的桌面, GUI 工具
(download size: 44MB, 113 packages)dnf install cockpit cockpit-machines
Cockpit Web控制台
Debian11 最简安装 KVM
- 使用 debian11(bullseye),(2022-8月测试)。
- 环境是: 不使用本地 console。使用 ssh 远程连接服务器,在线安装 kvm。
先 ssh 登录服务器,然后运行 tmux 防止意外掉线。 lscpu | egrep 'vmx|svm'
检查cpu支持虚拟化。
vmx 是 Intel的,svm 是 AMD的。lsmod | grep kvm
内核是否加载 kvm 模块。
如无,则modprobe kvm
加载。apt update
apt install libvirt-daemon-system
安装libvirtd服务。
会自动装上 libvirt-daemon, libvirt-client, qemu-kvm, qemu-utils,
download 207MB, 694MB disk space will be used. 304 packages.- qemu-system 是其他架构cpu(arm,ppc,...)的支持。我没装。
apt install virtinst
安装virt-install工具。
download 4MB, 20MB disk space will be used. 26 packages.- 这时候,
ip addr
没有新增 bridge。
libvirtd 服务已经启动。
virsh net-list
是空的。
virsh net-list --all
显示default 是inactive。 virsh net-start default
启动default网络。
virsh net-autostart default
自动启动default网络。- 这时候,
ip addr
多出一个 virbr0 的 bridge。 virsh net-info default
显示这个 default 网络的信息。virsh net-edit default
, 修改 default网络(virbr0) 的 IP 和 网段。
virsh net-destroy default; virsh net-start default
重启这个default网络,生效。- 创建网络,见下文。
- 到此,kvm安装完成。创建vm客户机,不能使用"桥接模式"。
因为没有为本机的物理网口创建网桥。后面用到"桥接"再说。
网桥设置参考: 【如何在 Debian 11 Bullseye Linux 上安装和配置 KVM】
创建网络
- virsh net-create name.xml 创建一个临时网络并启用,重启系统后丢失。
- 能 start,destroy。但不能设置 autostart。
- virsh define name.xml 创建一个永久网络。
- 能 start,destroy。也能设置 autostart。
- nat网络,带dhcp的例子
<!-- 文件名: my-wan.xml --> <network> <name>my-wan</name> <forward mode='nat'/> <bridge name='virbr1' stp='on' delay='0'/> <ip address='192.168.22.22' netmask='255.255.255.0'> <dhcp> <range start='192.168.22.100' end='192.168.22.200'/> </dhcp> </ip> </network>
- 隔离网络,无dhcp的例子
<!-- 文件名: my-lan.xml --> <network> <name>my-lan</name> <bridge name='virbr1' stp='on' delay='0'/> <ip address='192.168.22.22' netmask='255.255.255.0'> </ip> </network>
KVM 虚拟化嵌套
- vm客户机的cpu是否支持vmx。
- Centos8默认未打开。
cat /sys/module/kvm_intel/parameters/nested
0:关闭,1:打开。- 修改
/etc/modprobe.d/kvm.conf
中options kvm_intel nested=1
rmmod kvm-intel
或者modprobe -r kvm-intel
卸载。
modprobe kvm-intel nested=1
重新加载。
或者,重启整个系统。
- Debian11默认是打开的。
安装 VM 客户机
qcow2 的镜像 测试
- 镜像来源
https://openwrt.cc/snapshots/targets/x86/64/immortalwrt-x86-64-generic-ext4-combined-efi.qcow2.gz
- 用 gunzip 解压。
mv immortalwrt-.....efi.qcow2 /var/lib/libvirt/images/
qemu-img info immortalwrt-.....efi.qcow2
看到这个镜像的虚拟大小是814MB.
Centos8 , Debian11
- 创建 VM 客户机
virt-install \ --virt-type kvm \ --name opwrt2 \ --memory 512 \ --vcpus 1 \ --cpu host-passthrough \ --os-variant archlinux \ --network bridge=virbr0,model=virtio \ --graphics vnc \ --import \ --noautoconsole \ --autostart \ --disk path=/var/lib/libvirt/images/immortalwrt-x86-64-generic-ext4-combined-efi.qcow2,bus=virtio,format=qcow2
- virsh 部分命令列表:
virsh start opwrt2
启动
virsh list --all
列出所有vm客户机
virsh suspend opwrt2
暂停
virsh resume opwrt2
恢复
virsh dhutdown opwrt2
正常关机
virsh destroy opwrt2
强制关机
virsh undefine opwrt2
删除vm客户机
virsh autostart --disable opwrt2
禁止vm客户机.自动启动 - 修改 opwrt2 的 LAN口IP。
virsh console opwrt2
连接终端。按^]
退出终端。
改/etc/config/network
中,IP 为 192.168.122.10。
/etc/init.d/network reload
重启生效。
或用 uci命令修改IP,见【制作免配置固件】,【官方文档:The UCI system】。uci set network.lan.ipaddr='192.168.122.10' uci commit network /etc/init.d/network reload
- 用 putty 通过 ssh 登录宿主机。
在 putty 的主菜单
->Change Settings...
->Connection
->SSH
->Tunnels
中。
Source port
:9988
,Destination
:192.168.122.10:80
, 点击Add
, 点击Apply
。- 打开浏览器,访问 localhost:9988。配置 opwrt2。
设置 LAN 的 网关,dns。关掉 LAN 的 dhcp。 - 配置完成后。直接在 putty 中退出登录宿主机(要等2min才会完全退出),即可。
- 打开浏览器,访问 localhost:9988。配置 opwrt2。
img 的镜像 测试
- 镜像来源
https://downloads.openwrt.org/releases/21.02.3/targets/x86/64/openwrt-21.02.3-x86-64-generic-ext4-combined-efi.img.gz
- 用 gunzip 解压。
mv openwrt-21.02.3-.....efi.img /var/lib/libvirt/images/
qemu-img info openwrt-21.02.3-.....efi.img
看到这个镜像的虚拟大小是121MB.- 如需扩容,参考:【openwrt_21.02_img_空间扩容_改分区表大小】
Centos8 , Debian11
- 创建 VM 客户机
virt-install \ --virt-type kvm \ --name opwrt21 \ --memory 256 \ --vcpus 1 \ --cpu host-passthrough \ --os-variant archlinux \ --network bridge=virbr0,model=virtio \ --graphics vnc \ --import \ --noautoconsole \ --autostart \ --disk path=/var/lib/libvirt/images/openwrt-21.02.3-x86-64-generic-ext4-combined-efi.img,bus=virtio,format=raw
- 修改 LAN口IP。配置 openwrt。同 qcow2 的镜像测试。
虚拟机接受kvm关机指令
接受,虚拟机服务的virsh shutdown xxxx
指令。
否则实体机的主系统,关闭/重启,要等很久。通常是300秒每个虚机。
看/etc/init.d/libvirt-guests
或/usr/lib/systemd/system/libvirt-guests.service
服务脚本的超时设置。
创建的虚机需要一个信道设备org.qemu.guest_agent.0
,见【虚拟机op接受kvm关机指令】。
- 对于openwrt,安装
opkg install qemu-ga
, op21有4个依赖包,约占用3.4-4MB 空间。重启opwnrt 生效。
qemu-ga 的配置文件是/etc/qemu/qemu-ga.conf
,op中没这个文件,需要时,自己创建。 - 对于 debian,默认就安装了 qemu-guest-agent。
如果没有,自行安装apt install qemu-guest-agent
,重启生效。 - 其他系统,类似。
NAT 端口映射
- 参考: 【kvm虚拟机端口映射(端口转发)到宿主机】
- 以下是针对,带有nat的网络"virbr0",进行端口转发。
防火墙中,已经有"内->外"的 MASQUERADE 的伪装规则,"内->外"的forward转发规则。 - 检查"包转发"已经打开。
sysctl net.ipv4.ip_forward
应该显示=1。 - 允许"外->内"的转发。
iptables -I FORWARD -m state -o virbr0 -d 192.168.122.0/24 --state NEW -j ACCEPT
这个命令只需设置一次。注意 virbr0 和 ip 段,要改成你自己的。
这个规则也可以限制严格一点,比如,加上--dport
,限制tcp-p tcp
。 - 假设 宿主机/实体机 的网口为 eth0, 外部1234端口映射到内网192.168.122.10:5678端口。
用
iptables -t nat -I PREROUTING ! -s 192.168.122.0/24 -p tcp --dport 1234 -j DNAT --to-destination 192.168.122.10:5678
或者
iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 1234 -j DNAT --to-destination 192.168.122.10:5678
实现。
不同端口,使用不同的规则。
vm客户机的缺省网关需要指向"virbr0"的网关IP,比如"192.168.122.1"。
从外部连接这个端口,vm客户机中的应用,获取的是真实的"来源IP"。
debian-10 和 debian-11 中测试成功。 - Centos8 可以用上述的两条 iptables 规则。实测成功。
可以使用firewall-cmd --direct --add-rule ...
或firewall-cmd --direct --passthrough ...
把这两条iptables规则添加进去。 - Centos8 用
firewall-cmd
命令实现。测试失败。
或者用firewall-cmd --add-forward-port=port=1234:proto=tcp:toport=5678:toaddr=192.168.122.10 # 下面这行, "外->内"的forward规则。添加的规则内容正确,但位置不对。所以不能解决问题。 firewall-cmd --zone libvirt --add-forward #没有使用 firewall-cmd --permanent 和 firewall-cmd --reload 虽然不影响 virbr0 的nat网络规则。但影响手工添加的规则。
firewall-cmd --zone=my_zone --add-rich-rule="..."
(未测试)。 - nft 的办法类似,需要自己写规则。
参考:【configuring_nat_using_nftables】
对于centos-8,firewalld启用。成功。## 这是规则的原理。未实际测试! # 假设 宿主机/实体机 的网口为 eth0。宿主机网口的IP为 123.123.123.123,234.234.234.234。 table ip port_fwd { chain forward { type filter hook forward priority filter +10; policy accept; oifname "virbr0" ip daddr 192.168.122.0/24 ct state new counter accept #开放"外->内"的转发 #这条规则需要插入到原有的chain中。即"type filter hook forward"的chain中,如果有的话。 #因为accept虽然会终止当前chain的rule的匹配,但还会继续匹配其他的(相同的hook)chain中的rule。 #而drop就完全终止剩余rule的匹配,无论是当前chain的rule还是其他chain的rule。 } chain dstnat { type nat hook prerouting priority dstnat +10; policy accept; iifname "eth0" tcp dport 1234 counter dnat ip to 192.168.122.10:5678 #添加,端口转发,计数 #或 iifname "eth0" meta nfproto ipv4 tcp dport 1234 counter dnat ip to 192.168.122.10:5678 #添加,端口转发,计数 #或 ip saddr != 192.168.122.0/24 tcp dport 1234 counter dnat ip to 192.168.122.10:5678 #添加,端口转发,计数 #或 ip saddr != 192.168.122.0/24 ip daddr '{123.123.123.123,234.234.234.234}' tcp dport 1234 counter dnat ip to 192.168.122.10:5678 #添加,端口转发,计数(规则严格点) } }
vm客户机的缺省网关需要指向"virbr0"的网关IP,比如"192.168.122.1"。#centos-8,firewalld启用,实测成功! nft insert rule ip filter LIBVIRT_FWI index 0 oifname "virbr0" ip daddr 192.168.122.0/24 ct state new counter accept #允许"外->内"的转发,只需执行一次 nft add table ip port_fwd nft add chain ip port_fwd dstnat '{type nat hook prerouting priority dstnat +5; policy accept;}' nft add rule ip port_fwd dstnat meta l4proto tcp ip saddr != 192.168.122.0/24 tcp dport 1234 counter dnat ip to 192.168.122.10:5678 #端口映射,一个端口一条rule #或 nft add rule ip port_fwd dstnat meta l4proto tcp ip saddr != 192.168.122.0/24 ip daddr '{123.123.123.123, 234.234.234.234}' tcp dport 1234 counter dnat ip to 192.168.122.10:5678 #端口映射,一个端口一条rule (规则严格点) #或者 nft add rule ip firewalld nat_PRE_libvirt_allow meta l4proto tcp ip saddr != 192.168.122.0/24 tcp dport 1234 counter dnat ip to 192.168.122.10:5678 #加入到已有的chain中(ip firewalld nat_PRE_libvirt_allow)或(ip nat PREROUTING)
从外部连接这个端口,vm客户机中的应用,获取的是真实的"来源IP"。
- 以下是针对,带有nat的网络"virbr0",进行端口转发。
- 为了宿主机重启之后,保留端口映射。把上述两条规则,写入到
/etc/rc.local
中。- 如果有
/etc/rc.local
这个文件,就保留里面的内容。如果没有这个文件,则自己创建。
echo -e '#!/bin/sh\n\nexit 0' >> /etc/rc.local; chmod +x /etc/rc.local
- 然后把规则写在
/etc/rc.local
中,exit 0
这行的前面。
- 如果有
- 不带nat的网络,如果要映射。也可以。实测成功。
- 首先,允许双向转发。
- 然后用 SNAT + DNAT 的一对规则实现。
vm客户机的缺省网关指向哪里都 OK,不影响端口映射。# 假设"virbr1"是不带nat的隔离网络,"virbr1"的网关IP是"192.168.125.1"。在debian-10中测试成功。 #允许双向转发 iptables -I FORWARD -m state -o virbr1 -d 192.168.125.10/32 --state NEW,RELATED,ESTABLISHED -j ACCEPT iptables -I FORWARD -m state -i virbr1 -s 192.168.125.10/32 --state RELATED,ESTABLISHED -j ACCEPT #SNAT+DNAT 规则, 外部1234端口映射到192.168.125.10:5678端口 iptables -t nat -I PREROUTING ! -s 192.168.125.0/24 -p tcp --dport 1234 -j DNAT --to-destination 192.168.125.10:5678 iptables -t nat -I POSTROUTING ! -s 192.168.125.0/24 -d 192.168.125.10 -p tcp --dport 5678 -j SNAT --to-source 192.168.125.1
从外部连接这个端口1234,vm客户机中的应用,无法获取真实的"来源IP",得到的"来源IP"是网关IP"192.168.125.1"。 - 如果想让vm客户机中的应用,能够获取真实的"来源IP"。则,
记得检查vm客户机的缺省网关指向的是"virbr1"的网关IP,即"192.168.125.1"。iptables -I FORWARD -m state -o virbr1 -d 192.168.125.10/32 --state NEW,RELATED,ESTABLISHED -j ACCEPT iptables -I FORWARD -i virbr1 -s 192.168.125.10/32 -j ACCEPT iptables -t nat -I PREROUTING ! -s 192.168.125.0/24 -p tcp --dport 1234 -j DNAT --to-destination 192.168.125.10:5678 iptables -t nat -I POSTROUTING -s 192.168.125.10 ! -d 192.168.125.0/24 -p tcp --sport 5678 -j MASQUERADE #或 iptables -t nat -I POSTROUTING -s 192.168.125.10 ! -d 192.168.125.0/24 -p tcp --sport 5678 -j SNAT --to-source 123.123.123.123 #宿主机外网口IP
这样,vm客户机就能获取真实的"来源IP"。
端口映射-其他
- 无论是 DNAT 还是 SNAT, 内核都会同时创建返回包的匹配状态。
比如,当有数据包从 1.2.3.4:12345->192.168.122.10:5678,
内核会创建 192.168.122.10:5678->1.2.3.4:12345 作为 ESTABLISHED 的匹配。
只是 dnat 是数据包通过网关时改变了目标地址和端口。snat 是数据包通过网关时改变了源地址和端口。 - 如果 dnat 到本机的 127.0.0.1:5678,
需要对应网卡的sysctl -w net.ipv4.conf.eth0.route_localnet=1
设置,
或echo 1 > /proc/sys/net/ipv4/conf/eth0/route_localnet
。
或者设置net.ipv4.conf.all.route_localnet = 1
。 - 如果流量大,出现 ip_conntrack: table full, dropping packet 的问题。
加大表容量,find /proc/sys/net -name nf_conntrack_max
。应该找到两个,修改它们的值。
降低timeout,find /proc/sys/net -name 'nf_conntrack_tcp_timeout*'
。修改它们的值。
针对某个大流量的服务, NOTRACK(不跟踪), 比如80口, 参考【iptables raw表】,iptables -t raw -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j NOTRACK iptables -t raw -A OUTPUT -s 1.2.3.4 -p tcp --sport 80 -j NOTRACK iptables -A INPUT -m state --state UNTRACKED -j ACCEPT
- nat/iptables 的其他例子
【debian11_nftables/ip6tables_限制ipv6公网访问特定端口_centos8/debian仅允许部分IPv4访问端口】。
映像文件转换格式
- 用 qemu-img 。
- 有 for windows 的命令行版本。
- debain 装
apt install qemu-utils
。 - centos8 装
yum install qemu-img
。
qemu-img -h
查看帮助。resize 是改映像大小,convert 是改格式。
qemu-img info 映像文件名
查看文件的格式类型。
支持 img(raw), vhdx, vmdk, vdi, qcow, qcow2, dmg, ... 等很多格式,互相转换。- 例子,
qemu-img resize -f raw 映像文件名.img +200M
qemu-img convert -f raw -O vhdx 输入的映像名.img 输出的映像名.vhdx
如果有图形桌面
- 可以安装
apt install virt-manager
。
可以管理虚拟网络,可以管理虚拟机。 - 网络管理在这里找。隐藏的挺深,不熟悉的话还找不到。
可以创建NAT网络,private网络。可以设定网段,指定静态路由。 - 手动添加qemu-ga的通道。
----end----
转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/16417701.html
来自 osnosn的博客 https://www.cnblogs.com/osnosn/ .