操做系统与虚拟化计算机的发展计算机基础CPUCPU总线类型I/OOS系统调优概述调优工具CPU优化CPU亲和型调度策略中断请求内存调优虚拟内存管理文件系统相关调优网络相关调优IO磁盘调度器工具查看虚拟化技术CPU虚拟化:硬件虚拟化CPU半虚拟化 (para-virtulization)Memory虚拟化I/O虚拟化两种实现方式虚拟化网络:XenXen的工做模式Xen的使用方式:Xen Grub配置xen虚拟状态:xm经常使用命令建立xen pv模式虚拟机xm的配置文件关联loop设备文件移动安装虚拟机Xen快速安装Xen 总结:磁盘映像管理工具qemu-img镜像格式libvirt磁盘和网络热插拔Xen实时迁移KVMqemu-kvm其余经常使用选项KVM虚拟网络模型qemu-imgCirrOS虚拟机迁移virtioLibvirtvirshvirt-installRHEL 虚拟化包组ESXI补充:css
12:26:50 13:10:30html
http://www.cnblogs.com/xkfz007/archive/2012/10/08/2715163.html前端
电子电路, 逻辑电路,数字电路柔和起来的芯片. 让硬件工做起来是极其困难的. 软件. 因而有了操做系统, 能够提供通用接口跟硬件打交道.node
公共功能被抽取出来叫作库, 这些向上的接口, application program interface. 只要是被开发为应用程序, 不是在内核空间所运行的程序称为, 用户态. 好比计算1+1=2的运算, 无需通过内核处理, 能够直接在CPU上面执行.python
用户态; 内核态linux
咱们须要一个用户态的接口能够通知而且与内核交互. 因而咱们有shell.ios
第一代:真空管,I/O穿孔卡片, 穿孔纸带(耗电量惊人) 1945-1955nginx
第二代:晶体管,批处理系统, 在磁带机上工做, 串行执行$$job1$$job2$$job
. 1955-1965git
Mainframe大型计算机web
Fortran:古老的编程语言(高级语言)
第三代:集成电路芯片,多道程序设计, 引入的监控程序, 在硬件上同时执行多个程序, 多个程序彼此之间互相隔离, 有个进程级的概念。(65年~80年)
进程是程序的副本, 从程序入口开始, 到程序运行结束, 期间调度都是经过监控程序来实现.
引入了监控程序,time-sharing, 分时设计系统。将CPU的运算分红了时间片
第四代:PC机。
LSI:大规模集成电路。在每平方厘米的芯片上能够继承数千个晶体管. 目前,22nm技术。
CP/M: 微机上出现的第一个操做系统. 微型计算机的控制程序,control program for micro-computer (1974)
77年: digital research(数据研究所), 重写的CP/M使得CP/M能够运行在早期intel的8080芯片上.
IBM和比尔盖茨的故事.
计算机五大部件
冯诺依曼
HD controller: 硬盘控制器. 并非直接链接到主机上. 通常经过控制机或者适配器链接到主机上.
I/O设备之间为了彼此通讯, 要经过总线的方式链接在一块儿.
若是使用星型模型, 设备之间的链接将会变得很是麻烦. CPU要给每设备提供一根线, 拓扑十分复杂.
总线的工做频率一般比较高, 数据交换能力比较强. 早期的计算机架构中, 总线并非CPU使用的瓶颈.
至今国人没法生产CPU, 指令集丑陋不堪
MMU: X86架构下内存管理单元,Memory Management Unit。主要做用是实现内存分页
CPU执行的过程:取指,解码,肯定其类型和操做树并执行 (每一个时钟周期). 必要时会取数据.
如此一来, 任何一个指令的执行都须要三个时钟周期.
第一个时钟周期取来数据, 从内存单元获取数据的时候可能还比较慢. (理想状态) .
为了保证其流畅性, 使用多级流水线的方式来工做. 取指单元取完第一个指令以后, 就去取第二个指令.
取指单元-->解码单元-->执行单元
取指单元-->
CPU访问内存的时候会先发送请求指令给内存控制器, 发送请求地址进行定址. 内存控制器在内部, 经过虚拟电路, 使CPU和访问内存地址创建起关联关系.
FSB: 前段总线的速度称为CPU和内存之间的瓶颈. (10GB/s)
AMD研发的HT技术和Intel研发的QPI技术, 将CPU和内存直接相连. 速率提高在一倍以上
CPU内部都有一些保存临时关键变量和临时数据的存储器, 这些存储器叫作CPU的寄存器.
CPU的寄存器:程序计数器和堆栈指针,程序状态字。
程序计数器记录程序的指令, 并经过堆栈指针指向下一条指令
寄存器保持跟CPU时钟同步的存储单元, 在CPU内部总线上完成通讯.
上下文切换时,CPU要将寄存器中的内容保存至内存中, 保存现场. 现场保存到内存中.即寄存器会被清空.
task struct: 一种内核使用的数据结构, 记录了当前进程的各类状态信息,其中就包括上下文现场的信息
多核心,超线程均可以提升运算能力。
进程的CPU亲原型, CPU affinity.
摩尔定律: CPU中晶体管的数量每二十四个月翻一番
超线程可使CPU在两个线程之间进行切换,在cpu中引入一个独特的相似于寄存器之类的设备来实现的.
任务管理器中看到的核心数是逻辑核心数.
3Ghz=3 * 1024^3
不论有多少颗核心, 一个进程在运行时只能使用一颗核心. 核心越多, 能够分配给更多的进程使用. 为了利用多核系统, 并行编程变得很是重要. 理想状态, 好比将400条指令分配给4个核心, 每一个核心执行100条指令. 可是很容易出现的状况就是一个执行流结束后要等待其余执行流的执行结果. 若是一个线程正在打开一个文件, 而且另外一个线程也要打开此文件, 那么另外一个线程只能处于等待状态. 因为线程之间是共享进程的文件描述符, 防止资源征用, 通常都要施加以锁机制.
资源证用的地方称之为临界区
对于linux而言,内核调用线程的时候将其看做进程
一个CPU管理两个队列, 运行队列没有完成的操做会放到过时队列中.
两者能够互置,减小了复制的操做.
内核rebalance 来从新优化Core的work load (每一秒钟). rebalance可能致使缓存没法命中.
将一个进程绑定在一个CPU核心上是为了提升其缓存命中率的
SMP:对称多处理器, 多CPU.(在多核心没法知足横向扩展的前提)
CPU Socket: CPU插槽
CPU经过总线与内存相连,用于存储.
1600MHZ是目前内存主流频率, 1866MHZ.
I/O桥. 南桥慢(ISA桥), 打印机键盘鼠标,北桥快(PCI桥)
一些高端的CPU已经直接使用专门的内存总线让CPU和内存链接通讯.
程序局部性原理
空间局部性:程序是由指令+数据组成, 一个数据被访问到, 离这个数据很近的数据也可能被访问到.
时间局部性:一个指令执行完成以后, 很快还会再次被访问到.
因为局部性原理的存在, 不管是空间仍是时间上, 咱们都要对其作缓存.
引入内存, 是一种拿时间换空间的方式.
加上缓存, 是一种用空间换时间的方式.
而对于CPU自身而言, 他所能操做的存储器只有寄存器. 本地存储单元.
磁带-->机械式硬盘-->固态硬盘-->内存-->三级缓存-->二级缓存-->一级缓存-->寄存器
缓存的n-way associate n路关联
1ns-->2ns-->4ns-->8ns-->10ns-->1ms--->10ms
二八法则,百分之二十的缓存存放于上级存储设备中
缓存的造价很是高,主频,一二级缓存大小
一级二级缓存是各物理核心专用的, 三级缓存是各物理核心共享的.
多核心共享使用CPU和三级缓存会产生资源争用的问题. 须要内存访问仲裁控制器
NUMA: null uniformed memory access. 非一致性内存访问。每颗CPU(Socket)都有独立的外部内存空间
这样一来不当紧, 若是程序从core1 复用到core3, 就会产生core3所对应的内存低智商上并无该程序的数据. 因而须要将数据从core1的内存空间复制一份到core3上.
这种机制对CPU绑定进程的方式更加迫切
缓存中的写机制
write through: 通写,从一级缓存到写入内存,才释放CPU资源
write back: 回写,写到一级缓存就通知CPU,写完成
硬盘的缓存机制同理.
每一个IO设备一般有两部分组成:
设备控制器(Controller):集成在主板上的一块芯片或一组芯片。负责从操做系统得到命令并执行
设备自己
控制器是置于I/O设备自己的或者系统的主印制电路板(一般成为主板)上的芯片组,而适配器则是一块插在主板插槽上的卡。不管如何,它们的功能都是在I/O总线和I/O设备之间传递信息
对于操做系统而言, 在驱动程序之上, 全部的硬件操做都被抽象成文件的操做. 驱动程序控制控制器转换命令操做.
真正的硬件操做是由驱动程序来完成的,而并非内核. 将操做系统的请求转换成电气信号.
驱动程序:一般应由设备生产商;位于内核中
每一个控制器都有少许的用于实现通讯的寄存器。直接集成在控制器内部
好比一个磁盘的控制器, 可能会有指定磁盘地址, 内存地址, 扇区计数, 方向(数据存储方向)等相关的寄存器. 操做系统发起的请求经过驱动转换成相应指令并放置于控制器的寄存器中, 才能完成操做.
I/O端口空间: 每一个寄存器表现为一个I/O端口(由成百上千个控制器的寄存器组成)
全部的寄存器组合成设备的I/O地址空间
I/O端口空间,16bit, 65535. 或32bit
在开机时,向主机注册申请,根据申请顺序,依次给与IO端口
I/O请求须要CPU将数据放置到内存中给某程序处理, 进程未必处于运行状态.
实现输入输出:
中断控制器通常与CPU经过某个引脚直连, 在中断到来时通知CPU. 得到通知后的CPU能够直接根据IO端口, 并激活内核并作进程切换, 这种切换称为中断切换(不一样于进程切换). 内核将正在运行的进程切换出去, 并将kernel自己运行在CPU上, kernel指挥着到响应的I/O设备上获取其中断请求, 并断定是否能完成其请求.
中断处理一般分为两部分:
理论上每一个网卡报文到达网卡都会引发CPU中断.
3 . DMA设备,Direct Memory Access.直接内存访问。硬盘网卡都具备DMA设备。是I/O设备上自带的一个具备智能型的控制芯片. CPU通知DMA设备, 能够得到总线的使用权限. (此权限同一时间只能由一个设备具备), 并通知DMA设备可使用的内存地址空间(起始地址和结束地址), 负责将设备缓冲区的内容读到内核缓冲区(完成中断的上半部). 提供出一大段连续的内存空间用于存储缓冲数据. DMA设备具备控制总线的权限, 经过CPU来协调使用. 当数据复制完成, DMA通知CPU中断上半部完成.
网卡设备都有其缓冲区, 发送缓冲, 和接受缓冲. 网卡发起中断, 通知CPU, CPU根据IO端口, 激活内核作中断切换, 内核将数据从网卡缓冲区复制到内核缓冲区(内存中的读缓冲区), 若是目标IP是本身则拆报文封装. 并根据服务端口发送给用户程序.
进程是资源分配的最小单元
CPU: 时间片,time slice. 不考虑优先级的状况下, 每一个进程在分配时间片的时候是等长的.
Memory:
内存是编指的. 变量是命名的内存空间.
CPU有寻址/编指单元, CPU字长 32位/64位, 其实是地址总线的编指.
一般硬件(X8六、ARM这类架构的机器)中断向量是放在高地址空间的,因此内核也就放在高地址空间。另外,一般状况下,低地址空间0~64MB的范围是不用的,为了捕获null异常。
OS在RAM中,处于高地址空间.
OS在ROM中,处于高地址空间. 好比Andord操做系统. 其中ROM的地址空间也会被编指
OS在RAM中,ROM存放驱动.
虚拟地址空间出现的缘由, 若是CPU有4G的编指能力, 可是实际的物理内存只有2G怎么办. 若是有多个进程同时运行, 也会产生内存地址的征用.
虚拟地址空间:实现内存地址的使用
I/O: 抽象成文件
进程:资源集合
Page Frame:页框,一般每4k为一个单位。内存使用页框做为存储单元.
地址空间: 低 ---> 高
代码段-->数据段(静态变量)-->堆(数据流 由malloc建立) -->映射的共享库-->栈(变量)
一般CPU上有一个特殊的称之为堆指针的寄存器 (stack pointer) 。在程序初始化时,该指针指向栈顶,栈顶的地址最大。CPU有特殊的指令能够将值Push到线程堆上,以及将值Pop出堆栈
Stack最经典的使用方式就是算数运算.
在现实生活中Queue的应用也很普遍,最普遍的就是排队了,”先来后到” First come first service ,以及Queue这个单词就有排队的意思。还有,好比咱们的播放器上的播放列表,咱们的数据流对象,异步的数据传输结构(文件IO,管道通信,套接字等)
进程通知CPU线性地址,CPU要查询内核中的task struck的内存映射(Page Table)并找到物理地址。
Page Table: 页表。多级映射(一级目录,二级目录,三级目录,相似ext3),映射连续地址空间与物理地址空间. 使用目录项来作映射. 每个对应关系称为一个页表项, page table entry.
CPU中的MMU组件就是用来完成页表映射的。上下文切换的时候MMU中的内容也要进行切换.
TLB: CPU与MMU之间存在缓存,CPU先查缓存,没有结果再去查找MMU-
Translate Lookback Buffer,转换后援缓存器,用于缓存页表的查询结果
64位地址的MMU转换方式是相反的, 物理地址转换成虚拟地址.
为了实现虚拟化, 早先的地址映射都是由CPU映射到HOST的地址, 而后才能映射到真是的物理地址. 通过两次映射. 如今的CPU都有两个MMU, shadow page table, 影子页表.
isolcpus=0,1隔离CPU
若是进行swap的时候, maps映射表将会发生变化. CPU会发生缺页异常. swap回内存时, 会使用新的内存区域.
Major Exception: 大异常, 当内存数据找不到时, 须要从交换空间换回时, 咱们就称之为大异常.
Minor Exception: 小异常, 当发生缺页异常的时候, 无需从硬盘上重新查找, 只须要在内存上重定向就能够找到的场景. 好比共享库.
内存常驻内存集: RSS, 只能在内存中存储, 指令, 静态变量. 数据,好比打开的文件能够交换出内存.
干净页面: 在内存中没有被修改过的页面. 修改过的页面, 都会被同步到磁盘中, 叫作脏页同步.
7200转的硬盘, 每秒钟一百次随机I/O就已经很是不错了, 固态硬盘是写,300-400, 读 500-600
因为机械臂只有一个, 因此磁盘I/O必然是串行的. I/O数量过多, 会产生阻塞, 致使CPU产生等待.
PCI-E的特定设计过的固态硬盘, 每秒钟能够达到数十万个.
cache: 读取, 命中或者未命中
buffer: 写, 如今内存中写, 再写入磁盘中
内核守护线程: ps指令加中括号的指令. 其优先级较高.
进程优先级: 1-99 数字越大优先级越高, 100-139. 一共一百四十个. 0-139.
实时进程: 内核中执行某些后台的关键性的守护线程, 其优先级较高. 通常进程分到的时间片是5ms, 不论进程是否执行完成, 都要切到其余进程中.然而, 实时进程不是这么调度的. 实时进程在执行时, 只要其未执行完毕, 则不会进行进程切换, 除非有优先级更高的进程要执行.
普通进程都是按照时间片进行分配的.
内核进行动态优先级决策.
CPU的调度队列: 每一个优先级都有一个队列. 共有140个队列. CPU时间片分配大体是这样的, 按照队列的优先级从高低依次扫描, 找到待执行进程并取出执行.
进程调度策略:
CFS: completely fair schedular 彻底公平调度器,
调度实时进程和调度用户进程的调度方法是不同的, 实时进程是按照先进先出, 或者是轮流的方法(RR)
用户进程使用的调度算法通常是CFS, 会对占用CPU时长过多的进程进行惩罚.
网络I/O. 使用特殊内存数据结构来维持每个链接.
后援队列: 当进程注册的内存的缓冲区满了, 内核会在其内存空间将新的请求接进来, 等以后再决定如何处理.
tcp链接重用机制
sar, 淘宝tsar. htop, dstat, glances, vmstat, netperf, iftop
重量级: systemtap, oprofile, perf, valgrind(内存级别的性能分析公爵)(开发级别的工具)
systemtap: 是一个跟踪和探测工具, 可让用户监控并分析操做系统活动(特别是内核活动)的细节, 它提供相似netstat, top, ps 和iostat等工具的输出结果, 但包含为所收集信息的额外过滤和分析选项.
CPU掩码, 最高位对应最后一个逻辑CPU. 0x00000001表明处理器0, 0x00000003表明处理器0和1.
taskset -p mask pid taskset -c 0,5,7 -- program taskset -pc 2 2480 taskset -c 1,2 nginx
taskset能够控制CPU的亲原型, 可是在numa架构下, 也很难保证, CPU所访问的数据是在其对应的内存空间的.
/sys/devices/system/cpu目录中包含有关系统CPU是如何链接的信息.
/sys 目录下通常保存跟硬件驱动相关的信息
/proc 内核运行属性相关
numactl --show --hardware --membind 只从指定节点分配内存.
两三万的服务器都不支持numa体系结构, 多个物理CPU, 并有多个内存控制器
实时策略
SCHED_FIFO: 静态优先级调度, 根据程序优先权顺序扫描SCHED_FIFO线程列表. 这个线程会运行到它阻断,推出或者被更高的线程枪战准备运行的时候. 其优先级高于非实时线程
SCHED_RR:论调的调度. 有相同优先级的线程使用特定仲裁或者时间片以轮询的方式进行调度.
chrt 修改实时优先级属性, 默认是用RR
chrt [options] <policy> <priority> {<pid> | <command> [<arg> ...]} chrt -f 3 service nginx start
通常调度策略
SCHED_OTHER: 默认调度策略, 该策略使用彻底公平调度程序(CFS). CFS创建了动态优先权列表, 部分是根据每一个进程线程的niceness值.
SCHED_IDLE: 首先用于低优先权任务, 优先级很是低的任务.
SCHED_BATCH: 也是用于低优先权任务.
/proc/interrupts
IRQ是用于服务的请求, 在硬件层发出, 可以使用专用硬件线路或跨硬件总线的信息数据包(消息信号中断, MSI)发出中断.
启用中断后, 接受IRQ后会提示切换到中断上下文. 内核中断调度代码会搜索IRQ号码及其关联的注册中断服务路由(ISR)列表, 并按顺序调用ISR.
man 5 proc
中断亲原性
grep eth0 /proc/interrupts cat /proc/irq/19/smp_affinity 00000000,00000000,00000000,00000008
TLB: 转义后援缓冲器, CPU缓存级别. 条目很是的少
MMU是分级的, 相似于目录结构, 便于遍历.
对于吃内存的进程, 一般使用大内存页的方式. 超大页面必须在引导时分配, 而且他们很难手动管理.
THP: 透明大页面, 自动建立, 管理和使用超大页面.
Varnish跟THP不兼容.
容量调节
位于/proc/sys/vm/
overcommit_memory: 规定决定是否接受超大内存的请求, 是否能够超出物理内存的大小. OOM kill: Out Of Memory. 坏蛋评分, 内核决定. 优先kill坏蛋评分高的.
0 . 默认设置, 内核执行启发式内存过量使用处理. 计算方式通常是, 物理内存加交换内存.
1 . 无内存过量使用处理. 使用这个设置会增大内存超载的可能性
2 . 内存拒绝等于或者大于总可用swap大小及overcommit_ratio指定的物理RAM比例的内存请求.
eg. 4G物理内存+4G交换内存. swap + memory* overcommit_ratio, 此处最多可使用6G内存
比较理想, 可是若是有4G物理内存, 8G交换内存. 则, 此处可使用8G内存, 显然并非合理.
max_map_count: 规定某个进程可能使用的最大内存映射区域. 默认为65530, 映射文件数. Mmap, 将磁盘的文件直接映射到内存地址空间, 像使用内存同样使用磁盘上的数据.减小I/O, 从磁盘copy文件到内存的时间.
nr_hugepages: 规定在内核中配置的超大页数. 默认为0. 只有当系统中有足够的连续可用页时, 方可分配超大页.
sysctl -w vm.nr_hugepages=20
MySQL的配置变量中能够设置容许使用大内存页.
清楚缓存和缓冲
清buffer sync 清cache echo 1 >/proc/sys/vm/drop_caches
容量相关可调参数, 位于/proc/sys/kernel/目录中
msgmax: 以字节为单位规定信息队列中任意信息的最大容许大小. 这个值必定不能超过该队列的大小(msgmnb), 默认为65536
msgnmb: 信息队列的最大值. 默认是65535
msgmni: 规定信息队列识别符的最大数量. 64位 为1985, 32位为1736
shmall: 以字节为单位规定一次在系统中可使用的共享内存总量. 64位 4294967296; 32位 268435456
shmmax: 以字节为单位规定内核可容许的最大共享内存片断. 64位68719476736, 32位4294967295
shmmi: 规定系统范围内最大共享内存片断. 默认为4096
threads-max: 规定内核使用的最大线程. max_threads = mempages/(8*Thread_size/Page_Size)
文件系统相关参数, 位于/proc/sys/fs/目录
aio-max-nr: 规定在全部活动异步I/O上下文中可容许的最多事件数.
file-max: 列出内核分配的文件句柄最大值. (mempages*(Page_size/1024))/10或者NR_FILE
Out-of-Memory Kill 可调参数:
若是将/proc/sys/vm/panic_on_oom参数设定为0, 会让内核在出现OOM时调用oom_killer功能.
oom_adj: 定义-16到15之间的一个数值以便帮助决定某个进程的oom_score. oom_score值越高, 被oom_killer杀死的进程数就会越多.
位于/proc/sys/vm/下
zoned buddy allocator: 防止内存外碎片, 将大量的离散内存合并成连续的内存.
/proc/buddyinfo
slab allocator: 小内存空间的分配. 有固定个数. 防止内存内碎片
/proc/slabinfo
16M DMA使用 --> 896M 内核使用 --> 预留区域
zoneDMA zoneNormal 大于1G的地址空间, 经过映射的方式访问(zone high memory)
PAE: 物理地址扩展(Physical Address Extension) 多了四根线, 可寻址范围为64G
64位系统: DMA能够寻址1G的空间, 剩余空间为normal段
swappiness: 控制系统swap的程序. 高数值可优先系统性能, 在进程不活跃时,主动将其转出物理内存. 低数值可优先互动性尽可能避免将进程转换出物理内存. 表明一种倾向性, 默认值为60
dirty_ratio: 规定百分比值, 当脏数据组成达到系统内存总数的百分比值后开始写脏数据(pdflush), 默认为20(单个进程)
dirty_backgroud_ratio: 当脏数据组成达到系统内存总数的百分比后,开始在后端写下脏数据(pdflush), 默认为百分之10. (系统级别)
vm.dirty_expire_centisescs: pdflush守护进程被唤醒刷写数据的时间
vm.dirty_writeback_centisecs: 一个数据成为脏数据多久之后被刷写到磁盘.
刷写脏页的方法
1 . sync
2 . fsync system call
3 . echo s > /proc/sysrq-trigger
drop_caches: 让内存放弃各类缓存页和slab缓存的各类组合
1 . 系统释放全部页缓冲内存. 能够理解为free指令中显示的cache
2 . 系统全部未使用的slab缓冲内存. 能够理解为free指令中显示的buffer
3 . 系统释放全部也缓存和slab缓冲内存.
Barriers: 写入barrier是保证在永久存储中正确写入并排列文件系统元数据的内核机制. 即便在存储设备会常常断电的状况下也不例外. 只对非回写的机制有意义.
挂载文件系统时, 可提高文件系统性能:
nobarrier: barrier一般只对write back机制有意义
noatime: noatime包含nodiratime
nodiratime:
EXT4: 支持到最大文件系统为16TB, 单一最大文件为16TB
XFS: 另外一种可伸缩性文件系统, 没有文件大小的限制. 性能自己也很是不错
Socket buffer: 1. tcp_rmem 2. tcp wmem
网络接收器路径图表
NIC hardware buffer --> hard IRQ --> soft IRQ --> app socket queue <--- application
网络优化参数:
net.ipv4.tcp_max_tw_buckets: timewait的数量, 默认为8192
net.ip4.ip_local_port_range = 1024 65000: 容许系统打开的端口玩味, 前者为下面, 后面的数字为上限: 默认为32768 61000; 此范围决定了最后timewait状态的链接的数量, 下面的两项可有效下降tw状态链接的数量. (前端代理服务器通常应该修改)
net.ipv4.tcp_tw_recycle = {0|1}: 是否启用timewait快速回收, 注意, 开启此功能在NAT环境下可能会出现严重的问题, 由于TCP有一种行为, 它能够缓存每一个链接最新的时间戳, 后续请求中若是时间戳小于缓存中的时间戳, 即被视为无效并丢弃响应的请求报文.
net.ipv4.tcp_tw_reuse = {0|1}: 是否启用tw重用, 便是否容许将TIME-WAIT sockets用户新的TCP链接
net.ipv4.tcp_syncookies = {0|1}: 是否开启SYN Cookies, 即当SYN等待队列溢出时, 是否启用cookies功能.
net.ipv4.tcp_timestamps = 0 tcp报文时间戳, 关闭时能够避免序列号的卷绕. 缘由是当tcp_tw_recycle/tcp_timestamps都开启的条件下, 60s(timewait)时间内, 同一源ip的主机socket connect请求中的timestamp必须是递减的.
net.ipv4.tcp_max_syn_backlog = 262144: 保存的那些还没有收到客户端确认信息的链接请求的最大值: 默认为128, 能够增大此值.
net.ipv4.tcp_synack_retries = #: 为了打开对端的链接, 内核须要发送一个SYN并附带一个回应前面一个SYN的ACK, 这也即所谓三次握手中的第二次; 这个设置决定了内核放弃链接以前SYN+ACK的数量, 繁忙的服务器上建议设置为0或者1;
net.ipv4.tcp_syn_retries = #: 在内核放弃创建链接以前发送SYN包的数量, 繁忙的服务器应该设置为0或1.
net.ipv4.tcp_max_orphans = 262144: 系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上, 若是超过这个数字, 孤儿链接将即刻被复位并打印出警告信息, 这个限制仅仅是为了防止简单的Dos攻击, 不能过度依靠它或者认为的减小这个值, 若是须要修改, 在确保有足弓内存可用的前提下, 应该增大此值.
net.ipv4.tcp_fin_timeout = 5: 若是套接字由本段要求关闭, 这个参数决定了它保持在FIN-WAIT-2状态的时间, 缺省值为60秒. 然而, 对端可能会出错或者意外宕机并永远不关闭链接. 即便你的机器是一个轻载的WEB服务器, 也有由于大量的死套接字而内存溢出的风险, FIN-WAIT-2的危险性比FIN-WAI-1要小, 由于每一个链接最多只能消耗1.5k内存, 可是他们的生存期长些.
tcp.ipv4.tcp_keepalive_time = 30:当keepalive启用的时候, TCP发送keepalive消息的额度, 默认为2小时(7200).
net.core.rmem_max=8388608: 定义内核用于全部类型的链接的最大接受缓冲大小.
net.core.rmem_default=65536: 定义内核用于全部类型的链接的默认接收缓冲大小.
net.core.wmem_max=8388608: 定义内核用于全部类型的链接的最大发送缓冲大小
net.core.wmem_default=65536: 定义内核用于全部类型的链接的默认发送缓存大小
net.ipv4.tcp_mem='8388608 8388608 8388608' 定义TCP协议栈使用的内存空间, 分别为最小值, 默认值和最大值
net.ipv4.tcp_rmem='4096 87380 8388608': 定义TCP协议栈用于接收换种的内存空间: 第一个值为最小值, 即使当前主机内存空间吃紧, 也得保证TCP协议栈至少有此大小的空间可用, 第二个值为默认值, 他会覆盖net.core.rmem_default中为全部协议定义的接收缓冲的大小, 第三值为最大值, 即能用于TCP接收缓冲的最大内存空间.
net.ipv4.tcp_wmem='4096 65536 8388608'
CFQ尝试根据启动I/O的进程决定公平的I/O调度. 可提供三个不一样的调度等级: 实时(RT), 最佳效果(BE)和闲置. 可使用ionice命令手动分配调度等级.
在最新的内核版本和发行版中,都选择CFQ作为默认的I/O调度器,对于通用的服务器也是最好的选择.
CFQ赋予I/O请求一个优先级,而I/O优先级请求独立于进程优先级,高优先级进程的读写不能自动地继承高的I/O优先级.
CFQ为每一个进程/线程单首创建一个队列来管理该进程所产生的请求,也就是说每一个进程一个队列,各队列之间的调度使用时间片来调度,以此来保证每一个进程都能被很好的分配到I/O带宽.I/O调度器每次执行一个进程的4次请求.
只有CFQ调度算法可使用ionice更改类型和优先级
有八个调度等级, 0表明最高优先级, 7表明最低优先级. 默认等级为4.
eg. 采用cfg的实时调度, 优先级为7
ionice -c1 -n7 -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300&
采用缺省的磁盘I/O调度, 优先级为3
ionice -c2 -n3 -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300&
采用空闲的磁盘调度, 优先级为0
ionice -c3 -n0 -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300&
ionice的三种调度方法,实时调度最高,其次是缺省的I/O调度,最后是空闲的磁盘调度.
/sys/block/sda/queue/scheduler 调度器
noop: 电梯调度算法. NOOP实现了一个FIFO队列,它像电梯的工做主法同样对I/O请求进行组织,当有一个新的请求到来时,它将请求合并到最近的请求以后,以此来保证请求同一介质. NOOP倾向饿死读而利于写. 内核2.4以前的惟一算法
电梯算法饿死读请求的解释:由于写请求比读请求更容易.
写请求经过文件系统cache,不须要等一次写完成,就能够开始下一次写操做,写请求经过合并,堆积到I/O队列中.
读请求须要等到它前面全部的读操做完成,才能进行下一次读操做.在读操做之间有几毫秒时间,而写请求在这之间就到来,饿死了后面的读请求.
deadline: 会优先响应到期的I/O请求, 读的响应时间一般较短.
经过时间以及硬盘区域进行分类,这个分类和合并要求相似于noop的调度程序.
Deadline确保了在一个截止时间内服务请求,这个截止时间是可调整的,而默认读期限短于写期限.这样就防止了写操做由于不能被读取而饿死的现象.
Deadline对数据库环境(ORACLE RAC,MYSQL等)是最好的选择.
RAID芯片也可能有本身的调度算法
永久修改I/O调度
修改内核引导参数,加入elevator=调度程序名
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet
查看统计数据
ethtool -S ethx
dstat
iostat
sar
tsar
也能够监测流量
iostat
iftop
监测流量
lsof
glances
能够工做在C/S模式下
server端
glances -s -B 192.168.48.130
client端
glances -c 192.168.48.130
若是安装了 python-jinja2
能够glances -o HTML -f /var/www/html
可使用浏览器访问: http://ip/glances.html
起始于上个世纪70年代的IBM公司.
PC机的出现, 使虚拟化技术变得不那么重要.
CPU自己就是被抽象成时间片了, 这就是CPU虚拟化的基础.
Host: 宿主机
Guest: 虚拟机
模拟实现
虚拟机CPU是软件模拟,纯软件实现,特权指令是向host请求。
BT技术:Binary Translation 二进制翻译技术。运行时翻译,大大的提升了性能 (vmware)
BT技术的前提就是虚拟架构与底层物理架构相同. 使用这种方式的转换时, 虚拟机的用户空间运行在Ring3, 虚拟机的内核空间运行在Ring1, 宿主机的内核空间运行在Ring0
模拟:emulation,软件模拟。模拟ring 0~3
虚拟:virtulization 架构要相同,仅仅须要模拟ring0
彻底虚拟化,宿主机彻底虚拟出来一个虚拟平台,guest自己并不清楚本身是虚拟化出来的。
HVM: Hardware assistant Virtualization Machine
让CPU具备了五个环,多了一个-1环。虚拟机运行在环-1,环-1是虚拟机的根环
ring -1是特权指令环。
Host运行在ring -1上,虚拟机的内核运行在ring 0上
ring -1 能够捕获ring 0上的指令。
这种虚拟化技术能够达到硬件性能的百分之八十五以上
各guest的内核明确知道本身运行在虚拟化环境中, 他会向宿主机内核发起调用.
vm monitor = hypervisor 虚拟机监视器
hypervisor直接管理硬件(CPU和内存,通常不包括I/O),至关于内核
hyper call: 直接调用而非翻译
虚拟机的内核要被修改,让其内核知道此种调用机制。
这种虚拟化能够达到硬件性能的百分之九十以上
两次地址空间转换, 第一次转换成内核的虚拟拿到的连续的地址空间, 第二次从内核的虚拟空间转换至实际的物理地址空间(第二次转换是软件模拟)
进程:线性地址空间
内核:物理地址空间
Hypervisor: 虚拟连续地址空间转换成物理地址空间。Shadow page table, 影子列表的方式(一种模拟方式)。TLB难以命中,物理地址不重叠,为防止混淆,每次guest切换时,将会清空TLB缓存。
因而乎:
虚拟MMU
Intel:EPT, extend page table 扩展的页表技术
AMD: NTP, Nested Page Table 嵌套的页表技术
GVA: 虚拟机的虚拟地址
GPA: 虚拟机的物理地址
HPA: 宿主机的物理地址
GVA经过MMU虚拟化直接向Hypervisor转换成HPA, 须要硬件支持.
TLB 虚拟化
tagged TLB技术
打标签GVA到HPA的标记内容
外存:硬盘,光盘,软盘,u盘
网络设备:网卡
显示设备:VGA frame buffer机制
键盘鼠标:ps/2, usb
I/O虚拟化的方式:
IO Stack: 多个虚拟机将I/O排队
键盘和鼠标都是使用焦点捕获的方式, 将模拟设备和物理设备关联的方式
IOMMU, IO内存管理单元. 硬件要支持IO透传技术例如intel的VT-d
Intel: VT-d 基于北桥芯片的硬件辅助虚拟化技术,提升I/O可靠性,灵活性以及性能的。
DMA对传统的x86架构而言是集中式的, 让多个虚拟机直接使用某块网卡时, 会产生混淆.
IO中断: 可编程控制器, DMA.
DMA自己直接访问虚拟机的连续内存空间(GPA), 中间也要通过屡次转换. 而且要考虑缓冲的问题. 实现机制很是复杂
Type-II型:操做系统基础上安装虚拟化软件再建立各类主机
Type-I型:基于Hypervisor
Xen,vmware ESX/ESXI 属于Type-I型
VMware workstation/virtualbox/KVM 属于Type-II型
Intel硬件辅助虚拟化
第一类:跟处理器相关:vt-x
第二类:跟芯片相关:vt-d
第三类:跟I/O相关,VMDq和SR-IOV
模拟器PearPC, Bochs, QEMU
彻底虚拟化:VMware Worksation, VMware Server, Parallels Desktop, KVM, Xen(HVM环境中)
半虚拟化:Hyper call ABI. 虚拟机的内核通过修改。xen, uml (user-mode linux)
OS级别的虚拟化:OpenVZ, lxc. Solaris Containers. FreeBSD jails
库虚拟化:wine,
应用程序虚拟化:jvm
SDN:software defined network
Bridge方式:原物理网卡被作成交换机,而后模拟一个bridge设备出来。至关于两台交换机,一台虚拟出来的. 网卡工做在混杂模式, 不管是否是本机的IP都进行转发.
host-only: 仅主机模式,须要使用路由
NAT mode: 隐藏虚拟机.
TUN与TAP
在计算机网络中, TUN与TAP是操做系统内核中的虚拟网络设备, 不一样于普通硬件网络板卡实现的设备, 这些虚拟的网络设备所有用软件实现, 并向运行于操做系统的软件提供与硬件的网络设备彻底相同的功能.
TAP等同于一个以太网设备, 它操做第二层数据包如以太网数据帧. TUN模拟了网络设备, 操做第三层数据包好比IP数据封包.
操做系统经过TUN/TAP设备向绑定改设备的用户空间的程序发送数据, 反之, 用户空间的程序也能够像操做硬件网络设备那样, 经过TUN/TAP设备发送数据. 在后者状况下, TUN/TAP设备向操做系统的网络栈投递数据包, 从而模拟从外部接受数据的过程.
通常虚拟机不提供桥接模式,须要本身配置
为了作桥接模式的配置,应当关闭NetworkManager(network manager 不支持)
真正的桥功能是经过内核的TAP/TUN实现的. bridge-utils只是修改工具
yum install bridge-utils Device=br0 TYPE=Bridge NM_CONTROLLED=no
修改原eth0网卡
BRIDGE=br0
查看网桥状态
brctl show
使用brctl的配置过程:
brctl addbr br0 brctl stp br0 on ifconfig eth0 0 up brctl addif br0 eth0 ifconfig br0 IP/NETMASK up route add default gw GW
Ian Pratt, Keir Fraser. 两人研发.
Xen直接跑在硬件上. 须要预装Xen Hypervisor
核心问题是如何驱动各类I/O设备
Xen Hypervisor 自己只能虚拟化CPU,MMU进行管理
Domain是Xen虚拟机单元, domain是从0开始编号.
Dom0是第一台虚拟机,又称特权域. 能够直接使用硬件的驱动.
Dom0提供Xen console, 而且给DomU提供I/O各类驱动
DomU对于I/O设备的使用,仅仅是前端。
Dom0的内核必须作修改,能够直接调用Hyper Call. DomU也须要直接调用Hyper Call. 进程管理和内存使用, 以及中断部分都须要修改内核.
2.6.37以后的kernel代码已经直接整合全部Dom0所须要的功能
2.6.24+: DomU的内核部分已经被直接整合进内核中
Linux 3.0+ 以后对Xen作了专门的优化
CPU/Memory/中断经过Hypervisor, 可是对I/O的调用须要经过Dom0
4.2 以后版本使用XL
4.1 以前的版本使用XM,启用xm工具必须启动xend进程
目前Xen已经到4.4版本了
半虚拟化: grep -E ‘pae’ /proc/cpuinfo
全虚拟化: grep -E ‘svm|vmx’ /proc/cpuinfo
xen hypervisor
Xenserver:
citrix收购
使用XE/XAPI管理组件
XCP: Xen Cloud Platform
工具栈:xm/xend, xl, xapi/xe
通用工具栈:libvirt vrish/libvirtd, virtmanager(红帽开发)
wiki.xenproject.org
GlusterFS
centos在xen4.2开始支持使用xen.
红帽早在RHEL5就提供的xen的从新编译的内核, 2008年红帽收购了KVM. RHEL5.6 尝试引入KVM, 5.8 的时候开始取代Xen. 从RHEL6开始, 再也不支持Xen. 此时的Redhat能够运行在domU上.
安装镜像http://vault.centos.org/6.7/xen4/x86_64/
http://mirrors.163.com/centos/6.8/virt/x86_64/xen-44/
#boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title Red Hat Enterprise Linux Server (3.7.4-1.el6xen.x86_64) root (hd0,0) kernel /xen.gz dom0_mem=1024M cpufreq=xen dom0_max_vcpus=2 dom0_vcpus_pin module /vmlinuz-3.7.4-1.el6xen.x86_64 ro root=/dev/mapper/vg0-root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg0/swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_NO_DM KEYBOARDTYPE=pc KEYTABLE=us rd_LVM_LV=vg0/root rhgb quiet module /initramfs-3.7.4-1.el6xen.x86_64.img title Red Hat Enterprise Linux (2.6.32-279.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-279.el6.x86_64 ro root=/dev/mapper/vg0-root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg0/swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_NO_DM KEYBOARDTYPE=pc KEYTABLE=us rd_LVM_LV=vg0/root rhgb quiet initrd /initramfs-2.6.32-279.el6.x86_64.img
Avaya的dom0使用Xen 4.1
若是要使用xm,要确保xend服务启动
xm info xl info
Dom0的ID永远为0
r: 运行状态
b: I/O阻塞状态
p: 暂停(暂停在内存中,资源不释放)
s: 中止
c: 崩溃. crashed
d: dying,当前域开始关机
Time(s):占据CPU并使用于运行时间的时长
Destory: 关闭电源
Delete:删除虚拟机
create: 建立虚拟机 -c 表示打开控制台
destory: 关闭虚拟机电源
new: 添加到xend domain
delete: 删除
start: 开机一个域
shutdown: shutdown -h now
vcpu-list: 各虚拟机虚拟CPU状态
前提
DOMU内核借用DOM0内核
磁盘建立
建立稀疏格式的磁盘
dd if=/dev/zero of=centos6.img bs=1M oflag=direct seek=1023 count=1 dd if=/dev/zero of=/xen/vm/test.img oflag=direct count=120000 bs=1M count=1 seek=119999
1023直接被跳过
mount -o loop centos6.img /mnt cd /mnt;mkdir -pv etc/{init,rc.d} bin sbin lib64 dev proc sys tmp var home root
Kernel:内核
ramdisk: initramfs或initrd文件
name: 域名称
memory:内存大小
disk: 磁盘设备文件列表,格式disk = ["disk1","disk2",]。
每一个disk都由三个参数来定义
“Backend-dev": 有两种类型,物理设备,虚拟磁盘映像文件,格式分别为:
Frontend-dev: 定义其在DomU中的设备类型;虚拟磁盘映像文件对应的设备文件名一般为xvd[a-z],tr一般只能模拟IDE插槽,并不能模拟scssi设备
mode: 访问权限模型:r,w
vcpus: 虚拟CPU的个数,默认为1
root: 根文件系统路径, 指所在的设备
extra: 传递给内核的额外参数, selinux=0
on_reboot: 执行xm reboot命令时的操做,有destory和restart
on_crash: 有destory, restart,preserve(保存系统崩溃时的映像信息)
on_shutdown:
vif = ['ip=172.16.100.11',bridge=br0']
bootloader: 引导器文件的路径,通常指PyGrub的路径:
cpu: 指定在某颗物理CPU上启动
cpus: 指定当前域的VCPU能够在那些物理CPU上运行
research一下为什么没法启动此操做系统
kernel = "/tmp/vmlinuz" ramdisk = "/tmp/initramfs" memory = 512 name = "centos6_vm" vcpus = 2 disk = [ 'file:/xen/vm1/test.img,xvda,w' ] root = "/dev/xvda2 ro" extra = "3 selinux=0"
查找最小的未被使用的loop设备
losetup -f
使用镜像文件跟loop设备作关联
losetup /dev/loop0 /xen/vm1/test.img
而后就能够对loop0进行分区
fdisk /dev/loop0 kpartx -av /xen/vm1/test.img
随后磁盘映射文件会在/dev/mapper中显示
光盘安装使用的是isolinux下引导
将isolinux下的vmlinuz以及initrd.img文件cp出来
而后在虚拟机配置中设定kernel以及initrd
在安装完成以后,将kernel以及initrd内容取消,而后添加bootloader = /usr/bin/pygrub
#ramdisk="/boot/initramfs-2.6.32-358.el6.x86_64.img" #kernel="/boot/vmlinuz-2.6.32-358.el6.x86_64" name="linux" vcpus=1 memory=128 disk=['file:/xen/vm2/dom2.img,xvda,w',] bootloader="/usr/bin/pygrub" #root="/dev/xvda2 ro" #extra="selinux=0 init=/sbin/init" vif=[ 'bridge=br0' ] on_crash="destroy" on_reboot="restart"
安装时要添加kernel 和 initrd
reset
重置窗口大小
yum install centos-release-xen -y yum install xen -y yum update -y
pv:
启动一个虚拟机实例,内核和initramfs文件能够放置在Dom0,也可由本身的文件系统提供
第一种:配置文件,由xm/xl等管理工具来提供的引导过程
kernel = ramdisk = root = extra =
第二种:须要一个bootloader,pygrub
bootloader =
xm基于某过程引导安装过程:
isolinux:
vmlinuz
initrd.img
note:通常在半虚拟化的环境中,通常使用url方式来安装
在PV模式中运行guest系统,须要知足几个基本前提。
◇ 能运行于Xen DomU的(Xen-enabled)内核:Liunx 2.6.24及之后的内核已经添加了对Xen DomU的支持,所以,只要在内核编译时启用了相应的功能就能知足此要求,目前多数Linux发行版的内核都已经支持此特性;而此前的版本须要内核在编译前手动打补丁方可;
◇ 根文件系统(Root Filesystem):包含了应用程序、系统组件及配置文件等运行DomU的各类所须要文件的文件系统,其不用非得包含内核及对应的ramdisk,后面的这些组件放在Dom0中便可;事实上,用于DomU的内核文件必需要可以容许Dom0访问到,由于其运行时须要与Xen Hypervisor通讯,所以,这些内核组件能够位于Dom0可以访问到的任何文件系统上;然而,目前基于pygrub(可用于Dom0跟非特权域磁盘映像中的内核通讯),此内核文件也能够直接放置于非特权域的磁盘映像中;
◇ DomU内核所须要的内核模块:内核模块是内核的重要组成部分,它们通常存储于根文件系统;
◇ ramdisk或者ramfs:这个根据实际须要是个可选组件,若是在内核初始化过程当中不须要依赖于此来装载额外的驱动程序以访问根文件系统则也能够不用提供;
◇ swap设备:交换分区可以让Linux运行比仅有物理内存时更多的进程,所以,提供此组件是常见的作法;固然,它是可选的;
◇ DomU配置文件:集中在一块儿指定前述各组件的配置信息,以及定义其它有关PV DomU的基本属性的文件;其一般包含全部用于当前DomU属性配置参数,包括为其指定磁盘映像和内核文件的位置(或pygrub的位置)等,以及其它许多属性如当前DomU能够访问的设备等,这些设备包括网络设备、硬盘、显卡及其它PCI设备;同时,配置文件中也能够指定新建立的非特权域可使用的物理内存大小及虚拟CPU个数等等;
这里须要提醒的是,若是计划为PV DomU编译内核,须要以与传统方式不一样的方式放置内核及其模块。前面也已经提到,内核通常会放在Dom0的某路径下,而内核模块则须要放在DomU的根文件系统上。
PV DomU的根文件系统能够以多种不一样的方式进行安置,好比:
◇ 虚拟磁盘映像文件
◇ Dom0没有使用的额外物理磁盘分区
◇ Dom0没有使用的逻辑卷
◇ 块级别网络文件系统,如iSCSI设备
◇ 网络文件系统,如NFS
vfb:vnc或sd1,是一种c/s架构
安装vnc server
yum install tigervnc-server
启动vnc server
vncserver :1
VNC协议是明文的, 并不安全
vfb=[ 'vnc=1,vnclisten=0.0.0.0' ] 直接使用当前窗口打开另外一个窗口 vfb=[ 'vnc1,sdl=1']
帧缓冲:提供图形化界面
查看某种format的格式选项
qemu-img create -f qcow2 -o ? /xen/vm/test.img qemu-img create -f qcow2 -o size=120G,preallocation=metadata /xen/vm/centos.qcow2
raw: the raw format is a plain binary image of the disc image, and is very portable.
追加磁盘大小
dd if=/dev/zero of=zeros.raw bs=1024k count=4096 cat foresight.img zeros.raw > new-foresight.img
cow: copy on write
qcow: 同cow都是历史的弃婴
qcow2: QEMU copy-on-write format with a range of special features, including the ability to take multiple snapshots.
性能接近raw, 支持快照, 支持AES加密, 支持zlib磁盘压缩等
vmdk: vmware支持的虚拟化镜像格式. OVF的同一封包. 性能和功能上来讲vmdk都是目前比较出色的.
virsh
virt-viewer: python开发, 显示工具
virt-manager: python开发, 图形化配置文件
virt-install: 自动建立映像文件, 命令行工具
Redhat在RHEL6中有意的将libvirt对xen的支持的部分没有编译
service libvirt strat以后, 会自动建立一个virbr0的虚拟网桥
virt-install -n "centos6.7" -r 512 --vcpus=2 =l http://192.168.48.130/cobbler/ks_mirror/centos-6.7-x86_64 -disk path=/xem/vm/test.img --network bridge=br0 --force
xm block-attach centos6 file:/xen/vm1/test.qcow2 xvdb w
挂起虚拟机
xm save centos /tmp/centos.save
恢复虚拟机
xm restore /tmp/centos.save
暂停在内存中
xm pause/unpause
若是虚拟机被xend彻底管理, 则可使用suspend/resume
grep xend-relocation /etc/xen/xend-config.sxp |grep -v '#'
(xend-relocation-server yes)
(xend-relocation-port 8002)
(xend-relocation-address '')
(xend-relocation-hosts-allow '')
xm migrate [domu]
KVM: Kernel-based Virutal Machine
Popek, Globerg.提出了经典虚拟化的三个条件
1 . 等价执行
2 . 性能良好
3 . 安全隔离
以色列Qumranet公司 2008年之后被Redhat收购
KVM仅仅是kernel上的一个模块
相似寄存的方式, 将内核变成hypervisor.
I/O 经过qemu来模拟实现
note: KVM要求硬件必须支持HVM
加载KVM模块
modprobe kvm modprobe kvm-intel
qemu-kvm 专用于结合kvm使用的管理工具
模式: 内核模式, 用户模式, 来宾模式
来宾模式: guest mode, 虚拟机上的用户空间.
vCPU是经过线程来模拟实现CPU
KVM组件:
核心组件: /dev/kvm. 管理虚拟机的设备节点. 用户控件的程序可经过isctl()系统调用来对虚拟机的建立启动等管理工做. 1. 为虚拟机分配内存; 2 . 读, 写VCPU的寄存器. 3 .向vCPU注入中断; 4 . 运行vCPU;
qemu组件: qemu进程, 工做于用户空间的组件, 用于仿真PC机的I/O类硬件设备.
KVM必须使用HVM
egrep -i "vmx|svm" /proc/cpuinfo
qemu-kvm的标准选项涉及指定主机类型, CPU模式, NUMA, 软驱设备, 光驱设备以及硬件设备
◇ -name name:设定虚拟机名称; ◇ -M machine:指定要模拟的主机类型,如Standard PC、ISA-only PC或Intel-Mac等,可使用“qemu-kvm -M ?”获取所支持的全部类型; ◇ -m megs:设定虚拟机的RAM大小; ◇ -cpu model:设定CPU模型,如coreduo、qemu64等,可使用“qemu-kvm -cpu ?”获取所支持的全部模型; ◇ -smp n[,cores=cores][,threads=threads][,sockets=sockets][,maxcpus=maxcpus]:设定模拟的SMP架构中CPU的个数等、每一个CPU的核心数及CPU的socket数目等;PC机上最多能够模拟255颗CPU;maxcpus用于指定热插入的CPU个数上限; ◇ -numa opts:指定模拟多节点的numa设备; ◇ -fda file ◇ -fdb file:使用指定文件(file)做为软盘镜像,file为/dev/fd0表示使用物理软驱; ◇ -hda file ◇ -hdb file ◇ -hdc file ◇ -hdd file:使用指定file做为硬盘镜像; ◇ -cdrom file:使用指定file做为CD-ROM镜像,须要注意的是-cdrom和-hdc不能同时使用;将file指定为/dev/cdrom能够直接使用物理光驱; ◇ -drive option[,option[,option[,...]]]:定义一个新的硬盘设备;可用子选项有不少。 file=/path/to/somefile:硬件映像文件路径; if=interface:指定硬盘设备所链接的接口类型,即控制器类型,如ide、scsi、sd、mtd、floppy、pflash及virtio等; index=index:设定同一种控制器类型中不一样设备的索引号,即标识号; media=media:定义介质类型为硬盘(disk)仍是光盘(cdrom); snapshot=snapshot:指定当前硬盘设备是否支持快照功能:on或off; cache=cache:定义如何使用物理机缓存来访问块数据,其可用值有none、writeback、unsafe和writethrough四个; format=format:指定映像文件的格式,具体格式可参见qemu-img命令; ◇ -boot [order=drives][,once=drives][,menu=on|off]:定义启动设备的引导次序,每种设备使用一个字符表示;不一样的架构所支持的设备及其表示字符不尽相同,在x86 PC架构上,a、b表示软驱、c表示第一块硬盘,d表示第一个光驱设备,n-p表示网络适配器;默认为硬盘设备;
eg.
qemu-kvm -name "rhel5.8" -m 512 -smp 2 -boot d -drive file=/VM/images/rhel5.8/hda,if=virtio,index=0,media=disk,format=qcow2 -drive file=/isos/rhel-5.8.iso,index=1,media=cdrom -net nic,model=virtio,macaddr=52:54:00:A5:41:1E -vga cirrus -balloon virtio
qemu-kvm -name "centos65" -m 512 -smp 2 -hda /images/vm/centos.qcow2 -cdrom CentOS-6.5-x86_64-bin-DVD1.iso -boot order=dc
动态迁移时用到的选项: -incoming tcp:0:PORT
让qemu-kvm进程运行于后台: -daemonize
开启USB总线: -usb
GuestOS为Windows时, -usb -usbdevice tablet, 用于实现鼠标定位
打开KVM的支持: -enable-kvm (qemu-kvm默认启用此选项)
打开声音设备: -soundhw
设定iscsi存储设备: -iscsi 经过URL指定使用的iscsi设备 iscsi://<target_ip>/<target_iqn>/
user=USERNAME, password=PASSWORD, initiator-name=iqn
qemu-kvm -iscsi initiator-name= -drive file=iscsi://tgt.example.com/1qn.2014-05.com.example.com.tgt1/1
指定使用bios文件: -bios /path/to/some_bios_program
使用外部内核及ramdisk文件. -kernel -initrd -append 向内核传递的参数
NAT模型: 虚拟机实例的网卡都要虚拟成hypervisor上的虚拟网络接口. -net, nic -net tap 指令hypervisor的对应关系. NAT模型中, 再在hypervisor建立一个虚拟桥, 并无绑定任何物理接口.
dnsmasq: 能够提供dns服务器以及dhcp服务器.为嵌入式平台使用, 很是轻量级.
在虚拟网桥上建立SNAT规则
iptables -t nat -A POSTROUTING -s 192.168.21.0/24 -j SNAT --to-source 192.168.48.131
路由模型: 对虚拟网桥而言, 不作NAT转换, 而是作路由功能.
隔离模型: hypervisor中的虚拟网桥并无绑定到任何一个接口上.
桥接模型: 将eth0(物理网卡做为交换机来使用), 经过桥接的方式来链接虚拟机和物理机.
多路桥接模型:
/etc/qemu-ifup
#!/bin/bash switch=virbr0 if [ -n "$1" ];then ifconfig $1 up sleep 0.5 brctl addif $switch $1 exit 0 else echo "Error: no specified interface." exit 1 fi
开启虚拟机网桥
qemu-kvm -name "rhel5" -m 512 -smp 2 -drive file=/images/vm/centos.qcow2,if=virtio,index=0 -boot order=c -net nic,model=virtio -net tap,ifname=vnet0,downscript=no
SDL: Simple DirectMedia Layer, C语言编写的简单的跨平台的, 免费开源的多媒体程序库. 操做系统硬件平台的图形,显示, 声音等.
VNC: Virtual Network Computing: 基于RFB
-vnc display的指定方式:
1 . host:N 172.16.100.7:1, 侦听于5900+N的端口上
2 . unix: /path/to/socket_file
3 . none 不启动桌面
option: password, 链接时须要验证密码, 设定密码经过monitor接口使用change
reverse: 反向
change vnc password
-monitor stdio 在标准输入输出上显示monitor界面, 至关于alt+ctrl+2
Ctrl-a, c: 在console和monitor之间切换
Ctrl-a, h: 显示帮助信息
不作图形显示 -nographic
建立qcow2的磁盘镜像文件
qemu-img create -f qcow2 -o size=20G,preallocation=metadata /images/vm2/test.qcow2
增长其大小
qemu-img resize /images/vm2/test.qcow2 40G
查看虚拟磁盘镜像文件大小
qemu-img info /images/vm2/test.qcow2
镜像文件类型进行转换
qemu-img convert -f qcow2 -O vmdk -o adapter_type=lsilogic test.qcow2 test.vmdk
建立某一虚拟镜像文件快照
qemu-img snapshot -c test-1.snmp test.qcow2
查看快照
qemu-img snapshot -l test.qcow2
应用快照
qemu-img snapshot -a test-1.snap test.qcow2
删除快照
qemu-img snapshot -d test-1.snap test.qcow2
In a CirrOS image, the login account is cirros. The password is cubswin:)
qemu-kvm -name "cirros" -smp 2 -m 512 -drive file=/root/cirros-0.3.4-x86_64-disk.img,media=disk -net tap,ifname=vnet0,downscript=no -nographic
ctrl+a ^c
info cpus info status info tlb info vnc 使用info直接查看帮助文档
保持CPU架构相同.
incoming的机制: 等待其余虚拟机实例迁移过来
hb: qemu-kvm -incoming tcp:0:6767 (0表示容许任意主机)
ha: monitor: migrate tcp:hb:6767
-cpu host 能够将宿主机的cpu类型直接给虚拟机
通用于各类虚拟化技术的半虚拟化技术. linux内核从2.6.25起直接支持了virtio.通用框架, 提升io性能.
建议建立网络设备和磁盘设备的时候都使用virtio.
工具栈实现虚拟机管理
安装系统: virt-manager, virt-install
virsh不能安装, 能够用于管理
yum -y install libvirt virt-manager virt-viewer python-virtinst
查看帮助
virsh help iface-bridge
添加网桥
virsh iface-bridge eth0 br0
virsh能够运行在交互模式下
显示子类的帮助, 好比只显示虚拟机的管理子命令
vrish# help domain
分组
domain: 虚拟机域
使用pxe引导安装虚拟机
virt-install -n "centos6" --vcpus 2 -r 512 -l http://192.168.48.130/cobbler/ks_mirror/centos-6.7-x86_64/ --disk /images/vm/centos6.qcow2,bus=virtio,size=120,sparse --network bridge=br0,model=virtio --nographics --force
dump已有的xml配置文件
virsh dumpxml centos >/etc/libvirt/qemu/cirros.xml
建立cirros利用镜像文件
virsh create /etc/libvirt/qemu/cirros.xml --console
Virtualization: qemu-kvm, qemu-guest-agent, qemu-kvm-tools
Virtualization Client: python-virtinst, virt-manager, virt-viewer, virt-top
Virtualization Platform: libvirt, libvirt-client, virt-who, virt-what
Virtualization Tools: libguestfs
hypervisor自身包含一个dom0. 混合模式的I/O驱动模型.
各VMM对于I/O的驱动, 有三种模式:
1 . 自主VMM, VMM自行提供驱动 (几乎不存在)
2 . 混合VMM, 借助于OS提供驱动.
依赖于外部OS(xen)
自我提供特权域(ESXI)
3 . 寄宿式的VMM:
I/O虚拟化模型:
1 . 纯模拟的方式实现
2 . 半虚拟化
3 . 透传: 直接是用实际的物理设备.
IOV, SR-IOV: 将一个物理硬件轮流分给多个虚拟机实例.
QEMU: 实现CPU跨平台模拟
VMM: VM monitor
VM management: 虚拟机管理器
[root@centos6 ~]# tail master_key Start Time: 1456729243 Timeout : 300 (sec) Verify return code: 19 (self signed certificate in certificate chain) --- <html><body><h1>It works!</h1></body></html> <<< TLS 1.2 Alert [length 0002], warning close_notify 01 00 closed >>> TLS 1.2 Alert [length 0002], warning close_notify 01 00