NVIDIA GRID vGPU and KVMGT for KVM

This article will tell you how to use NVIDIA vGPU and KVMGT in KVM hypervisor with mdev.
I’ll use NVIDIA M60 and RHEL 7.4 for testing.

1. NVIDIA vGPU

1.1. Prepare drivers and utilities

1.2. Create vGPU with command line

1.3. Passthrough vGPU to vm

2. KVMGT

2.1. Prepare drivers and utilities

2.2. Create vGPU with command line

2.3. Passthrough vGPU to vm

3. AMD vGPU

3.1. Prepare drivers and utilities

3.2. Create vGPU with command line

3.3. Passthrough vGPU to vm

Ref:

https://www.kraxel.org/blog/tag/vgpu/

Home-based hybridcloud(家庭作坊式混合云)

名字起的不好听,不过无所谓,也是混合云了,做到了什么地步呢?
在数据层面,家中机器和linode以及gcp公有云全通,任意地点的客户端可以通过局域网地址访问家中和公有云,而这一且,只需要一个公网IP。那么如何组建呢?

1. 选择一个趁手的VPN,这里我使用的是SoftEther,全平台全功能,图形界面客户端全都有,自带域名反向解析,自带公网,又那么稳定,为啥不用。
只要在家中的一台PC上装好服务端,把5555端口通过路由器(有公网IP)映射出去即可完成VPN服务器的搭建。

2. Linode服务器集群选择一台作为网关(边界路由器),负责作为客户端接入VPN服务器,那么它就有了192.168.0段的地址,其它机器上因为linode没有VPC的概念,所以得加条到192.168.0.0/24的路由。

3. 总结下来,接入到home的VPN服务器会给所有客户端一个home的IP地址,然后加的路由表(使linode集群的10段暴露出去)都围绕这个地址展开达到互通的目的。

4. 目前我把linode上分散在全球8个机房的私有服务器都加了进来,当然,安全线路。尝试了一次kcptun加速VPN连接,但是linux下失败了,windows成功。

这是图,PC-Server为VPN服务器,LINODE为公有云,也加入了Google的公有云进去(没画),Windows-PC为个人服务器。

联通之后,Google的CDN、DNS可以混合到Linode去使用了,再展开点,大数据、数据库都可以结合Linode去跑了。

ZStack Glusterfs 超融合方案

ZStack 2.1版本中已经支持了NFS作为MNHA节点的存储,那么我们可以按照之前glusterfs组件oVirt超融合的方式直接使用,过程如下。

实验环境
服务器3台,双千兆网口,均已安装ZStack专家模式操作系统。

部署三节点无条带双副本分布式glusterfs存储
节点安装ZStack计算节点后,分别在三台上使用如下命令安装glusterfs。

部署ZStack HA管理节点
将glusterfs的路径分别挂载至/zstack/glusterfs/mnha/,但要注意NFS/glusterfs的IP,因为glusterfs到服务端的连接不同于

在ZStack中集成OVS/DPDK/ODL

这篇文章较之前的ZStack+Neutron更为简单,由于ZStack的vxlan实现没有使用ovs,所以。。我不管了,直接ovs吧。另外,你如果使用了vyos,我没研究,可以等到下一期处理。

以下方法仅仅从实现角度出发,理应适用于其他平台,如果是正经的集成,请自己编写模块。

环境:单台主机有两个网卡,相同网段(纯粹方便使用而搞,不要学习),ZStack已经安装,其中eno16780032为管理网络,eno33561344为ZStack二层网络接口,三层网络novlan。

集成OVS/ODL

1. 于计算节点中安装openvswitch。

wget https://repos.fedorapeople.org/repos/openstack/openstack-ocata/rdo-release-ocata-3.noarch.rpm
rpm -i rdo-release-ocata-3.noarch.rpm
yum --enablerepo=* install -y openvswitch
# yum --enablerepo=* install -y openvswitch-ovn*
systemctl enable openvswitch
systemctl start openvswitch

2. 接下来我给你解释一下,要怎么做了。
首先,由于ZStack的flat网络使用了network namespace,通过一对pair将其与linuxbridge相连,ns内的叫inner0,外部的叫outer0;其中ns中会有dnsmasq启动的dhcp服务,我们将ns看作一个带dhcp的功能交换机好了,仅仅提供dhcp能力。

然后,我们要创建一个ovs,为了将虚拟机的网口vnic1.0能够通过ovs进行控制,同时与dhcp交换机接通,我们需要一根线将ovs与linuxbridge接起来,如此一来,看下图(幸苦画的ASCII图没了!)。

# 创建ovs
ovs-vsctl add-br ovs-br0
ip link set dev ovs-br0 up

