KVM 虚拟化技术与部署
KVM 虚拟化技术与部署(基于 CentOS 7)
一、KVM 虚拟化基础
1. 虚拟化核心概念
- 定义:在单台物理计算机(宿主机,Host)上虚拟出多个独立逻辑计算机(客户机,Guest),每个客户机可运行不同操作系统,应用程序在隔离空间内互不影响。
- 核心价值:
节约成本:减少物理硬件采购、维护及能耗支出
提高效率:单 CPU 模拟多 CPU 并行,提升硬件资源利用率,简化 IT 管理。
2. 虚拟化技术分类(按 Hypervisor 架构)
类型 | 核心特点 | 代表技术 | 适用场景 |
完全虚拟化 | 无需修改客户机 OS 内核,Hypervisor 直接部署在物理机,依赖硬件虚拟化优化(如 Intel VT-x/AMD-V),性能高 | Xen、VMware ESXi、KVM | 生产环境,对性能要求高的场景 |
半虚拟化 | 需修改客户机 OS 内核以支持虚拟化驱动,基于普通 OS 运行,支持虚拟机嵌套(如 KVM 内再运行 KVM),灵活性强 | Xen(早期版本) | 开发测试、需要嵌套虚拟化的场景 |
3. KVM 虚拟化原理
- 定义:KVM(Kernel-Based Virtual Machine)是 Linux 内核原生支持的完全虚拟化技术,将 Linux 内核转变为 Hypervisor。
- 核心组件协同:
KVM 内核模块(kvm.ko):仅负责 CPU 与内存虚拟化,通过硬件辅助技术实现指令拦截与内存地址转换。
Qemu:纯软件模拟器,负责 I/O 虚拟化(存储、网络、显卡等),模拟硬件设备并将指令转译给物理硬件,与 KVM 配合实现完整虚拟化(KVM 负责高性能计算,Qemu 负责 I/O 处理)。
Libvirt:KVM 管理工具集,包含:
-
- libvirtd:后台服务,接收并处理 API 请求;
-
- API 库:支持开发图形化工具(如 virt-manager);
-
- virsh:命令行工具,用于管理虚拟机生命周期。
二、KVM 部署前置准备(CentOS 7)
1. 硬件与系统要求
项目 | 要求 |
内存 | ≥ 8GB(虚拟机内存分配需预留宿主机资源) |
磁盘 | ≥ 200GB(建议单独分区用于虚拟机存储) |
CPU | 支持硬件虚拟化(Intel VT-x 或 AMD-V) |
系统 | CentOS 7,已配置 YUM 源,关闭防火墙与 SELinux |
2. 关闭防火墙与 SELinux
# 关闭防火墙并设置开机禁用systemctl stop firewalldsystemctl disable firewalld# 临时关闭 SELinuxsetenforce 0# 永久关闭 SELinux(修改配置文件)vim /etc/selinux/configSELINUX=disabled
3. 磁盘分区与挂载(单独分区用于 KVM 存储)
# 1. 查看磁盘信息(确认待分区磁盘,如 /dev/sdb)parted -l# 2. 分区操作(以 /dev/sdb 为例)parted /dev/sdb# 输入以下命令(交互模式):(parted) mklabel msdos # 设置分区表类型为 msdos(parted) mkpart primary xfs 0% 100% # 创建主分区,占用全部磁盘空间(parted) quit # 退出# 3. 刷新磁盘分区信息udevadm settle# 4. 格式化分区(XFS 文件系统)mkfs.xfs /dev/sdb1# 5. 查看分区 UUID(用于永久挂载)blkid /dev/sdb1 # 记录 UUID,如:/dev/sdb1: UUID="xxxx-xxxx" TYPE="xfs"# 6. 永久挂载(编辑 /etc/fstab)vim /etc/fstab# 添加以下内容(UUID 替换为实际值,挂载点设为 /kvmdata)UUID=xxxx-xxxx /kvmdata xfs defaults 0 0# 7. 创建挂载点并刷新挂载mkdir -p /kvmdatamount -a# 验证挂载(确认 /dev/sdb1 已挂载到 /kvmdata)df -Th
三、KVM 核心组件安装
1. 安装基础依赖工具
yum -y install vim wget net-tools unzip zip gcc gcc-c++
2. 验证 CPU 虚拟化支持
# 输出 "vmx"(Intel)或 "svm"(AMD)表示支持egrep -o 'vmx|svm' /proc/cpuinfo
3. 安装 KVM 及相关组件
yum -y install \qemu-kvm \qemu-kvm-tools \qemu-img \ # 虚拟机磁盘管理工具virt-manager \ # 图形化管理工具libvirt \ # 虚拟化管理库libvirt-python \ # Python 调用 libvirt 的接口libvirt-client \ # libvirt 客户端工具virt-install \ # 虚拟机创建工具virt-viewer \ # 虚拟机图形化控制台bridge-utils \ # 网桥管理工具libguestfs-tools # 虚拟机磁盘维护工具
4. 配置桥接网络(KVM 虚拟机默认使用 NAT,桥接模式支持外部访问)
(1)复制并修改网桥配置文件
# 进入网卡配置目录cd /etc/sysconfig/network-scripts/# 复制物理网卡配置(以 ens33 为例)作为网桥模板cp ifcfg-ens33 ifcfg-br0
(2)编辑网桥配置(ifcfg-br0)
vim ifcfg-br0# 替换为以下内容(IP 按实际环境修改)TYPE=BridgeBOOTPROTO=noneNAME=br0DEVICE=br0ONBOOT=yesIPADDR=192.168.100.20 # 网桥 IP(与物理网卡同网段)PREFIX=24 # 子网掩码(255.255.255.0)GATEWAY=192.168.100.254 # 网关DNS1=8.8.8.8 # DNS 服务器
(3)修改物理网卡配置(ifcfg-ens33)
vim ifcfg-ens33# 保留以下内容,删除原有 IP 相关配置TYPE=EthernetBOOTPROTO=noneNAME=ens33DEVICE=ens33ONBOOT=yesBRIDGE=br0 # 绑定到网桥 br0
(4)重启网络并验证网桥
# 重启网络服务systemctl restart network# 查看网桥信息(确认 br0 已创建,ens33 已关联)ip abrctl show
5. 启动 KVM 相关服务并验证
# 1. 启动 libvirtd 服务并设置开机自启systemctl restart libvirtdsystemctl enable libvirtd# 2. 验证 KVM 模块加载(输出 kvm、kvm_intel/kvm_amd 表示成功)lsmod | grep kvm# 3. 验证 KVM 安装(无报错即可)virsh -c qemu:///system list # 查看虚拟机列表(初始为空)virsh --version # 查看 virsh 版本virt-install --version # 查看 virt-install 版本# 4. 创建 qemu-kvm 软链接(方便调用)ln -s /usr/libexec/qemu-kvm /usr/bin/qemu-kvm# 验证软链接ll /usr/bin/qemu-kvm
四、KVM Web 管理界面部署(webvirtmgr)
1. 安装 webvirtmgr 依赖包
yum -y install git python-pip libvirt-python libxml2-python python-websockify supervisor nginx python-devel
2. 从 GitHub 下载 webvirtmgr 源码
# 进入源码目录cd /usr/local/src/# 克隆代码(若克隆失败,需配置网络代理)git clone https://github.com/retspen/webvirtmgr.git
3. 安装 webvirtmgr 依赖库
# 进入 webvirtmgr 目录cd /usr/local/src/webvirtmgr/# 安装依赖(--trusted-host 解决 pip 源信任问题)pip --trusted-host pypi.python.org install -r requirements.txt
4. 验证 SQLite3 安装(webvirtmgr 依赖 SQLite 存储数据)
# 进入 Python 命令行python# 输入以下命令,无报错表示安装成功import sqlite3exit() # 退出 Python
5. 初始化 webvirtmgr 管理员账号
cd /usr/local/src/webvirtmgr/# 执行初始化命令python manage.py syncdb# 交互配置(按提示输入):Would you like to create one now? (yes/no): yes # 选择创建超级管理员Username (leave blank to use 'root'): # 管理员用户名(默认 root,可自定义)Email address: admin@example.com # 管理员邮箱(自定义)Password: # 管理员密码(输入时不显示)Password (again): # 再次确认密码
6. 配置 webvirtmgr 目录与权限
# 1. 复制 webvirtmgr 到 Nginx 网站根目录cp -r /usr/local/src/webvirtmgr/ /var/www/# 2. 修改目录属主为 Nginx 用户chown -R nginx.nginx /var/www/webvirtmgr/
7. 配置 SSH 免密登录(webvirtmgr 与 KVM 宿主机通信)
# 1. 生成 SSH 密钥(一路回车默认即可)ssh-keygen# 2. 分发公钥到 KVM 宿主机(本地部署,目标 IP 为宿主机 IP)ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.100.20# 3. 配置 Nginx 用户免密登录(webvirtmgr 运行用户为 nginx)su - nginx -s /bin/bash # 切换到 nginx 用户(使用 bash shell)ssh-keygen # 生成 nginx 用户的 SSH 密钥touch ~/.ssh/config# 添加 SSH 配置(跳过主机密钥检查)echo -e "StrictHostKeyChecking=no\nUserKnownHostsFile=/dev/null" >> ~/.ssh/configchmod 0600 ~/.ssh/config # 设置文件权限(必须 600)# 分发 nginx 用户公钥到宿主机ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.100.20# 验证免密登录(无密码登录成功即可)ssh root@192.168.100.20exit # 退出 nginx 用户
8. 配置 Nginx 服务
(1)备份并修改 Nginx 主配置
# 备份默认配置cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak# 编辑主配置vim /etc/nginx/nginx.conf# 修改以下内容:1. 删除 "listen [::]:80;" 行(避免 IPv6 端口冲突)2. 将 "server_name _;" 改为 "server_name localhost;"3. 删除 "root /usr/share/nginx/html;" 行4. 在 "include /etc/nginx/default.d/*.conf;" 下添加:location / {root html;index index.html index.htm;}5. 在 "pid /run/nginx.pid;" 下添加(解决 "Too many open files" 错误):worker_rlimit_nofile 655350;
(2)配置 Nginx 虚拟主机(webvirtmgr)
vim /etc/nginx/conf.d/webvirtmgr.conf# 添加以下内容:server {listen 80 default_server; # 监听 80 端口(默认站点)server_name $hostname;# 静态文件目录(webvirtmgr 静态资源)location /static/ {root /var/www/webvirtmgr/webvirtmgr;expires max; # 静态文件缓存最大化}# 反向代理到 webvirtmgr 服务(8000 端口)location / {proxy_pass http://127.0.0.1:8000;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;proxy_set_header Host $host:$server_port;proxy_set_header X-Forwarded-Proto $remote_addr;proxy_connect_timeout 600; # 连接超时时间proxy_read_timeout 600; # 读取超时时间proxy_send_timeout 600; # 发送超时时间client_max_body_size 1024M; # 允许上传最大文件大小(适配 ISO 镜像)}}
9. 配置 Supervisor(管理 webvirtmgr 进程)
# 编辑 Supervisor 配置文件vim /etc/supervisord.conf# 在文件末尾添加以下内容:[program:webvirtmgr]command=/usr/bin/python2 /var/www/webvirtmgr/manage.py run_gunicorn -c /var/www/webvirtmgr/conf/gunicorn.conf.pydirectory=/var/www/webvirtmgr # 工作目录autostart=true # 开机自启autorestart=true # 进程异常时自动重启logfile=/var/log/supervisor/webvirtmgr.log # 日志文件log_stderr=true # 错误日志重定向user=nginx # 运行用户[program:webvirtmgr-console]command=/usr/bin/python2 /var/www/webvirtmgr/console/webvirtmgr-consoledirectory=/var/www/webvirtmgrautostart=trueautorestart=truestdout_logfile=/var/log/supervisor/webvirtmgr-console.logredirect_stderr=trueuser=nginx
10. 配置系统文件打开数(解决连接数限制)
vim /etc/security/limits.conf# 在文件末尾添加:* soft nofile 655350 # 软限制(默认生效)* hard nofile 655350 # 硬限制(最大限制)
11. 启动服务并验证
# 1. 重启 Nginx、Supervisor、libvirtd 服务systemctl restart nginxsystemctl restart supervisordsystemctl restart libvirtd# 2. 设置服务开机自启systemctl enable nginxsystemctl enable supervisord# 3. 查看端口(确认 80、8000 端口已监听)ss -antl
五、KVM Web 界面使用(webvirtmgr)
1. 访问 Web 管理界面
- 浏览器输入 KVM 宿主机 IP:http://192.168.100.20
- 登录:输入初始化时创建的管理员账号与密码
2. 初始化配置(创建存储池与网络)
(1)创建存储池(用于存放虚拟机磁盘与 ISO 镜像)
- 登录后点击左侧 “Storage Pools” → “New Storage Pool”;
- 配置:
-
- Name:自定义名称(如 kvm_storage);
-
- Type:选择 “Directory”;
-
- Path:输入 /kvmdata(之前挂载的单独分区);
- 点击 “Create” 完成创建。
(2)上传 ISO 镜像(虚拟机安装介质)
- 进入存储池(kvm_storage)→ 点击 “Upload”;
- 选择本地 ISO 镜像(如 CentOS 7 镜像),上传到 /kvmdata 目录;
-
- 若 Web 上传慢,可通过 lrzsz 工具在宿主机上传:
yum -y install lrzszcd /kvmdatarz # 选择本地 ISO 镜像上传
(3)创建虚拟网络(使用桥接网络 br0)
- 点击左侧 “Networks” → “New Network”;
- 配置:
-
- Name:自定义名称(如 br0_network);
-
- Type:选择 “Routed” 或 “Bridge to LAN”;
-
- Bridge:选择 br0(之前配置的桥接网卡);
- 点击 “Create” 完成。
3. 创建虚拟机
- 点击左侧 “Instances” → “New Instance”;
- 按向导配置:
-
- Name:虚拟机名称(如 centos7-vm);
-
- Memory:内存大小(如 2048MB);
-
- VCPUs:CPU 核心数(如 2);
-
- Storage:选择存储池,设置磁盘大小(如 20GB);
-
- ISO Image:选择上传的 ISO 镜像;
-
- Network:选择创建的桥接网络 br0_network;
- 点击 “Create” 启动虚拟机,进入安装界面(与物理机安装系统一致)。
六、常见问题解决
1. 访问 Web 界面报错 “Too many open files”
- 原因:Nginx 或系统文件打开数限制不足;
- 解决:已在步骤四中配置 worker_rlimit_nofile 与 /etc/security/limits.conf,重启服务即可。
2. 虚拟机无法通过桥接网络联网
- 检查:brctl show 确认 ens33 已关联到 br0;
- 解决:重启网络服务 systemctl restart network,重新创建虚拟网络并选择 br0。
3. webvirtmgr 无法连接 libvirtd 服务
- 检查:systemctl status libvirtd 确认服务正常;
- 解决:配置 libvirt 远程访问权限:
vim /etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla# 添加以下内容:[Remote libvirt SSH access]Identity=unix-user:rootAction=org.libvirt.unix.manageResultAny=yesResultInactive=yesResultActive=yes# 修改权限并重启服务chown -R root.root /etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pklasystemctl restart libvirtd