在服务器上用qemu制作虚拟机

字符界面配置虚拟机好像有点难,所以还是先用vnc连接服务器:https://blog.csdn.net/qq_41961459/article/details/112909800

然后看这个:https://my.oschina.net/kelvinxupt/blog/265108
其中软件安装的部分不全,要装qemu-kvm

sudo apt install qemu-kvm

解决root窗口无法弹出的问题

在执行

sudo qemu-system-x86_64 -m 4096 -enable-kvm centos.img -cdrom ~/Downloads/CentOS-8.2.2004-x86_64-minimal.iso

的时候,会提示

X11 connection rejected because of wrong authentication.
Unable to init server: Could not connect: Connection refused
gtk initialization failed

看这篇文章可以解决:https://blog.csdn.net/qq_41961459/article/details/112916589
在服务器上用qemu制作虚拟机
ctrl+alt+g可以取消捕获。

联网

虚拟机一开始是没有网络的。

桥接网卡

参考:https://blog.csdn.net/u014022631/article/details/53411557配置网络。

sudo apt install bridge-utils uml-utilities

先看自己的机器的网卡编号

ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 30:9c:23:f0:33:40 brd ff:ff:ff:ff:ff:ff
    inet 10.249.41.236/21 brd 10.249.47.255 scope global dynamic noprefixroute eno1
       valid_lft 40668sec preferred_lft 40668sec
    inet6 fe80::140d:db62:feb5:b904/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

可以看到我的编号是eno1
由于操作网卡有可能导致连不上网,而连不上网的话服务器就失控了,所以最好是先设置一个定时重启,完成配置之后检测一下有没有网,有网则取消重启,否则就立即重启。由于操作过程有一段时间连不上网,所以需要把下面的保存为脚本运行:

set -e
if [ ! $1 ]; then
    echo Usage: $0 net_dev
    exit
fi
shutdown -r 1

brctl addbr br0
brctl addif br0 $1
brctl stp br0 off
brctl setfd br0 1
brctl sethello br0 1
ifconfig br0 0.0.0.0 promisc up
ifconfig $1 0.0.0.0 promisc up
dhclient br0
#brctl show br0
#brctl showstp br0

tunctl -t tap0 -u root              # 创建一个tap0接口,只允许root用户访问
brctl addif br0 tap0                # 在虚拟网桥中增加一个tap0接口
ifconfig tap0 0.0.0.0 promisc up    # 打开tap0接口
#brctl showstp br0                   # 显示br0的各个接口

if ping -c 1 baidu.com; then
    shutdown -c
    echo Shutdown canceled.
else
    shutdown -r now
fi

奇怪的是,在我的服务器上第一次失败了,但是重启之后第二次就成功了。

然后用下面的命令重新启动虚拟机:

sudo qemu-system-x86_64 -m 4096 -enable-kvm centos.img -net nic -net tap,ifname=tap0,script=no,downscript=no

如果虚拟机是centos的话,还需要在虚拟机中执行一下

dhclient

才能拿到ip。

这个相当于把虚拟机桥接到外面去了。如果外面的网络要登陆才能上网的话,还需要登陆一下。
在服务器上用qemu制作虚拟机

NAT

如果装的虚拟机没有GUI,但是外面的网络又需要在网页上登陆才能使用,那桥接就不太可行了,这时要用NAT模式,使虚拟机直接使用主机的网络。

https://wiki.qemu.org/Documentation/Networking/NAT
把下面的保存为ifup_nat.sh

#!/bin/sh
#
# Copyright IBM, Corp. 2010  
#
# Authors:
#  Anthony Liguori <aliguori@us.ibm.com>
#
# This work is licensed under the terms of the GNU GPL, version 2.  See
# the COPYING file in the top-level directory.

# Set to the name of your bridge
BRIDGE=br0

# Network information
NETWORK=192.168.53.0
NETMASK=255.255.255.0
GATEWAY=192.168.53.1
DHCPRANGE=192.168.53.2,192.168.53.254

# Optionally parameters to enable PXE support
TFTPROOT=
BOOTP=

