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-installvm客户机的命令行安装工具。
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-machinesCockpit 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 updateapt 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/nested0:关闭,1:打开。- 修改
/etc/modprobe.d/kvm.conf中options kvm_intel nested=1
rmmod kvm-intel或者modprobe -r kvm-intel卸载。
modprobe kvm-intel nested=1重新加载。
或者,重启整个系统。
- Debian11默认是打开的。
UOS
- 按照 debian11 的方法安装 kvm。
- 如果是arm架构的cpu,
检查是否安装了qemu-system-arm - 华为的 Kirin990 好像不支持 kvm。(2025-11)
- 搜索
kirin990 kvm cpu_map,没找到什么有用的。
- 搜索
安装 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 ## 关于org.qemu.guest_agent.0,见下文"虚拟机接受kvm关机指令" - 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 dominfo 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 ## 关于org.qemu.guest_agent.0,见下文"虚拟机接受kvm关机指令" - 修改 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 - img 转 qcow2
会生成一个新文件qcow2,旧的img不会被改写/覆盖。
qemu-img convert -O qcow2 输入的映像名.img 输出的映像名.qcow2
qemu-img convert -c -O qcow2 输入的映像名.img 输出的映像名.qcow2带上压缩属性。
如果有图形桌面
- 可以安装
apt install virt-manager。
可以管理虚拟网络,可以管理虚拟机。 - 网络管理在这里找。隐藏的挺深,不熟悉的话还找不到。
![]()
可以创建NAT网络,private网络。可以设定网段,指定静态路由。 - 手动添加qemu-ga的通道。
![]()
----end----
转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/16417701.html
来自 osnosn的博客 https://www.cnblogs.com/osnosn/ .



浙公网安备 33010602011771号