设为首页 收藏本站
查看: 2036|回复: 0

[经验分享] 虚拟化相关

[复制链接]

尚未签到

发表于 2017-6-22 09:35:16 | 显示全部楼层 |阅读模式
操作系统与虚拟化



操作系统与虚拟化计算机的发展计算机基础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补充:
  12:26:50 13:10:30
  http://www.cnblogs.com/xkfz007/archive/2012/10/08/2715163.html

计算机的发展
  电子电路, 逻辑电路,数字电路柔和起来的芯片. 让硬件工作起来是极其困难的. 软件. 于是有了操作系统, 可以提供通用接口跟硬件打交道.
  公共功能被抽取出来叫做库, 这些向上的接口, application program interface. 只要是被开发为应用程序, 不是在内核空间所运行的程序称为, 用户态. 比如计算1+1=2的运算, 无需经过内核处理, 可以直接在CPU上面执行.
  用户态; 内核态
  我们需要一个用户态的接口可以通知并且与内核交互. 于是我们有shell.
  第一代:真空管,I/O穿孔卡片, 穿孔纸带(耗电量惊人) 1945-1955
  第二代:晶体管,批处理系统, 在磁带机上工作, 串行执行$$job1$$job2$$job. 1955-1965
  ​ Mainframe大型计算机
  ​ 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和比尔盖茨的故事.

计算机基础
  计算机五大部件
  冯诺依曼


  • 存储器
  • 控制器
  • 运算器
  • Input
  • Output
  HD controller: 硬盘控制器. 并不是直接连接到主机上. 一般通过控制机或者适配器连接到主机上.
  I/O设备之间为了彼此通信, 要通过总线的方式连接在一起.
  如果使用星型模型, 设备之间的连接将会变得非常麻烦. CPU要给每设备提供一根线, 拓扑十分复杂.
  总线的工作频率通常比较高, 数据交换能力比较强. 早期的计算机架构中, 总线并不是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内部总线上完成通信.
  上下文切换时,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,写完成
  硬盘的缓存机制同理.

I/O
  每个IO设备通常有两部分组成:


  •   设备控制器(Controller):集成在主板上的一块芯片或一组芯片。负责从操作系统获得命令并执行

    • IDE:Integrated Drive Electronics, 集成驱动器电子设备
    • SATA


  •   设备本身

  控制器是置于I/O设备本身的或者系统的主印制电路板(通常成为主板)上的芯片组,而适配器则是一块插在主板插槽上的卡。无论如何,它们的功能都是在I/O总线和I/O设备之间传递信息
  对于操作系统而言, 在驱动程序之上, 所有的硬件操作都被抽象成文件的操作. 驱动程序控制控制器转换命令操作.
  真正的硬件操作是由驱动程序来完成的,而并不是内核. 将操作系统的请求转换成电气信号.
  驱动程序:通常应由设备生产商;位于内核中
  每个控制器都有少量的用于实现通信的寄存器。直接集成在控制器内部
  比如一个磁盘的控制器, 可能会有指定磁盘地址, 内存地址, 扇区计数, 方向(数据存储方向)等相关的寄存器. 操作系统发起的请求通过驱动转换成相应指令并放置于控制器的寄存器中, 才能完成操作.
  I/O端口空间: 每个寄存器表现为一个I/O端口(由成百上千个控制器的寄存器组成)
  ​ 所有的寄存器组合成设备的I/O地址空间
  ​ I/O端口空间,16bit, 65535. 或32bit
  ​ 在开机时,向主机注册申请,根据申请顺序,依次给与IO端口
  I/O请求需要CPU将数据放置到内存中给某程序处理, 进程未必处于运行状态.
  实现输入输出:


  • 轮询:忙等待. 用户程序发起一个系统调用, 内核将其翻译成一个对应设备驱动的过程调用, 设备驱动程序启动I/O, 并在一个连续不断的循环中检查该设备, 并查看该设备是否完成了操作.
  • 中断:中断CPU正在执行的操作。可编程中断控制器,中断向量是开机时获得,通过中断向量(中断号)使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是自己则拆报文封装. 并根据服务端口发送给用户程序.