do_brctl() {
    brctl "$@"
}

do_ifconfig() {
    ifconfig "$@"
}

do_dd() {
    dd "$@"
}

do_iptables_restore() {
    iptables-restore "$@"
}

do_dnsmasq() {
    dnsmasq "$@"
}

check_bridge() {
    if do_brctl show | grep "^$1" > /dev/null 2> /dev/null; then
	return 1
    else
	return 0
    fi
}

create_bridge() {
    do_brctl addbr "$1"
    do_brctl stp "$1" off
    do_brctl setfd "$1" 0
    do_ifconfig "$1" "$GATEWAY" netmask "$NETMASK" up
}

enable_ip_forward() {
    echo 1 | do_dd of=/proc/sys/net/ipv4/ip_forward > /dev/null
}

add_filter_rules() {
do_iptables_restore <<EOF
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007
*nat
:PREROUTING ACCEPT [61:9671]
:POSTROUTING ACCEPT [121:7499]
:OUTPUT ACCEPT [132:8691]
-A POSTROUTING -s $NETWORK/$NETMASK -j MASQUERADE 
COMMIT
# Completed on Fri Aug 24 15:20:25 2007
# Generated by iptables-save v1.3.6 on Fri Aug 24 15:20:25 2007
*filter
:INPUT ACCEPT [1453:976046]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1605:194911]
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 67 -j ACCEPT 
-A INPUT -i $BRIDGE -p udp -m udp --dport 67 -j ACCEPT 
-A INPUT -i $BRIDGE -p tcp -m tcp --dport 53 -j ACCEPT 
-A INPUT -i $BRIDGE -p udp -m udp --dport 53 -j ACCEPT 
-A FORWARD -i $1 -o $1 -j ACCEPT 
-A FORWARD -s $NETWORK/$NETMASK -i $BRIDGE -j ACCEPT 
-A FORWARD -d $NETWORK/$NETMASK -o $BRIDGE -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -o $BRIDGE -j REJECT --reject-with icmp-port-unreachable 
-A FORWARD -i $BRIDGE -j REJECT --reject-with icmp-port-unreachable 
COMMIT
# Completed on Fri Aug 24 15:20:25 2007
EOF
}

start_dnsmasq() {
    do_dnsmasq \
	--strict-order \
	--except-interface=lo \
	--interface=$BRIDGE \
	--listen-address=$GATEWAY \
	--bind-interfaces \
	--dhcp-range=$DHCPRANGE \
	--conf-file="" \
	--pid-file=/var/run/qemu-dnsmasq-$BRIDGE.pid \
	--dhcp-leasefile=/var/run/qemu-dnsmasq-$BRIDGE.leases \
	--dhcp-no-override \
	${TFTPROOT:+"--enable-tftp"} \
	${TFTPROOT:+"--tftp-root=$TFTPROOT"} \
	${BOOTP:+"--dhcp-boot=$BOOTP"}
}

setup_bridge_nat() {
    if check_bridge "$1" ; then
	create_bridge "$1"
	enable_ip_forward
	add_filter_rules "$1"
	start_dnsmasq "$1"
    fi
}

setup_bridge_vlan() {
    if check_bridge "$1" ; then
	create_bridge "$1"
	start_dnsmasq "$1"
    fi
}

setup_bridge_nat "$BRIDGE"

if test "$1" ; then
    do_ifconfig "$1" 0.0.0.0 up
    do_brctl addif "$BRIDGE" "$1"
fi

并给执行权限:

chmod +x ifup_nat.sh

如果不给执行权限会报错(exit code 255)。

然后启动虚拟机:

sudo qemu-system-x86_64 -m 4096 -enable-kvm centos.img -net nic -net tap,script=ifup_nat.sh

在服务器上用qemu制作虚拟机
这个方法我在家里的电脑上实验成功,但是在学校的服务器上失败了,不知道为什么。

上一篇:从0开始使用QEMU模拟ARM开发环境之uboot通过sd卡加载uImage


下一篇:docker使用常见问题解决方案:错误号码2058,docker WARNING :IPv4,容器间的通讯