kvm簡單介紹
KVM架構
KVM,是Keyboard Video Mouse的縮寫,KVM 通過直接連接鍵盤、視頻和鼠標 (KVM) 端口,能夠訪問和控制計算機。KVM 技術無需目標服務器修改軟件。這就意味着可以在BIOS環境下,隨時訪問目標計算機。KVM 提供真正的主板級別訪問,並支持多平臺服務器和串行設備。KVM 技術已經從最初的基礎SOHO辦公型,發展成爲企業 IT 基礎機房設施管理系統。可以從kvm 客戶端管理軟件輕鬆的直接訪問位於多個遠程位置的服務器和設備。KVM over IP 解決方案具備完善的多地點故障轉移功能、符合新服務器管理標準 (IPMI) 的直接界面,以及將本地存儲媒體映射至遠程位置的功能。
KVM 是實現攔截虛機的 I/O 請求的原理:
現代 CPU 本身實現了對特殊指令的截獲和重定向的硬件支持,甚至新硬件會提供額外的資源來幫助軟件實現對關鍵硬件資源的虛擬化從而提高性能。以 X86 平臺爲例,支持虛擬化技術的 CPU 帶有特別優化過的指令集來控制虛擬化過程。通過這些指令集,VMM 很容易將客戶機置於一種受限制的模式下運行,一旦客戶機試圖訪問物理資源,硬件會暫停客戶機運行,將控制權交回給 VMM 處理。VMM 還可以利用硬件的虛級化增強機制,將客戶機在受限模式下對一些特定資源的訪問,完全由硬件重定向到 VMM 指定的虛擬資源,整個過程不需要暫停客戶機的運行和 VMM 的參與。由於虛擬化硬件提供全新的架構,支持操作系統直接在上面運行,無需進行二進制轉換,減少了相關的性能開銷,極大簡化了VMM的設計,使得VMM性能更加強大。從 2005 年開始,Intel 在其處理器產品線中推廣 Intel Virtualization Technology 即 IntelVT 技術。
QEMU-KVM:
其實 QEMU 原本不是 KVM 的一部分,它自己就是一個純軟件實現的虛擬化系統,所以其性能低下。但是,QEMU 代碼中包含整套的虛擬機實現,包括處理器虛擬化,內存虛擬化,以及 KVM需要使用到的虛擬設備模擬(網卡、顯卡、存儲控制器和硬盤等)。 爲了簡化代碼,KVM 在 QEMU 的基礎上做了修改。VM 運行期間,QEMU 會通過 KVM 模塊提供的系統調用進入內核,由 KVM 負責將虛擬機置於處理的特殊模式運行。當虛機進行 I/O 操作時,KVM 會從上次系統調用出口處返回 QEMU,由 QEMU 來負責解析和模擬這些設備。 從 QEMU 角度看,也可以說是 QEMU 使用了 KVM 模塊的虛擬化功能,爲自己的虛機提供了硬件虛擬化加速。除此以外,虛機的配置和創建、虛機運行所依賴的虛擬設備、虛機運行時的用戶環境和交互,以及一些虛機的特定技術比如動態遷移,都是 QEMU 自己實現的。
KVM:
KVM 內核模塊在運行時按需加載進入內核空間運行。KVM 本身不執行任何設備模擬,需要 QEMU 通過 /dev/kvm 接口設置一個 GUEST OS 的地址空間,向它提供模擬的 I/O 設備,並將它的視頻顯示映射回宿主機的顯示屏。它是KVM 虛機的核心部分,其主要功能是初始化 CPU 硬件,打開虛擬化模式,然後將虛擬客戶機運行在虛擬機模式下,並對虛機的運行提供一定的支持。以在 Intel 上運行爲例,KVM 模塊被加載的時候,它:
首先初始化內部的數據結構;
做好準備後,KVM 模塊檢測當前的 CPU,然後打開 CPU 控制及存取 CR4 的虛擬化模式開關,並通過執行 VMXON 指令將宿主操作系統置於虛擬化模式的根模式;
最後,KVM 模塊創建特殊設備文件 /dev/kvm 並等待來自用戶空間的指令。
接下來的虛機的創建和運行將是 QEMU 和 KVM 相互配合的過程。兩者的通信接口主要是一系列針對特殊設備文件 /dev/kvm 的 IOCTL 調用。其中最重要的是創建虛機。它可以理解成KVM 爲了某個特定的虛機創建對應的內核數據結構,同時,KVM 返回一個文件句柄來代表所創建的虛機。
針對該句柄的調用可以對虛機做相應地管理,比如創建用戶空間虛擬地址和客戶機物理地址、真實物理地址之間的映射關係,再比如創建多個 vCPU。KVM 爲每一個 vCPU 生成對應的文件句柄,對其相應地 IOCTL 調用,就可以對vCPU進行管理。其中最重要的就是“執行虛擬處理器”。通過它,虛機在 KVM 的支持下,被置於虛擬化模式的非根模式下,開始執行二進制指令。在非根模式下,所有敏感的二進制指令都被CPU捕捉到,CPU 在保存現場之後自動切換到根模式,由 KVM 決定如何處理。
除了 CPU 的虛擬化,內存虛擬化也由 KVM 實現。實際上,內存虛擬化往往是一個虛機實現中最複雜的部分。CPU 中的內存管理單元 MMU 是通過頁表的形式將程序運行的虛擬地址轉換成實際物理地址。在虛擬機模式下,MMU 的頁表則必須在一次查詢的時候完成兩次地址轉換。因爲除了將客戶機程序的虛擬地址轉換了客戶機的物理地址外,還要將客戶機物理地址轉化成真實物理地址。
Linux 上的用戶空間、內核空間和虛機:
Guest:客戶機系統,包括CPU(vCPU)、內存、驅動(Console、網卡、I/O 設備驅動等),被 KVM 置於一種受限制的 CPU 模式下運行。
KVM:運行在內核空間,提供 CPU 和內存的虛級化,以及客戶機的 I/O 攔截。Guest 的 I/O 被 KVM 攔截後,交給 QEMU 處理。
QEMU:修改過的被 KVM 虛機使用的 QEMU 代碼,運行在用戶空間,提供硬件 I/O 虛擬化,通過 IOCTL /dev/kvm 設備和 KVM 交互。
2. KVM 的功能列表
KVM 所支持的功能包括:
支持 CPU 和 memory 超分(Overcommit)
支持半虛擬化 I/O (virtio)
支持熱插拔 (cpu,塊設備、網絡設備等)
支持對稱多處理(Symmetric Multi-Processing,縮寫爲 SMP )
支持實時遷移(Live Migration)
支持 PCI 設備直接分配和 單根 I/O 虛擬化 (SR-IOV)
支持 內核同頁合併 (KSM )
支持 NUMA (Non-Uniform Memory Access,非一致存儲訪問結構 )
3. KVM 工具集合
libvirt:操作和管理KVM虛機的虛擬化 API,使用 C 語言編寫,可以由 Python,Ruby, Perl, PHP, Java 等語言調用。可以操作包括 KVM,vmware,XEN,Hyper-v, LXC 等在內的多種 Hypervisor。
Virsh:基於 libvirt 的 命令行工具 (CLI)
Virt-Manager:基於 libvirt 的 GUI 工具
virt-v2v:虛機格式遷移工具
virt-* 工具:包括 Virt-install (創建KVM虛機的命令行工具), Virt-viewer (連接到虛機屏幕的工具),Virt-clone(虛機克隆工具),virt-top 等
sVirt:安全工具
4. RedHat Linux KVM 安裝
RedHat 有兩款產品提供 KVM 虛擬化:
Red Hat Enterprise Linux:適用於小的環境,提供數目較少的KVM虛機。最新的版本包括 6.5 和 7.0.
Red Hat Enterprise Virtualization (RHEV):提供企業規模的KVM虛擬化環境,包括更簡單的管理、HA,性能優化和其它高級功能。最新的版本是 3.0.
RedHat Linux KVM:
KVM 由 libvirt API 和基於該 API的一組工具進行管理和控制
KVM 支持系統資源超分,包括內存和CPU的超分。RedHat Linux 最多支持物理 CPU 內核總數的10倍數目的虛擬CPU,但是不支持在一個虛機上分配超過物理CPU內核總數的虛擬CPU。
支持 KSM (Kenerl Same-page Merging 內核同頁合併)
KVM安裝
環境:centos 7.7-1908
外網:10.0.0.41
內網: 176.16.1.41
1、關閉防火牆與selinux
[root@ c7-41 ~]# systemctl stop firewalld
[root@ c7-41 ~]# systemctl disable firewalld
[root@ c7-41 ~]# setenforce 0
[root@ c7-41 ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
2、安裝依賴
[root@ c7-41 ~]# yum -y install epel-release vim wget net-tools unzip zip gcc gcc-c++
3、配置環境、修改網站訪問併發量
[root@ c7-41 ~]# vim /etc/security/limits.conf ###在末尾添加
* soft nofile 65535
* hard nofile 65535
[root@ c7-41 ~]# cat /etc/security/limits.conf |grep -w '*' | grep -v '^#'
* soft nofile 65535
* hard nofile 65535
[root@ c7-41 ~]# vim /etc/pam.d/login ###在末尾添加
session required /lib/security/pam_limits.so
[root@ c7-41 ~]# vim /etc/profile ###在末尾添加
ulimit -n 65535
[root@ c7-41 ~]# source /etc/profile ###生效
[root@ c7-41 ~]# ulimit -n
65535
###星號代表全局, soft爲軟件,hard爲硬件,nofile爲這裏指可打開文件數。
4、驗證CPU是否支持KVM;如果結果中有vmx(Intel)或svm(AMD)字樣,就說明CPU的支持的
關閉虛擬機設置
[root@ c7-41 ~]# egrep -o 'vmx|svm' /proc/cpuinfo
vmx
5、kvm安裝
[root@ c7-41 ~]# yum -y install qemu-kvm qemu-kvm-tools qemu-img virt-manager libvirt libvirt-python libvirt-client virt-install virt-viewer bridge-utils libguestfs-tools
6、啓動服務,驗證安裝結果
[root@ c7-41 ~]# systemctl start libvirtd
[root@ c7-41 ~]# systemctl enable libvirtd
[root@ c7-41 ~]# systemctl status libvirtd
[root@ c7-41 ~]# lsmod|grep kvm
kvm_intel 188644 0
kvm 621480 1 kvm_intel
irqbypass 13503 1 kvm
[root@ c7-41 ~]# virsh -c qemu:///system list
Id Name State
----------------------------------------------------
[root@ c7-41 ~]# ln -s /usr/libexec/qemu-kvm /usr/bin/qemu-kvm
[root@ c7-41 ~]# ll /usr/bin/qemu-kvm
lrwxrwxrwx 1 root root 21 May 5 11:16 /usr/bin/qemu-kvm -> /usr/libexec/qemu-kvm
kvm web管理界面安裝
kvm 的 web 管理界面是由 webvirtmgr 程序提供的
1.安裝依賴
[root@ c7-41 ~]# yum -y install git python-pip libvirt-python libxml2-python python-websockify supervisor nginx python-devel
##升級pip
[root@ c7-41 ~]# pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
Collecting pip
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/54/2e/df11ea7e23e7e761d484ed3740285a34e38548cf2bad2bed3dd5768ec8b9/pip-20.1-py2.py3-none-any.whl (1.5MB)
100% |████████████████████████████████| 1.5MB 256kB/s
Installing collected packages: pip
Found existing installation: pip 8.1.2
Uninstalling pip-8.1.2:
Successfully uninstalled pip-8.1.2
Successfully installed pip-20.1
pip 20.0.2文檔 https://pip.pypa.io/en/stable/user_guide/#config-file
pip是一個很好用的第三方庫安裝方式,但是默認的源沒法連接,就算有時候可以成功率也很低,所以換成國內鏡像源比較方便。
將pip源更換到國內鏡像
用pip管理工具安裝庫文件時,默認使用國外的源文件,因此在國內的下載速度會比較慢,可能只有50KB/s。幸好,國內的一些頂級科研機構已經給我們準備好了各種鏡像,下載速度可達2MB/s。
臨時方法
阿里雲 https://mirrors.aliyun.com/pypi/simple/
中國科技大學 https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) https://pypi.douban.com/simple/
清華大學 https://pypi.tuna.tsinghua.edu.cn/simple/
中國科學技術大學 http://pypi.mirrors.ustc.edu.cn/simple/
華中理工大學:http://pypi.hustunique.com/
山東理工大學:http://pypi.sdutlinux.org/
從github上下載webvirtmgr代碼
[root@ c7-41 ~]# cd /usr/local/src/
[root@ c7-41 src]# git clone git://github.com/retspen/webvirtmgr.git
安裝webvirtmgr
[root@ c7-41 src]# cd webvirtmgr/
##如果報錯,換一個鏡像(上面有)
[root@ c7-41 webvirtmgr]# pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
檢查sqlite3是否安裝
[root@ c7-41 webvirtmgr]# python
Python 2.7.5 (default, Aug 7 2019, 00:51:29)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> exit()
8、初始化帳號信息
[root@ c7-41 webvirtmgr]# python manage.py syncdb
WARNING:root:No local_settings file found.
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table servers_compute
Creating table instance_instance
Creating table create_flavor
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes ##是否創建超級管理員帳號
Username (leave blank to use 'root'): ##回車默認爲root
Email address: [email protected] ##設置超級管理員郵箱
Password: 123456 ##設置超級管理員密碼
Password (again):123456
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 6 object(s) from 1 fixture(s)
拷貝web網頁至指定目錄
[root@ c7-41 webvirtmgr]# mkdir /var/www
[root@ c7-41 webvirtmgr]# cp -r /usr/local/src/webvirtmgr/ /var/www/
[root@ c7-41 webvirtmgr]# chown -R nginx.nginx /var/www/webvirtmgr/
生成密鑰
首次生成直接回車,不是則Overwrite (y/n)? y 選擇覆蓋
##都是回車
[root@ c7-41 webvirtmgr]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:FBWgwlyptDF8dem65poTlImt5c1Qm63bf9Mp2WDJGSs root@c7-41
The key's randomart image is:
+---[RSA 2048]----+
| . .o+o+o |
| o=.o..o. |
| .+O.+.= |
| +.B.o o . |
| = +So . = |
| . o = E B |
| . + o +..|
| ..+ . ooo.|
| o=. ..... |
+----[SHA256]-----+
##由於這裏webvirtmgr和kvm服務部署在同一臺機器,所以這裏本地信任。如果kvm部署在其他機器,則需要更換ip
[root@ c7-41 webvirtmgr]# ssh-copy-id 10.0.0.41
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '10.0.0.41 (10.0.0.41)' can't be established.
ECDSA key fingerprint is SHA256:AxAn8ho/KqTHrRuTeSOokFBDmQK36JAdH49GlnnjoOg.
ECDSA key fingerprint is MD5:57:79:69:72:65:46:7e:04:7d:f5:55:0e:c6:44:65:70.
Are you sure you want to continue connecting (yes/no)? yes ##yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: ##123456
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '10.0.0.41'"
and check to make sure that only the key(s) you wanted were added.
端口轉發,查看
[root@ c7-41 ~]# ssh 10.0.0.41 -L localhost:8000:localhost:8000 -L localhost:6080:localhost:60
Last login: Tue May 5 11:50:04 2020 from 10.0.0.1
[root@ c7-41 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:6010 *:*
LISTEN 0 128 127.0.0.1:6080 *:*
LISTEN 0 128 127.0.0.1:8000 *:*
LISTEN 0 128 *:111 *:*
LISTEN 0 5 192.168.122.1:53 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 [::1]:25 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6080 [::]:*
LISTEN 0 128 [::1]:8000 [::]:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 128 [::]:22 [::]:*
配置nginx
[root@ c7-41 ~]# vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name localhost;
include /etc/nginx/default.d/*.conf;
location / {
root html;
index index.html index.htm;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
添加webvirtmgr.conf
[root@ c7-41 ~]# vim /etc/nginx/conf.d/webvirtmgr.conf
server {
listen 80 default_server;
server_name $hostname;
#access_log /var/log/nginx/webvirtmgr_access_log;
location /static/ {
root /var/www/webvirtmgr/webvirtmgr;
expires max;
}
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;
}
}
確保bind綁定的是本機的8000端口
[root@ c7-41 ~]# vim /var/www/webvirtmgr/conf/gunicorn.conf.py
bind = '127.0.0.1:8000'
backlog = 2048
啓動nginx
[root@ c7-41 ~]# systemctl start nginx
設置supervisor
[root@ c7-41 ~]# vim /etc/supervisord.conf
##在末尾添加
[program:webvirtmgr]
command=/usr/bin/python2 /var/www/webvirtmgr/manage.py run_gunicorn -c /var/www/webvirtmgr/conf/gunicorn.conf.py
directory=/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-console
directory=/var/www/webvirtmgr
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/webvirtmgr-console.log
redirect_stderr=true
user=nginx
啓動supervisor並設置開機自動啓動
[root@ c7-41 ~]# systemctl start supervisord
[root@ c7-41 ~]# systemctl enable supervisord
[root@ c7-41 ~]# systemctl status supervisord
配置nginx用戶
未創建nginx用戶,所以用su命令賦予它交互式登錄的權限
[root@ c7-41 ~]# su - nginx -s /bin/bash
[nginx@ c7-41 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/nginx/.ssh/id_rsa):
Created directory '/var/lib/nginx/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/lib/nginx/.ssh/id_rsa.
Your public key has been saved in /var/lib/nginx/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:yx8WDwCmUpIpg+jPDa5/6qPbxr58GIyVBb6sd40tC4A nginx@c7-41
The key's randomart image is:
+---[RSA 2048]----+
|o .+o o |
|= +o + . |
|.o..+ . |
|...=. . |
|E.Boo S o |
| .o* .+. . + |
| .ooo+ oo o . |
| .+=ooo o . |
| oBO*. . |
+----[SHA256]-----+
[nginx@ c7-41 ~]$ touch ~/.ssh/config && echo -e "StrictHostKeyChecking=no\nUserKnownHostsFile=/dev/null" >>~/.ssh/config
[nginx@ c7-41 ~]$ chmod 0600 ~/.ssh/config
[nginx@ c7-41 ~]$ ssh-copy-id [email protected]
/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/var/lib/nginx/.ssh/id_rsa.pub"
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Warning: Permanently added '10.0.0.41' (ECDSA) to the list of known hosts.
[email protected]'s password:123456
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
[nginx@ c7-41 ~]$ exit
logout
[root@ c7-41 ~]# vim /etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla
[Remote libvirt SSH access]
Identity=unix-user:root
Action=org.libvirt.unix.manage
ResultAny=yes
ResultInactive=yes
ResultActive=yes
[root@ c7-41 ~]# chown -R root.root /etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla
[root@ c7-41 ~]# systemctl restart supervisord
[root@ c7-41 ~]# systemctl restart libvirtd
kvm web界面管理
瀏覽器訪問:http://10.0.0.41
通過遠程連接軟件上傳ISO鏡像文件至存儲目錄/var/lib/libvirt/images/
[root@ c7-41 ~]# cd /var/lib/libvirt/images
[root@ c7-41 images]# ll
total 4554752
-rw-r--r-- 1 root root 4664066048 May 8 15:03 CentOS-7-x86_64-DVD-1908.iso
在web界面查看ISO鏡像文件是否存在
創建系統安裝鏡像
kvm網絡管理
實例管理
實例(虛擬機的創建)
設置在web上訪問虛擬機的密碼
虛擬機安裝
正常的虛擬機安裝過程