# 创建接口对
ip link add name veth0 type veth peer name veth0p

# 开始扎物理网线
brctl delif br_eno16780032 eno16780032
ovs-vsctl add-port ovs-br0 br_eno16780032

# 扎接口对
brctl addif br_eno16780032 veth0
ovs-vsctl add-port ovs-br0 veth0p
ip link set dev veth0 up
ip link set dev veth0p up

最后由于我们的虚拟机接口vnic1.0每次都会创建到linuxbridge上,所以我们要把它拔下来插ovs上从而可以进行流表控制(可以保存为脚本)。

brctl delif br_eno16780032 vnic1.0
ovs-vsctl add-port ovs-br0 vnic1.0

Q: 为啥要把物理网口eno33561344放到ovs里?
A: 为了保持纯粹 :)

Q: 为啥不把outer0直接放到ovs里?
A: ZStack逻辑每次创建虚拟机都会试图把outer0加到linuxbridge里,如果已经加到其他网桥虚拟机创建会失败。

最后,把物理机的OVS实例交给ODL处理吧,不画图了。

ovs-vsctl set-manager tcp:opendaylight_ip:6640
# 也可以单独设置网桥的控制器,如果不想全被控制的话
ovs-vsctl set-controller ovs-br0 tcp:controller_ip:6633

# 安装ODL的插件
cd ODL_DIR
./bin/bash
./bin/client
# 安装netvirt与dlux界面,安装netvirt与yang
opendaylight-user@root> feature:install odl-netvirt-openstack odl-dlux-all odl-dlux-yangman odl-mdsal-apidocs odl-netvirt-ui

物理机关机了或者新建主机了咋办?
自己写网络配置文件、手撸脚本,方便的话可以进ZStack公司报名学习。

集成DPDK

为什么要做这件事儿呢?因为Intel说将DPDK与OVS结合会极大提升传输效率,https://download.01.org/packet-processing/ONPS2.1/Intel_ONP_Release_2.1_Performance_Test_Report_Rev1.0.pdf

OK,那就开始换模块插网线吧,如果对DPDK不熟悉的同学可以去http://dpdk.org扫一眼tutorial。

首先修改grub文件,在kernel启动参数中加入如下内容,尺寸自己酌情添加。

iommu=pt intel_iommu=on hugepages=16 hugepagesz=2M hugepages=2048 iommu=pt intel_iommu=on isolcpus=0-3

将上述内容加入到/etc/default/grub的CMDLINE后,执行“grub2-mkconfig > /boot/grub2/grub.cfg”并重启。

然后启用CentOS的Extra源并安装DPDK,这步操作较DPDK刚出来的时候已经良心很多了。。

yum install dpdk dpdk-tools driverctl

将网卡与vfio_pci绑定,没错,Intel的万兆卡。

modprobe vfio_pci

driverctl -v list-devices|grep Ether
0000:02:00.0 XXX
driverctl set-override 0000:02:00.0 vfio-pci

在OVS中配置使用dpdk,这里我们创建另外一个OVS桥。

ovs-vsctl add-br ovs-br1

ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true

ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem="1024,0"

ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-lcore-mask=0xf

ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0xf

systemctl restart openvswitch

ovs-vsctl list Open_vSwitch
[dpdk, dpdkr, dpdkvhostuser, dpdkvhostuserclient, geneve, gre, internal, ipsec_gre, lisp, patch, stt, system, tap, vxlan]

然后,创建ovs-br1并塞俩vhost接口。

ovs-vsctl add-br ovs-br1 -- set bridge ovs-br1 datapath_type=netdev
ovs-vsctl add-port ovs-br1 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser
ovs-vsctl add-port ovs-br1 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser

到这里,工作基本完成,然后修改ZStack计算节点的虚拟机定义,目的是添加以下参数。

-chardev socket,id=char1,path=/run/openvswitch/vhost-user1 \
-netdev type=vhost-user,id=mynet1,chardev=char1,vhostforce \
-device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1 \
-object memory-backend-file,id=mem,size=1G,mem-path=/dev/hugepages,share=on
-numa node,memdev=mem -mem-prealloc

怎么加呢?先virsh shutdown 1,然后virsh edit 1,并找到合适的地方加如下内容(开启平台设置中的NUMA选项)。

...

    
      
    
    
    

<interface type="vhostuser">
<model type="virtio" />
<source mode="server" path="/var/run/openvswitch/vhost-user1" type="unix" />
<link state="up" />
<bandwidth />
</interface>
...

最后virsh start 1。

然后同样方法启动第2台虚拟机,在虚拟机里尝试 iperf,对比一下数据,整体来说都会获得些许提升以榨干网卡能力。