OS
  进程是资源分配的最小单元
  CPU: 时间片,time slice. 不考虑优先级的情况下, 每个进程在分配时间片的时候是等长的.
  Memory:
  内存是编指的. 变量是命名的内存空间.
  CPU有寻址/编指单元, CPU字长 32位/64位, 实际上是地址总线的编指.
  通常硬件(X86、ARM这类架构的机器)中断向量是放在高地址空间的,所以内核也就放在高地址空间。另外,通常情况下,低地址空间0~64MB的范围是不用的,为了捕获null异常。
  OS在RAM中,处于高地址空间.
  OS在ROM中,处于高地址空间. 比如Andord操作系统. 其中ROM的地址空间也会被编指
  OS在RAM中,ROM存放驱动.
  虚拟地址空间出现的原因, 如果CPU有4G的编指能力, 但是实际的物理内存只有2G怎么办. 如果有多个进程同时运行, 也会产生内存地址的征用.
  虚拟地址空间:实现内存地址的使用
  I/O: 抽象成文件
  进程:资源集合


  • CPU时间
  • Memory,抽象虚拟地址空间(32bits:4G) 固定是上层3G内存,内核固定使用低端1G内存.根据程序的局部性原理, 内存地址的分配也是局部的, 只分配当前使用的一部分地址就可以.
  • I/O, 打开的多个文件,fd(文件描述符 file descriptor) 输入:0 标准输出:1 错误输出:2
  • 正常文件
  • 设备文件: 块设备, 字符设备
  • 管道文件:一个进程的输出作为另一个进程的输入所产生的文件, 由内核创建出一个虚拟文件
  • 套接字文件:
  • Task Struct:作业地址结构,内核在内核的地址空间内为每一个进程所维护的数据结构。通过链表的形式保存各种资源占用信息。维护进程的资源集.
  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亲和型
  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'

IO磁盘调度器
  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

CPU虚拟化:
  模拟:emulation,软件模拟。模拟ring 0~3
  虚拟:virtulization 架构要相同,仅仅需要模拟ring0
  ​ 完全虚拟化,宿主机完全虚拟出来一个虚拟平台,guest本身并不清楚自己是虚拟化出来的。


  • BT: 二进制翻译(软件级别)
  • HVM: 硬件辅助的虚拟化(硬件)

硬件虚拟化
  HVM: Hardware assistant Virtualization Machine
  让CPU具有了五个环,多了一个-1环。虚拟机运行在环-1,环-1是虚拟机的根环
  ring -1是特权指令环。
  Host运行在ring -1上,虚拟机的内核运行在ring 0上
  ring -1 可以捕获ring 0上的指令。
  这种虚拟化技术可以达到硬件性能的百分之八十五以上

CPU半虚拟化 (para-virtulization)
  各guest的内核明确知道自己运行在虚拟化环境中, 他会向宿主机内核发起调用.
  vm monitor = hypervisor 虚拟机监视器
  hypervisor直接管理硬件(CPU和内存,一般不包括I/O),相当于内核
  hyper call: 直接调用而非翻译
  虚拟机的内核要被修改,让其内核知道此种调用机制。
  这种虚拟化可以达到硬件性能的百分之九十以上

Memory虚拟化
  两次地址空间转换, 第一次转换成内核的虚拟拿到的连续的地址空间, 第二次从内核的虚拟空间转换至实际的物理地址空间(第二次转换是软件模拟)
  进程:线性地址空间
  内核:物理地址空间
  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的标记内容

I/O虚拟化
  外存:硬盘,光盘,软盘,u盘
  网络设备:网卡
  显示设备:VGA frame buffer机制
  键盘鼠标:ps/2, usb
  I/O虚拟化的方式:


  • 模拟: 完全使用软件来模拟真实硬件
  • 半虚拟化: I/O frontend --> I/O backend (仅适用于硬盘和网卡). 虚拟机内核明确知道自己运行在虚拟化环境中, 在本地并不使用本地驱动进行, 对设备的调用直接转换到后端.


  • IO-through:I/O透传, 直接分配物理资源给虚拟机. 仍然需要hypervisor进行协调.
  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硬件辅助虚拟化


  • CPU角度: VT-x. EPT, tagged-TLB
  • IO/CPU: VT-d, IOV, VMDq
  第一类:跟处理器相关: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
