技术分享
虚拟机KVM
2020-03-11
虚拟化
在x个物理资源上,运行y个逻辑资源,实现完全,部分,硬件辅助等的程度
系列 | PC/服务器版代表 |
---|---|
VMware | VMware Workstation vSphere |
Microsoft | VirtualPC Hyper-V |
RedHat | KVM RHEV |
Citrix |
Xen |
Oracle | Oracle VM VirtualBox |
虚拟化服务平台
KVM :linux内核的模块,需要cpu支持,采用硬件辅助虚拟化技术Intel-VT,AMD-V 内存的相关EPT 和AMD的RVI
QEMU :虚拟化的仿真工具,通过ioctl与内核kvm交互完成对硬件的虚拟化支持
Libvirt :对虚拟化管理的接口和工具,提供用户端程序virsh virt-install virt-manager virt-view与用户交互
必备软件 | 可选功能 | 虚拟机的组成 |
---|---|---|
qemu-kvm 为kvm提供底层仿真支持 | virt-install 系统安装工具 |
内核虚拟化模块kvm 系统设备仿真qemu 一个XML文件(虚拟机配置声明文件) 位置/etc/libvirt/qemu 一个磁盘镜像文件(虚拟机的硬盘) 位置/var/lib/libvirt/images |
libvirt-daemon libvirtd守护进程,管理虚拟机 | virt-manager 图形管理工具 | |
libvirt-client 用户端软件,提供客户端管理命令 | virt-v2v 虚拟机迁移工具 | |
libvirt-daemon-driver-qemu libvirtd链接qemu的驱动 | virt-p2v 物理机迁移工具 |
[root@guo ~]# yum group list //列出list组 已加载插件:fastestmirror, langpacks 没有安装组信息文件 Maybe run: yum groups mark convert (see man yum) Loading mirror speeds from cached hostfile 可用的环境分组: 最小安装 基础设施服务器 文件及打印服务器 基本网页服务器 ...
KVM管理
virsh 提供管理虚拟机的命令接口
交互模式 :查看/创建/停止/关闭...
格式 :virsh 控制命令 [虚拟机名称] [参数]
命令 | 说明 |
---|---|
virsh --help | 查看帮助 |
virsh list [--all] | 列出虚拟机 |
virsh net-list [--all] | 列出虚拟网络 |
virsh dominfo 虚拟机名称 | 查看虚拟机的信息 |
virsh start|reboot|shutdown 虚拟机名称 | 运行|重启|关闭指定的虚拟机 |
virsh destroy 虚拟机名称 | 强制关闭虚拟机 |
virsh autostart 虚拟机名称 | 将虚拟机设置为开机自动运行 |
[root@guo ~]# virsh --help ... options: -c | --connect=URI hypervisor connection URI -d | --debug=NUM debug level [0-4] -e | --escape <char> set escape sequence for console -h | --help this help ... [root@guo ~]# virsh list --all Id 名称 状态 ---------------------------------------------------- 3 zabbix-server running 4 web1 running ... [root@guo ~]# virsh net-list 名称 状态 自动开始 持久 ---------------------------------------------------------- default 活动 是 是 private1 活动 是 是 [root@guo ~]# virsh dominfo web1 Id: 4 名称: web1 UUID: eb892706-b58b-4421-b2a6-aa64defcc749 OS 类型: hvm ... [root@guo ~]# virsh start node1 域 node1 已开始 [root@guo ~]# virsh shutdown node1 域 node1 被关闭
常用镜像盘类型
注:虚拟化中,物理机称呼为host 虚拟主机称为guest 虚拟机的硬盘在物理机上只是一个文件
特点\类型 | RAW | QCOW2 |
---|---|---|
kvm默认 | 否 | 是 |
I/O效率(输入/输出)效率 | 高 | 较高 |
占用空间 | 大(预分配空间模式,虚拟机20G,物理机直接分配20G) | 小(延迟分配方式,虚拟机20G,物理机不直接分配20G,虚拟机随着数据的增加,自动增长空间) |
压缩/后端盘复用/快照 | 不支持 | 支持 |
qemu-img命令
虚拟机的磁盘管理命令,支持非常多的磁盘格式,例如raw qcow2 vdi vmdk等
qemu-img格式 qemu-img 命令 参数 块文件名称 大小
create 创建一个磁盘 |
qemu-img create -f 格式 磁盘路径 大小 创建新的镜像盘文件 qemu-img create -b 磁盘1 -f qcow2 新的磁盘2 使用后端模板文件 |
convert 转换磁盘格式 | |
info 查看磁盘信息 | qemu-img info 磁盘路径 查询镜像盘文件的信息 |
snapshot 管理磁盘快照 |
[root@guo ~]# cd /var/lib/libvirt/images/ //切换到磁盘镜像目录 [root@guo images]# ls -a ... conf.d openstack.img .rh7_template.img content proxy-1.qcow2 .rhel6.xml ... [root@guo images]# du -lh .rh7_template.img 3.7G .rh7_template.img [root@guo images]# qemu-img info .rh7_template.img image: .rh7_template.img file format: qcow2 virtual size: 20G (21474836480 bytes) disk size: 3.6G cluster_size: 65536 ... [root@guo images]# qemu-img create -f qcow2 -b .rh7_template.img myrh7.img //利用后端盘创建前端盘 [root@guo images]# qemu-img info myrh7.img //查看前端盘信息 image: myrh7.img file format: qcow2 virtual size: 20G (21474836480 bytes) disk size: 196K ... [root@guo images]# virt-manager //利用前端盘生成新的虚拟机 打开图形界面--点击“新建虚拟机”--导入现有磁盘镜像--/var/lib/libvirt/images/myrh7.img--根据向导可以完成后续操作
cow原理(copy on write 写时复制)
直接映射原始盘的数据内容,当原始盘的旧数据有修改时,在修改之前自动将旧数据存入到前端盘,但前端盘的修改不回写到原始盘
virsh管理
链接本地 vish virsh # connect qemu:///system(默认选项)
virsh # connect qemu +ssh://user@ip:port/system 链接远程 (可以管理其他用户的虚拟机)
[root@guo images]# virsh virsh # connect qemu:///system virsh # list --all Id 名称 状态 ---------------------------------------------------- 3 zabbix-server running 4 web1 running ... virsh # connect qemu+ssh://root@172.40.58.160:22/system Are you sure you want to continue connecting (yes/no)? yes root@172.40.58.160's password: irsh # list --all Id 名称 状态 ---------------------------------------------------- 2 web2 running 3 zabbix running 5 web1 running 9 rh7_node1 running ...
使用virt-manager客户端工具
打开界面--add connection(添加链接)-- "remote tunnel over ssh"
注:这个需要使用ssh免密登录,如果没有免密登录需要安装python的ssh相关模块
[root@guo images]# virt-manager
虚拟网络管理
virt-manager打开图形--编辑(edit)--链接详情--虚拟网络
虚拟机通过默认的default网并且访问互联网(确保虚拟网络的default活跃)
1.把虚拟机的网络链接协议改为default,设备为virtio
2.虚拟机如果有virbr0,把它删除(否则和物理机冲突)
[root@localhost ~]# ifconfig virbr0 down [root@localhost ~]# brctl delbr virbr0
3.重新激活虚拟机的eth0即可(网卡不一定叫这个名字,以实际为准即可)。因为default默认有dhcp功能,所以虚拟机将会自动或得IP地址,并且default网络默认用的是NATMOSHI,所以获取IP后,可以直接上网
[root@localhost ~]# ping www.baidu.com PING www.a.shifen.com (119.75.217.26) 56(84) bytes of data. 64 bytes from 119.75.217.26 (119.75.217.26): icmp_seq=1 ttl=54 time=4.56 ms 64 bytes from 119.75.217.26 (119.75.217.26): icmp_seq=2 ttl=54 time=5.41 ms 64 bytes from 119.75.217.26 (119.75.217.26): icmp_seq=3 ttl=54 time=2.81 ms 64 bytes from 119.75.217.26 (119.75.217.26): icmp_seq=4 ttl=54 time=5.39 ms 64 bytes from 119.75.217.26 (119.75.217.26): icmp_seq=5 ttl=54 time=3.03 ms ^C --- www.a.shifen.com ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 5416ms rtt min/avg/max/mdev = 2.816/4.245/5.411/1.121 ms
创建虚拟交换机
libvirtd 网络接口 调用dnsmasq提供DNS ,DHCP等功能
创建配置文件 /etc/libvirt/qemu/networks/vbr.xml
]# vim /etc/libvirt/qemu/networks/vbr.xml <network> <name>vbr</name> #网络名 <forward mode='nat'> #网络模式 </forward> <bridge name='vbr' stp='on' delay='0'/> #网卡名 <ip address='192.168.1.254' netmask='255.255.255.0'> #网卡vbr的IP地址 <dhcp> #虚拟机连到此网络时,为虚拟机分配的IP地址范围 <range start='192.168.1.101' end='192.168.1.200'/> </dhcp> </ip> </network>
virsh net-list 查看虚拟网络 | virsh net-define vbr.xml 创建虚拟网络 |
virsh net-edit vbr 修改vbr网络的配置 | virsh net-undefine vbr 删除虚拟网络 |
virsh net-autostart vbr 设置vbr虚拟网络开机自启动 | virsh net-start vbr 启动虚拟网络 |
virsh net-destroy vbr 停止虚拟网络 |
实例:自行创建网络,允许虚拟机通过自己创建的虚拟网络上网
1.将default网络的配置文件导出,将其当作模板文件,进行修改
[root@guo ~]# virsh net-dumpxml default > /tmp/default.xml
2.修改配置default.xml
[root@guo ~]# vim /tmp/default.xml <network> <name>vbr</name> <forward mode='nat'> </forward> <bridge name='vbr' stp='on' delay='0'/> <ip address='192.168.1.254' netmask='255.255.255.0'> <dhcp> <range start='192.168.1.101' end='192.168.1.200'/> </dhcp> </ip> </network>
3.利用文件生成网络
[root@guo ~]# virsh net-define /tmp/default.xml 从 vbr定义网络/tmp/default.xml
4.激活vbr网络,并设置开机自动激活
[root@guo ~]# virsh net-start vbr 网络 vbr 已开始 [root@guo ~]# virsh net-autostart vbr 网络vbr标记为自动启动 [root@guo ~]# virsh net-list 名称 状态 自动开始 持久 ---------------------------------------------------------- default 活动 是 是 private1 活动 是 是 private2 活动 是 是 public1 活动 是 是 public2 活动 是 是 rhce 活动 是 是 vbr 活动 是 是
5.为虚拟机指定自己刚才设置的网络
6. 删除网卡virbr0 ,激活eth0 查看并测试
[root@localhost ~]# ifconfig virbr0 down [root@localhost ~]# brctl delbr virbr0 [root@localhost ~]# ifup eth0 [root@localhost ~]# ifconfig eth0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.180 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 fe80::6892:782f:1432:b529 prefixlen 64 scopeid 0x20<link> ether 52:54:00:aa:35:94 txqueuelen 1000 (Ethernet) ... [root@localhost ~]# ping www.baidu.com PING www.a.shifen.com (119.75.217.26) 56(84) bytes of data. 64 bytes from 119.75.217.26 (119.75.217.26): icmp_seq=1 ttl=54 time=4.49 ms 64 bytes from 119.75.217.26 (119.75.217.26): icmp_seq=2 ttl=54 time=5.92 ms ...
xml管理
xml配置文件:定义了一个虚拟机的名称、cpu、内存、虚拟磁盘、网卡等各种参数设置 /etc/libvirt/qemu/虚拟机名.xml
xml模板 :<!-- 注释的开始 --> 注释的结尾
例如:自定义一台虚拟机,通过xml文件克隆一台虚拟机
1.创建前端盘
[root@guo ~]# cd /var/lib/libvirt/images/ [root@guo images]# qemu-img create -f qcow2 -b .rh7_template.img myrh7_2.img Formatting 'myrh7_2.img', fmt=qcow2 size=21474836480 backing_file='.rh7_template.img' encryption=off cluster_size=65536 lazy_refcounts=off
2.把现有的虚拟机配置文件导出,作为即将克隆虚拟机的配置文件
查看:virsh dumpxml 虚拟机名
备份:virsh dumpxml 虚拟机名 > 虚拟机名.xml
[root@guo images]# virsh list --all Id 名称 状态 ---------------------------------------------------- 4 web1 running 5 web2 running 6 agent77 running 14 generic running [root@guo images]# virsh dumpxml generic > /tmp/myvm.xml
3.修改文件,使它成为新虚拟机的配置文件
注:可以用virsh edit 虚拟机名 对虚拟机进行调整,如果修改name,memory,disk,network可自动保存为新虚拟机配置
[root@guo images]# vim /tmp/myvm.xml <domain type='kvm'> //删除原有的id <name>myrh7_2</name> //修改为新的虚拟机的名字 <uuid>d674cc9a-be3f-4053-8f1d-24a4d198e6a0</uuid> //删除UUID ... <source file='/var/lib/libvirt/images/myrh7_2.img'/> //改成第一步创建的磁盘名称 ... <mac address='52:54:00:aa:35:94'/> //删除mac地址 ... <channel type='spicevmc'> //如有,这一块闭合全部删除 <target type='virtio' name='com.redhat.spice.0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel> ...
4.使用文件生成新的虚拟机 virsh define XML描述文件 virsh undefine 模板 清楚模板配置
[root@guo images]# virsh define /tmp/myvm.xml 定义域 myrh7_2(从 /tmp/myvm.xml)
5.启动虚拟机
注:必要时可以删除多余的xml配置,避免出现多个虚拟机磁盘和MAC地址冲突
删除虚拟机 virsh undefine 虚拟机名
[root@guo images]# virsh start myrh7_2 域 myrh7_2 已开始
自定义虚拟机
网络yum源的安装和配置(见案例)
[root@guo ~]# yum -y install vsftpd [root@guo ~]# vim /etc/vsftpd/vsftpd.conf ... listen=YES ... listen_ipv6=NO ... [root@guo ~]# systemctl restart vsftpd [root@guo ~]# systemctl enable vsftpd
案例:创建教学环境
A 创建一个虚拟网络vbr,能够访问互联网(可以用默认的)
B 安装模板虚拟机
a.生成一个qcow2文件
b.将系统安装在第一步创建的磁盘文件
c.初始化系统(配置yum/firewall/selinux等)
C 通过模板机克隆新的虚拟机
a.生成一个虚拟机的xml文件
b.修改xml文件,用于克隆虚拟机
c.利用改好的xml文件生成新虚拟机
1.挂载centos7.4光盘挂载到/var/ftp/centos7.4
[root@guo ~]# yum -y install vsftpd [root@guo ~]# systemctl restart vsftpd [root@guo ~]# systemctl enable vsftpd [root@guo ~]# ls 456/ CentOS7-1708.iso RHEL7-extras.iso RHEL7OSP-10.iso [root@guo ~]# mkdir /var/ftp/CentOS7.4 [root@guo ~]# vim /etc/fstab /root/456/CentOS7-1708.iso /var/ftp/CentOS7.4 iso9660 defaults 0 0 [root@guo 456]# mount -a
2.为模板及生成磁盘镜像文件
[root@guo ~]# cd /var/lib/libvirt/images/ [root@guo images]# qemu-img create -f qcow2 cent7.img 2G Formatting 'cent7.img', fmt=qcow2 size=2147483648 encryption=off cluster_size=65536 lazy_refcounts=off
3.安装系统到cent7.img
[root@guo images]# virt-manager
virt-manager --新建虚拟机--网络安装--ftp://192.168.1.254/centos7.4 --内存2048,cpu2 --“选择管理的或者其他现有设备”/var/lib/libvirt/images/centos7.img--名称cent7 网络选择vbr
4.进入安装向导后
语言English--INSTALLATION DESTINATION --I will configure partitioning --店家done--下拉菜单选择Standard Partition--左下角的+好--Mount point 选 / ,下面的capacity 选2048,也就是把全部磁盘空间都分配给根分区--点击Done 选择 Accept Changes --取消KDUMP功能
5.初始化系统
关闭selinux /etc/selinux/config SELINUX=disabled
配置 yum
[root@localhost ~] # cd /etc/yum.repos.d [root@localhost yum.repos.d]# mkdir repoback [root@localhost yum.repos.d]# mv *.repo repoback/ [root@localhost yum.repos.d]# cat local.repo [server] name=server baseurl=ftp://192.168.1.254/CentOS7.4 gpgcheck=0 [root@localhost yum.repos.d]# yum repolist [root@localhost yum.repos.d]# ifup eth0
卸载防火墙和NetworkManager
[root@localhost ~] # yum remove -y NetworkManager-* python-firewall firewalld-*
安装软件lftp 常用命令net-tools vim-enhanced bridge-utils psmisc
删除网络配置里的个性化信息 /etc/sysconfig/network-scripts/ifcfg-eth0 和禁用空路由 /etc/sysconfig/network(防止机器获得169.254.x.x的地址,如果客户机选择自动选取地址,又没有服务给他们分配,它就会得到169.254.x.x的地址)
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 # Generated by dracut initrd DEVICE="eth0" ONBOOT=yes IPV6INIT=no BOOTPROTO=dhcp TYPE=Ethernet [root@localhost ~]# vim /etc/sysconfig/network # Created by anaconda NOZEROCONF=yes
修改内核参数,作用:可以使网卡叫ethX 虚拟机可以支持virsh console(可以不用IP链接)
[root@localhost yum.repos.d]# vim /etc/default/grub ... GRUB_CMDLINE_LINUX="biosdevname=0 net.ifnames=0 console=ttyS0 rhgb quiet" GRUB_DISABLE_LINUX_UUID=true #禁用UUID挂载 GRUB_ENABLE_LINUX_LABEL=true # 启用卷标挂分区 [root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg //grub2-mkconfig 会根据/etc/default/grub/ 生成 grub.cfg
安装虚拟机磁盘扩展命令,当克隆虚拟机时,指定虚拟机磁盘后,虚拟机磁盘可以自动扩容
[root@localhost ~] # yum -y install cloud-utils-growpart [root@localhost ~] # chmod 755 /etc/rc.local //虽然我们查看这个文件是777权限,但这只是源文件的链接,源文件只是644权限,所以我们要赋予x权限 [root@localhost ~]# vim /etc/rc.local ... /usr/bin/growpart /dev/vda 1 /usr/sbin/xfs_growfs /
关闭模板虚拟机,执行如下命令清理个性化设置,这个操作完成,初始化完成
[root@guo ~]# yum search virt-sysprep [root@guo ~]# yum -y install libguestfs-tools [root@guo ~]# virt-sysprep -d rhel7.4 [ 0.0] Examining the guest ... [ 22.4] Performing "abrt-data" ... [ 22.4] Performing "backup-files" ... [ 23.0] Performing "bash-history" ... ...
注:如果虚拟机已经关机了(或出现故障无法启动)可以使用guestmount在物理机上挂在虚拟机的磁盘
(guestmount 支持离线挂在raw,qcow2格式虚拟机磁盘,可以直接修改磁盘中的文档,方便对虚拟机定制,修复,脚本维护)
guestmount -a 虚拟机磁盘路径 -i /挂载点
[root@guo ~]# guestmount -a /var/lib/libvirt/images/cent7.img -i /mnt/ [root@guo ~]# ls /mnt/ bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr
脚本案例:编写配置IP的脚本
1.配置工作目录
[root@guo ~]# mkdir ~/bin/ [root@guo ~]# cd /root/bin/
2.编写脚本
#!/bin/bash read -p "interface: " ifname read -p "ip address: " ipaddr read -p "prefix: " prefix read -p "gateway: " gateway read -p "dns: " dns ipfile=/etc/sysconfig/network-scripts/ifcfg-$ifname cat <<EOF >$ipfile <<终止重定向,读到EOF停止 DEVICE=$ifname ONBOOT=yes TYPE=Ethernet IPV6INT=no BOORPROTO=none IPADDR=$ipaddr PREFIX=$prefix EOF if [ -n "$gateway" ];then sed -i "\$aGATEWAY=$gateway" $ipifle fi if [ -n "$dns" ]; then sed -i "\$aDNS=$dns" $ipfile fi
xml文件
虚拟机的xml文件存放位置/etc/libvirt/qemu
文件说明:
[root@guo ~]# vim /etc/libvirt/qemu/generic.xml <domain type='kvm'> <name>generic</name> //虚拟机的名字,如果有id,去掉 <uuid>d674cc9a-be3f-4053-8f1d-24a4d198e6a0</uuid> //去掉 <memory unit='KiB'>1048576</memory> //虚拟机最大使用内存,可以手动调整 <currentMemory unit='KiB'>1048576</currentMemory> //创建虚拟机使用内存 <vcpu placement='static'>1</vcpu> //cpu设置,可以调整 <resource> ...... </resource> //资源设置,可以删除 <os> //系统配置,及引导文件,不需要修改 <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type> <boot dev='hd'/> </os> <features> //电源配置不用修改 ... </features> <cpu mode='custom' match='exact' check='partial'> //cpu设置,可以修改乘使用真机 cpu <model fallback='allow'>Haswell-noTSX</model> </cpu> <clock offset='utc'> //时钟相关配置 ... </clock> <on_poweroff>destroy</on_poweroff> //重启,关机,强制关闭对应命令 <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <pm>......</pm> //内存及硬盘休眠相关设置,可以删除 <devices>...... </devices> //仿真设备及相关配置 <seclabel> ... ... </seclabel> //驱动安全标签,可删除 <address ... //总线设置和别名都可删除 <alias ... <emulator>/usr/libexec/qemu-kvm</emulator> //硬盘配置,需要修改 <disk type='file' device='disk'> ... </disk> <controller type='usb' index='0' model='ich9-ehci1'> //usb相关配置,可以删除 ... type='pci'... //pci总线设备,可以删除 ... type='virtio-serial'... //串口设备需要保留串口终端 ... type='network'... //网络配置需要更改 ... type='pty'... //串口终端,需要保留 ... type='unix'... //虚拟机通讯控制室接口 ... type='spicevmc'... //图形图像相关配置可以删除 ... type='tablet' //数位板,可以删除 ... type='mouse'... //鼠标,保留 ... type='keyboard'... //键盘保留 graphics, video //图形图像显卡相关配置,可以删除 sound //声卡相关配置,可以删除 redirdev //设备重定向,可以删除 memballoon //内存气泡,可以动态调整内存
利用已有文件创建虚拟机
1.创建前端盘
[root@guo ~]# cd /var/lib/libvirt/images/ [root@guo images]# qemu-img create -f qcow2 -b cent7.img cent7node1.img 100G Formatting 'cent7node1.img', fmt=qcow2 size=107374182400 backing_file='cent7.img' encryption=off cluster_size=65536 lazy_refcounts=off [root@guo images]# cd /root
2.修改虚拟机配置文件
[root@guo ~]# cp nsd1809/node.xml /tmp/ [root@guo ~]# vim /tmp/node.xml <domain type='kvm'> <name>cent7node1</name> //改名 ... <source file='/var/lib/libvirt/images/cent7node1.img'/> ...
3.生成虚拟机
[root@guo ~]# virsh define /tmp/node.xml 定义域 cent7node1(从 /tmp/node.xml) [root@guo ~]# virsh start cent7node1 域 cent7node1 已开始 [root@guo ~]# virsh console cent7node1 连接到域 cent7node1 换码符为 ^]
脚本案例:批量创建虚拟机
[root@guo ~]# cp nsd1809/node.xml /root/bin [root@guo ~]# cd /root/bin/ [root@guo bin]# vim cent7clone.sh #!/bin/bash read -p "create vm numbers: " NUMBER COUNTER=0 IMG_DIR=/var/lib/libvirt/images while [ $COUNTER -lt $NUMBER ] do let n++ vm=cent7node$n result=$(virsh list --all | grep $vm) if [ -z "$result" ];then qemu-img create -f qcow2 -b $IMG_DIR/cent7.img $IMG_DIR/${vm}.img 100G &> /dev/null cp /root/bin/node.xml /tmp sed -i "s/node/${vm}/" /tmp/node.xml virsh define /tmp/node.xml &> /dev/null let COUNTER++ echo -e "create ${vm} .... \t\t\t\t \033[32;1m[Done]\033[0m" fi done

- 标签:
-
其他