注意:以上内容仅仅是为了好玩,不要轻易在自己的ZStack生产环境中测试!

参考:
https://software.intel.com/en-us/articles/set-up-open-vswitch-with-dpdk-on-ubuntu-server
https://www.ovirt.org/blog/2017/09/ovs-dpdk/
https://libvirt.org/formatdomain.html

如何正确计算CPU利用率?

我们平时使用的CPU利用率方法是极具误导性的,并且一年更甚一年。那么什么是CPU利用率?是你的CPU到底有多忙,是像“% CPU”这样到处在用的指标所显示的那样吗?

在top命令里,你看到90%的CPU利用率是这样:

然而它真正想表达的是这个意思:

Stall(这里译作“怠速”)是说这个处理器没有在跑指令,比如在等待内存I/O的时候。我上图所画的比例(“忙”与“怠速”之间)是我在真实生产环境中遇到的,并且你的CPU也很可能是处于“怠速”状态。

这些对你有什么意义呢?理解CPU怠速多少,会直接影响到你在减少代码或者减少内存I/O的调优工作。

那么真正的CPU利用率怎么算呢?

平时的CPU利用都是非空闲时间,即CPU不运行idle线程(比如Windows里的空闲进程)的时间。你的操作系统那会平时会在上下文切换的时候跟踪它,但是假如一个非idle线程开始运行100毫秒后停止,那内核会认为后面这段时间CPU也在这个非idle线程上。

在老旧的分时系统里,这么算没毛病。阿波罗登月舱的导航系统计算机将这里的idle线程叫做“DUMMY JOB”,工程师用利用它来测算计算机的利用率,可以参考之前我写过的这样一篇文章

那么它有什么毛病呢?

现在的CPU比内存已经快了很多倍,但等待内存的时间仍然被算进CPU时间中。当你在top命令中看到较高的“%CPU”的时候,你可能认为它到达了一个性能瓶颈,就是散热片和风扇下面的那个CPU,但实际上,这是那一根根内存条的锅。

如何分辨CPU到底在忙啥?

使用性能监测计数器(PMC)——一种能够用perf或者其他工具命令查看的硬件计数器。比如,观测整个系统10秒钟:

# perf stat -a -- sleep 10

 Performance counter stats for 'system wide':

     641398.723351      task-clock (msec)         #   64.116 CPUs utilized            (100.00%)
           379,651      context-switches          #    0.592 K/sec                    (100.00%)
            51,546      cpu-migrations            #    0.080 K/sec                    (100.00%)
        13,423,039      page-faults               #    0.021 M/sec                  
 1,433,972,173,374      cycles                    #    2.236 GHz                      (75.02%)
   <not supported>      stalled-cycles-frontend  
   <not supported>      stalled-cycles-backend   
 1,118,336,816,068      instructions              #    0.78  insns per cycle          (75.01%)
   249,644,142,804      branches                  #  389.218 M/sec                    (75.01%)
     7,791,449,769      branch-misses             #    3.12% of all branches          (75.01%)

      10.003794539 seconds time elapsed

这里的一个关键指标就是instructions per cylce(IPC,每CPU周期执行指令数),它能够显示每CPU周期内每个CPU运行了多少指令,越高说明效率越高。上述示例中,这一值为0.78,但这并不说明CPU利用率为78%,因为现代CPU的IPC最大值为4.0(新的已经到了5.0),也就是4-wide。CPU在执行指令时,单个指令会被分割为多个步骤,比如取指令、解码、执行、内存访问、写寄存器等,这些命令如果在单个CPU周期内最多执行一个,那么需要5个CPU周期来完成一条命令,IPC就是0.2,如果采用指令流水线,即3~5-wide的CPU,那么完美状态下1个CPU周期就可以完成一条命令,IPC就是1。(译者注:作者文中使用了CPU clock cycle表示通常所说的CPU周期,为了避免与晶振时钟周期混肴我并没有将其译为CPU时钟周期。)

当然,还有数百个其他你可以用来测量的性能计数器。

如果在虚拟化环境中,guest一般不能直接访问PMC,这取决于hypervisor是否支持。我最近写的一篇The PMCs of EC2: Measuring IPC展示了AWS EC2中基于Xen的虚拟机如何使用PMC。

最佳实践

如果你的IPC小于1.0,你可能遇到了内存操作密集型,软件调优策略可以有减少内存I/O,增强内存本地访问性,尤其是在NUMA系統上。硬件调优策略则是使用CPU cache较大以及更快的内存、总线和内联技术。

如果你的IPC > 1.0,你可能是指令密集型。可以试图减少指令的执行数量,比如消除不必要的工作和缓存操作等,可以用一下CPU火焰图。硬件调优方面,可以尝试高主频、多核、超线程的CPU。