Xen
  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

Xen的工作模式


  • 半虚拟化:对CPU,I/O设备都完全执行半虚拟化, PV: para-virtualization. Xen研发的硬件, 都是基于Xen的驱动程序.
  • 全完虚拟化:依赖于CPU的HVM. 依赖QEMU.
  • PV on HVM: CPU完全虚拟化,I/O设备使用半虚拟化
  4.2 之后版本使用XL
  4.1 之前的版本使用XM,启用xm工具必须启动xend进程
  目前Xen已经到4.4版本了
  半虚拟化: grep -E ‘pae’ /proc/cpuinfo
  全虚拟化: grep -E ‘svm|vmx’ /proc/cpuinfo

Xen的使用方式:


  •   xen hypervisor

    • 硬件--->正常安装linux发行版-->编译安装xen-->修改grub配置其内核为xen,而不再使用linux内核(Linux的内核和initramfs文件当做xen的模块)-->重新编译Linux内核,使其能够运行于Dom0 -->重启系统
    • DomU: 在Dom0使用工具创建虚拟机-->启动虚拟机-->安装操作系统


  •   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/

Xen Grub配置

#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

xen虚拟状态:
  r: 运行状态
  b: I/O阻塞状态
  p: 暂停(暂停在内存中,资源不释放)
  s: 停止
  c: 崩溃. crashed
  d: dying,当前域开始关机
  Time(s):占据CPU并使用于运行时间的时长
  Destory: 关闭电源
  Delete:删除虚拟机

xm常用命令
  create: 创建虚拟机 -c 表示打开控制台
  destory: 关闭虚拟机电源
  new: 添加到xend domain
  delete: 删除
  start: 开机一个域
  shutdown: shutdown -h now
  vcpu-list: 各虚拟机虚拟CPU状态

创建xen pv模式虚拟机
  前提


  • Kernel在半虚拟化模式
  • initrd或initramfs用于装载真正的根文件系统
  • DomU内核模块
  • 根文件系统
  • swap设备(optional)
  • DomU的配置文件
  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
xm的配置文件
  Kernel:内核
  ramdisk: initramfs或initrd文件
  name: 域名称
  memory:内存大小
  disk: 磁盘设备文件列表,格式disk = ["disk1","disk2",]。
  ​ 每个disk都由三个参数来定义


  •   “Backend-dev": 有两种类型,物理设备,虚拟磁盘映像文件,格式分别为:

    • phy: device路径
    • file: /path/to/image_file


  •   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']


  • type: 设备类型,默认为netfront
  • mac: 指定网卡mac地址
  • bridge: 指定桥接到的物理设备
  • ip: 指定IP地址
  • script: 配置此接口的脚本文件
  • vifname : 后端设备名称
  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设备文件
  查找最小的未被使用的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 重置窗口大小

Xen快速安装

yum install centos-release-xen -y
yum install xen -y
yum update -y
Xen 总结:


  • type-I: Xen hypervisor
  • Dom0: 特权域,管理IO
  • 管理控制台:Dom0; xm/xend, xl
  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']
  帧缓冲:提供图形化界面

磁盘映像管理工具qemu-img
  查看某种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都是目前比较出色的.

libvirt
  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

Xen实时迁移
  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
  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
  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 向内核传递的参数

KVM虚拟网络模型
  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

qemu-img
  创建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
CirrOS
  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类型直接给虚拟机

virtio
  通用于各种虚拟化技术的半虚拟化技术. linux内核从2.6.25起直接支持了virtio.通用框架, 提高io性能.
  建议创建网络设备和磁盘设备的时候都使用virtio.

Libvirt
  工具栈实现虚拟机管理
  安装系统: virt-manager, virt-install
  virsh不能安装, 可以用于管理

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: 虚拟机域

virt-install
  使用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
RHEL 虚拟化包组
  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

ESXI
  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: 虚拟机管理器

[iyunv@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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-386738-1-1.html 上篇帖子: 网络协议与网络安全学习记录 下篇帖子: 【转】XenServer体系架构解析
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表