性能检测产品应该告诉你什么呢?

性能检测工具都应该显示出每个进程的IPC,或者是按照指令周期与怠速周期,比如%INS和%STL,下图为Linux中的tiptop命令:

tiptop -                  [root]
Tasks:  96 total,   3 displayed                               screen  0: default

  PID [ %CPU] %SYS    P   Mcycle   Minstr   IPC  %MISS  %BMIS  %BUS COMMAND
 3897   35.3  28.5    4   274.06   178.23  0.65   0.06   0.00   0.0 java
 1319+   5.5   2.6    6    87.32   125.55  1.44   0.34   0.26   0.0 nm-applet
  900    0.9   0.0    6    25.91    55.55  2.14   0.12   0.21   0.0 dbus-daemo

CPU利用率具有误导性的其他理由

使得这个%CPU指标错误的理由除了CPU在内存的怠速周期外,还有如下因素:
1. 温度也能使CPU进入怠速;
2. Turboboost(睿频)引起时钟频率变化;
3. SpeedStep引起时钟频率变化;
4. 一分钟内的80%的平均利用率并不能表示100%的突发利用率(类似网络QoS);
5. 自旋锁:CPU在很严肃地瞎忙;

Update: CPU利用率真的错了吗?
自这篇文章发布以后,留言讨论非常激烈,已经有了上百条了。首先谢谢你们对这话题感兴趣并花时间阅读,但我在这里还是要统一回复:我对disk的iowait并不关心(译者注:PC CPU不能直接操作外部存储),并且文中也已经给出了内存操作密集型的对应调优措施。

然后,CPU利用率到底是从本质上错了还是仅仅是了?我认为需要人将高CPU利用率视为处理单元的瓶颈的事儿,是错的。那么这个指标的计算方法从技术上讲正确吗?如果CPU在怠速期间不能被其他任何进程使用,那么这不就是所谓的“使用等待”(听起来有点矛盾)。某些情况下,%CPU作为一个操作系统层面的指标是技术正确但是容易误导人的。在超线程中,怠速周期可以被其他线程使用,所以%CPU的算法也会将其算在内,而实际上并没有利用。那样是不对的,这篇文章中我强调的是解释问题并提出对策,并且,这个指标也有技术上的问题。

结论

CPU利用率已成为一个极具误导性的指标:它算进了等待主存的周期,而这类周期在现代的CPU负载中占据不少。如果使用额外指标,你就能搞清楚%CPU到底意味着什么,包括每CPU周期执行指令数(IPC)。IPC < 1.0可能意味着你的应用是内存密集型,而IPC > 1.0则可能是指令密集型。我在之前的一篇文章

显示%CPU的性能监控产品也应该显示PMC测量指标,并给予充分解释,这样才不会误导用户。比如,它们可以一起显示%CPU和IPC,或者指令周期与怠速周期。有了这些指标,开发或管理人员才能在应用和操作系统中选择正确的调优方式。

本文翻译自Brendan Gregg的博客文章《CPU Utilization is Wrong》,原文链接为http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html,就是那本《性能之巅(中译)》的作者,调试工具dtrace的作者,现就职于NetFlix。

PS:为什么要翻译这个文章呢?因为很多时候总感觉PC的这个CPU利用率的百分比显示没能真实反应我的CPU到底忙不忙,在学校的时候用单片机也是算idle,但到了PC后隐约感觉这么算不对,看了BG的文章后才恍然大悟。另外这篇文章之前已经被翻译过,但作者又有更新,也挺有意思的,我就重新翻了一遍,并加了一些弹幕。

在ZStack中集成OpenStack Neutron组件

以笔者目前对ZStack源码的掌握,并不能较为产品化地集成Neutron,所以只能用点稍微hack的技巧将其用起来。

实验材料:ZStack单机版,OpenStack Neutron with Dashboard and OVS bridge

实验目的:通过修改ZStack实例的开机xml(或者新建主机时修改网络为openvswitch bridge),调用Neutron API,并将实例网络桥接至OVS网桥。

实验步骤:

1. 搭建ZStack,略。

2. 搭建OpenStack Neutron实例,参考脚本https://…

3. 编写hook脚本

4. 开机测试

5. 通过OpenStack Dashboard查看

实验思考:

这就是KVM平台的好处,互操作性杠杠的。另外,Neutron可作为VM Appliance单独提供,加上Cloud-Init就更好了。

实验过程:

1. 集成oVirt与Neutron

2. 集成ZStack与Neutron

3. Neutron与其产品的集成

参考链接:

http://www.ovirt.org/develop/release-management/features/cloud/neutronvirtualappliance/

TBD