运行docker报错Cannot connect to the Docker daemon. Is 'docker -d' running on this host?

Ansible 回复了问题 2 人关注 1 个回复 5899 次浏览 2015-09-01 20:53 来自相关话题

KVM性能测试报告

Ansible 发表了文章 0 个评论 7141 次浏览 2015-09-01 11:11 来自相关话题

本测试试图找出以下问题的答案:            1. 虚拟机相对于物理机性能损失有多严重(CPU/MEM/NET/DISK)             2. 对于多个虚拟机,KVM 对资源的分配是否公正         ...查看全部
kvmlogo.gif

本测试试图找出以下问题的答案:
           1. 虚拟机相对于物理机性能损失有多严重(CPU/MEM/NET/DISK) 
           2. 对于多个虚拟机,KVM 对资源的分配是否公正
           3. 找出性能最好的物理机磁盘类型和虚拟机磁盘类型及参数 
               A) 物理机使用 ext4 的最优化设置 
                     ➔  使用 raw 磁盘的最优性能设置 
                           ➢  cache类型 
                                 • none 
                                 • writeback 
                                 • writethrough 
                           ➢  驱动类型              
                                 • ide 
                                 • virtio 
                     ➔  使用 qcow2 磁盘的最优性能设置 
                           ➢  cache类型
                                 • none        
                                 • writeback 
                                 • writethrough 
                           ➢  驱动类型 
                                 • ide 
                                 • virtio 
                           ➢  是否preallocation  
                      ➔  比较得出使用 ext4 的虚拟机磁盘类型最优化设置 
 
              B) 物理机使用xfs磁盘的最优化设置 
                      ➔  使用 raw 磁盘的最优性能设置
                            ➢  cache类型 
                                 1. none
                                 2. writeback
                                 3. writethrough
                            ➢  驱动类型 
                                  1. ide
                                  2. virtio
                      ➔  使用 qcow2 磁盘的最优性能设置
                            ➢  cache类型 
                                  1. none
                                  2. writeback
                                  3. writethrough
                            ➢  驱动类型 
                                  1. ide
                                  2. virtio
                            ➢ 是否preallocation
                      ➔ 比较得出使用 ext4 的虚拟机磁盘类型最优化设置 
  
              C) 比较得出ext4和xfs那个更优秀 


物理机配置


服务器型号:DELL R410
CPU型号:CPU:Intel(R) Xeon(R) CPU E5620 2.4G*2
内存大小:8GB
硬盘大小:300*2
网卡:Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet * 2


虚拟机配置


在测试一个参数的时候为了防止其它因素的影响,不同的测试虚拟机配置会不同


CPU 的测试


虚拟机与物理机之间的性能对比 
主要测试相对于物理机,虚拟机的性能损失有多少


虚拟机配置


1个VCPU    2G 内存    20G 硬盘
用一个寻找质数的 C 程序,分别测试找出一百万,一千万,1 亿以内的质数所用的时间 
kc1.png

kc2.png

从上面的图可以看到,KVM 虚拟机相对于物理机的 CPU 性能损失非常小(不到 1%) 
 
由于物理机是 8 核的 CPU,我们猜想是不是他们运行在各自的 CPU,所以我们分别测试了同时在 2 个,4 个,6 个,8 个和 10 个虚拟机中运行测试程序所使用的时间,得到的结果是他们使用的时间相差不大,这里是同时在 10 个虚拟机中运行测试程序找出 1 亿中的质数所使用的时间对比图,我们在最后加上了在物理机中的运行时间 
kc3.png

我们猜想当同时运行的程序数(10)多于 CPU 数(8)时会有资源争抢或资源分配不均的情况出现,从上图可以看 到 KVM 于这些处理的很好,资源利用率很高,物理机和最慢的相差不到 20 秒(6%),资源分配也比较公正 


内存 


对于内存的测试多们使用了一个程序 memtester(注意不是 memtest),它能取给定大小的内存进行读写等一系 列的测试操作 
kc4.png

从这个图可以看出,相对于物理机,虚拟机的性能损失非常小 
kc5.png

上图是两个虚拟机同时运行测试所用的时间和物理机之间的对比,可以看出 KVM 对内存资源的分配很公平 


网络


我们在连接在相同交换机的另一台服务器上搭建 Web 服务器,让测试机和虚拟机同时下载 5G 的文件 
kc6.png

从这个图可以看到,公认的性能比较好的 virtio 驱动将虚拟机的网络性能发挥到极致,和物理机不相上下 
kc7.png

这个图再一次反映了 KVM 对资源分配的公平性 
 
我们还测试了同一台物理机上的虚拟机之间的传输速度可以稳定在 122MB/s 


硬盘 


磁盘的测试花了一些时间,因为有很多因素会影响磁盘性能,这个测试也没有覆盖所有可能的因素 先上数据 
kc8.png

对表的说明: 
      • 这个表记录了不同的参数对安装一个 CentOS 到虚拟机中所用的时间的影响
      • 安装使用相同的 kickstart
      • 使用 time 命令记录安装过程所使用的时间
      • 最后一列是将前一列的时间转化为秒数
      • 第一列的 xfs 和 ext4 指宿主机的存放虚拟磁盘镜像文件的分区类型,挂载参数都使用 default
      • Raw 和 Qcow2 指虚拟机的磁盘类型
      • ide 和 virtio 指虚拟机磁盘的驱动类型
      • pre 和 nopre 只是针对 qcow2 磁盘类型,创建磁盘文件时加上参数 preallocation=metadata 既为 pre
      • none,wt,wb,分别指缓存类型为 none, writethrough, writeback
      • 虚拟机都使用 1vcpu,2G 内存,40G 磁盘
 
下面从总体上看下他们的性能如何
kc9.png

从这个图不太容易看出哪个配置使用的时间最短,但非常容易看出最耗时的一个: 
 
宿主机使用 xfs,虚拟机使用 qcow2 磁盘,ide 驱动和 writethrough 缓存类型 
 
下面我们以由小到大的顺序,找出每个区域的最高性能,然后他们之间做对比 


首先看一下不同的缓存类型对性能的影响 


kc10.png

kc11.png

从两幅图可以得到的结论是:使用 writethrough 性能最差,none 和 writeback 相差不大 
 
这里插点缓存的知识
KVM 缓存模式概览 通常,虚拟机使用宿主机上的一个文件保存它的数据,这个文件代表一个虚拟机作为正常的物理磁盘使用的虚 拟磁盘,然而,从宿主机的角度来看这个虚拟磁盘只是一个正常的数据文件并且可以对它缓存

在这种情况下,缓存是隐藏一些磁盘数据在内存中.当我们只在内存中存储上次读的数据,我们称之为读缓存,或 者 write-through 缓存.当我们还存储一些要写到硬盘的数据在内存中,在以后的某个时间再写到磁盘,我们称 之为读写缓存,或者 write-back 缓存,write-back 缓存通过将写磁盘请求缓存到高速内存中,有更高的性能,然 而它也比 write-through 更有可能丢失数据,因为后者只缓存写请求,写请求立即写到磁盘里 
 
因为磁盘 I/O 是非常重要的因素,Linux 和 Windows 系统通常使用 write-back 策略周期性的写到磁盘里,然 而,当然后虚拟化管理程序虚拟一个机器时,你可以有效的缓存一些数据两次(一次在宿主机的内在中,一次在虚 拟机的内存中),所以你可以取消宿主机对磁盘文件的缓存,让虚拟机自己管理它的缓存.些外,宿主机端的 write- back 策略很大程序上增加了数据丢失的可能性,然而,你很快会发现,新特性”barrier passing”的加入,你不用 再担心这个 


我们可以用一个图来更好的理解


kc12.png

假设传统的(没有 barrier-passing)程序:当虚拟机里的程序要写一些数据,通常数据保存到虚拟机的页缓存中. 页缓存会周期性的冲数据到虚拟磁盘设备也就是宿主机上的磁盘文件,另一方面,如果应用程序有一些非常重 要的数据要写,它可以绕过页缓存并且使用同步写方式,只有当写操作成功才返回,确保了所有的数据写到了虚 拟机的永久存储系统 
 
然而,在这一点上(写到虚拟机磁盘上)有三种可能:
         • 如果缓存策略是'writeback',数据会缓存到宿主机的页缓存中(红箭头) 
         • 如果缓存策略是'none',数据立即写到物理磁盘(灰箭头)
         • 如果缓存策略是'writethrough',数据将立即写到物理磁盘(蓝箭头) 
更多详情


下面我们看看 qcow2 磁盘使用和不使用 preallocation 的性能差异有多大 


kc13.png

从上图可以看出,不管宿主机使用 ext4 还是 xfs,虚拟机使用 ide 还是 virtio 驱动,使用 preallocation 都有性能 的提升,
这里有一个不问题:如果宿主机使用 xfs,创建 qcow2 磁盘镜像使用 preallocation 会很慢(40G 需要 8 分钟) 


下面我们来看看 ide 和 virtio 他们的性能对比 


kc14.png

很明显使用 virtio 是更明智的选择 


下面我们再看看 raw 和 qcow2 之间的对比


这里插一点 Raw 和 qcow2 的知识:
raw 的优势(能找到的相关资料太少,不知道是不是理解有误):
• 简单,并能够导出为其他虚拟机的虚拟硬盘格式
• 根据实际使用量来占用空间使用量,而非原先设定的最大值(比如设定最高 20G,而实际只使用
3G)。——需要宿主分区支持 hole(比如 ext2 ext3 ntfs 等)
• 以后能够改变空间最大值(把最高值 20G 提高到 200G,qcow2 也可以,不过要转为 raw)
• 能够直接被宿主机挂载,不用开虚拟机即可在宿主和虚拟机间进行数据传输(注意,此时虚拟机不要开)
而qcow2 的优势:
• 更小的虚拟硬盘空间(尤其是宿主分区不支持 hole 的情况下)
• optional AES encryption, zlib based compression and support of multiple VM snapshots.
原文在这里:http://www.linuxsir.org/bbs/thread368695.html 
kc15.png

从图表中可以看出,如果 qcow2 使用 preallocation, raw 的性能优势已经不是很明显 


下面看看 ext4 和 xfs 之间 的对比 


kc16.png

可以看到 ext4 性能要比 xfs 高,这可能是默认的挂载参数不能充分发挥 xfs 的性能 


最后,我们把时间最短的放到一起看到底那个最快 


kc17.png


总结 


CPU,内存都不是问题,对于硬盘,通过前面一系列的测试,我推荐使用以下配置:
• 使用 Ext4 做为宿主机磁盘格式
• 虚拟机用 qcow2+preallocation,
• 缓存使用 writeback
• 虚拟机网卡驱动使用 virtio
文章来源于网络,如果有问题联系社区相关人员!
 
 

浅谈docker文件系统分层与隔离

空心菜 发表了文章 0 个评论 4906 次浏览 2015-08-28 01:27 来自相关话题

        Docker 的很多特性都表现在它所使用的文件系统上,比如大家都知道docker的文件系统是分层的,所以它可以快速迭代,可以回滚。下面就聊一下我对docker文件系统的理解       Docker 使用的支 ...查看全部
df1.png
   
    Docker 的很多特性都表现在它所使用的文件系统上,比如大家都知道docker的文件系统是分层的,所以它可以快速迭代,可以回滚。下面就聊一下我对docker文件系统的理解
 
    Docker 使用的支持的文件系统有以下几种: aufs、devicemapper、btrfs  Vfs 我们先来介绍一下aufs


一、  Aufs(advanced multi layered unification filesystem)


    Aufs直译过来就是高级分层统一文件系统。做为一种Union FS 它支持将不同的目录挂载到同一个虚拟文件系统下. 这个怎么理解呢。通过一条命令我们来看一下吧。
mount -t aufs -o br=/tmp/dir1=ro:/tmp/dir2=rw none /tmp/newfs

    []-o 指定mount传递给文件系统的参数[/][]br 指定需要挂载的文件夹,这里包括dir1和dir2[/][]ro/rw 指定文件的权限只读和可读写[/][]none 这里没有设备,用none表示[/]

    这个结果是什么样子的呢。 就是把/tmp/dir1 t和/tmp/dir2  合并之后挂载到/tmp/newfs ,如果这时在/tmp/dir1 下创建一个文件a  /tmp/dir2下创建一个文件b 则  在/tmp/newfs 会看到a,b 这两个文件,并且a 是只读的, 如果有相同的文件则以先挂载的为准,后面挂载的操作会被忽略掉
 
   通过对Aufs的理解,大家可以想像一下docker所谓的“layer”的概念。还是实际的例子说明一下。

    一个镜像通过docker save  保存之后 会被打成一个tar 包,我们来看下这个tar包里都有些什么?
docker save cloud_jiankongbao:01.tar cloud_jiankongbao:01
    通过上面的语句我们把镜像保存出下来。可以看到,保存下来的是tar 包。 不是.iso文件^_^,镜像解压之后是什么呢?
ls . 
a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329
d9bde94c518a16a886514758b6b4431200145ecd58e30c5633ac3c0256544d77
f1b10cd842498c23d206ee0cbeaa9de8d2ae09ff3c7af2723a9e337a6965d639
fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f
repositories
    出现了四个目录文件,再通过
docker images --tree
└─f1b10cd84249 Virtual Size: 0 B
└─fb9cc58bde0c Virtual Size: 203.1 MB
└─a005304e4e74 Virtual Size: 203.1 MB
└─d9bde94c518a Virtual Size: 1.957 GB Tags: cloud_jiankongbao:01
    大家可以看到,4个目录其实分别是4个ID(注每次使用docker commit 提供对docker的修改之后就会产生一个新的id,就是通过这个ID可以实现对镜像的回滚)。每个目录下有json  layer.tar  VERSION 这三个文件。我们再看一下layer.tar 
cd fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f;tar -xf layer.tar;ls

ls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/
bin etc json lib lost+found mnt proc sbin srv tmp var
dev home layer.tar lib64 media opt root selinux sys usr VERSION
    这里存放的系统文件。

    我们再看一下镜像的4个不同ID的系统。

    f1b10cd84249 这个镜像是初始镜像,大小为0, fb9cc58bde0c 这个镜像是在f1b10cd84249基础上创建新的镜像,a005304e4e74是以fb9cc58bde0c为基础创建新的镜像。是树状继承的关系。我们再看下bin目录下的文件
ls a005304e4e74c1541988d3d1abb170e338c1d45daee7151f8e82f8460634d329/bin/
gtar tar
ls fb9cc58bde0c0a8fe53e6fdd23898e45041783f2d7869d939d7364f5777fde6f/bin/
arch cpio egrep gunzip logger mountpoint raw sleep true
awk cut env gzip login mv readlink sort umount
basename date ex hostname ls netstat rm stty uname
bash dd false ipcalc lsblk nice rmdir su unlink
cat df fgrep iptables-xml mkdir nisdomainname rpm sync usleep
chgrp dmesg find iptables-xml-1.4.7 mknod ping rvi taskset vi
chmod dnsdomainname findmnt kill mktemp ping6 rview touch view
chown domainname gawk link more ps sed tracepath ypdomainname
cp echo grep ln mount pwd sh tracepath6 zcat
    a005304e4e74 只有两个文件 fb9cc58bde0c包括了大部分bin下的文件,这就是Aufs,理解起来感觉有点像增量备份。


二、简单的说一下devicemapper 


    devicemapper是利用了Snapshot 和Thinly-Provisioned Snapshot两种原理。将多个快照挂在同一个卷下从而实现文件系统的分层。不过使用devicemapper 的话一个container的大小最大只能是10G。
 
    在启动docker daemon时用参数-s 指定:  docker -d -s devicemapper
 
    关于隔离是怎么实现的呢,当容器基于镜像启动之后,每个容器都会获得自己的写读可写的文件系统层。原镜像的那部分文件系统是只读的,从而实现每个容器的在文件系统上的离隔。
 
   平时大家都在说dokcer 是弱隔离的,为什么呢?因为他没有隔离的很彻底,比如内核,内核是跟大家共用的,跟宿主机共用同一个内核,SELinux、 Cgroups以及/sys、/proc/sys、/dev/sd*等目录下的资源是与宿主机共用的。

   如果要隔离的彻底那就是VM了,而且如果dockers要想实现这些隔离就必然要牺牲一下现在轻量级的特性。那还不如直接用虚拟机好了!
文章转载出处

我的docker为什么总是拉去镜像失败呢

空心菜 回复了问题 2 人关注 3 个回复 4814 次浏览 2015-08-27 00:01 来自相关话题

Docker主机间怎么共享数据卷

OpenSkill 发表了文章 0 个评论 4775 次浏览 2015-08-26 00:07 来自相关话题

     Docker容器在不同的主机间共享数据是一件很棘手的事情。本文从"Docker容器实践"中采取,我们将研究一个轻量级,一个更复杂的方式在不同的主机间共享Docker数据卷。      尽管容器之间共享同一台主机上的数据变得更为简便,跨主机 ...查看全部
dk1.png

     Docker容器在不同的主机间共享数据是一件很棘手的事情。本文从"Docker容器实践"中采取,我们将研究一个轻量级,一个更复杂的方式在不同的主机间共享Docker数据卷。
     尽管容器之间共享同一台主机上的数据变得更为简便,跨主机间共享Docker数据卷比较棘手。数据容器是解决这个问题的一个方法,但如果数据经常变化或特别大,这样做会变得笨拙。
     我们要考察两个解决这个问题的方法。第一个是一个轻量级的分布式解决方案使用BitTorrent协议,仅仅需要安装Docker。 第二是使用NFS,并引入基础设施的容器的概念的更复杂的解决方案。


方法一:分布式数据卷BitTorrent的同步


     当Docker在一个组中实验,希望在组内共享大量数据,但是可能共享服务器没有足够的能力分配资源。懒惰的解决方案是在你需要他们的时候复制其他团队成员的最新文件,这将对一个更大的组失去控制。
     对此的解决方案是使用一个分散的工具共享文件–没有专门的资源要求。
问题:
     你想在互联网上共享跨主机的卷
解决方法:
     使用BitTorrent同步image共享卷
讨论:
    下面说明图显示了我们的目标,结束与设置:
dk2.png
   
     A - 该BTSync服务器是一个拥有我们将要共享的/data数据卷Docker容器
B - 在同一主机上设置一个容器从BTSync服务器上挂载数据卷
C - 在一个单独的网络中的其他主机,在BTSync服务器生成一个密钥,客户端可以通过引用BitTorrent协议来访问共享数据。
D - 在另外一台主机上的BTSync客户端,从第一主机BTSync服务器挂载数据同步更新/data数据。
E - 容器从BTSync客户端挂载数据卷
     最终的结果是卷/data-即方便地同步在互联网上,而不需要任何复杂的设置。
     在您的主服务器上运行这些命令来设置第一台主机上的容器:
[host1]$ [#A]docker run -d -p 8888:8888 -p 55555:55555 --name btsync ctlc/btsync
$ [#B]docker logs btsync
Starting btsync with secret: [#C]ALSVEUABQQ5ILRS2OQJKAOKCU5SIIP6A3 By using this application, you agree to our Privacy Policy and Terms. http://www.bittorrent.com/legal/privacy http://www.bittorrent.com/legal/terms-of-use
total physical memory 536870912 max disk cache 2097152 Using IP address 172.17.4.121
[host1]$ [#D]docker run -i -t --volumes-from btsync ubuntu /bin/bash
$ touch /data/shared_from_server_one [#E] $ ls /data shared_from_server_one
     A -运行发表CTLC / btsync image btsync守护程序容器调用并打开所需的端口
     B -获取 btsync容器的输出,所以我们可以记下key
     C -记下key-不同的运行产生有所不同
     D-启动一个交互式的容器从btsync服务器的卷
     E-添加文件到/data
     在第二个服务器上打开一个终端,运行以下命令来设置数据同步
[host2]$ docker run -d
--name btsync-client -p 8888:8888 -p
55555:55555 ctlc/btsync ALSVEUABQQ5ILRS2OQJKAOKCU5SIIP6A3 [#A]
[host2]$ docker run -i -t --volumes-from btsync-client ubuntu bash [#B] $ ls /data shared_from_server_one [#C] $ touch /data/shared_from_server_two [#D] $ ls /data
shared_from_server_one shared_from_server_two
     A -启动 btsync客户端容器与host1上的守护程序运行生成的密钥守护进程
     B -启动安装卷从我们的客户守护进程的互动容器
     C - host1上创建的文件已被转移到主机2
     D -创建 host2上的第二个文件
     回到主机1的运行容器,我们应该看到的文件,就像第一次是在主机之间进行同步:
$ ls /data
shared_from_server_one shared_from_server_two
      注:文件同步是没有时间保证,所以你可能要等待同步数据。这是特别真实的更大的文件。

      警告:由于数据被发送到互联网和处理的协议,你没有控制,不要依赖于此,如果你有任何有意义的安全性,可扩展性或性能约束。


方法二:通过NFS共享数据


      在一些大公司极有可能已经在使用NFS,NFS是一种行之有效的选项作为文件中心服务。Docker想要工作,它能够访问这些共享文件通常是很重要的!
      然而,Docker不支持NFS开箱即用和每个集装箱上安装NFS客户端,以便能够挂载远程文件夹不被认为是最佳时实践。相反,建议的方法是有一个容器用作从NFS翻译为Docker更友好的概念–卷!
问题:
      你要无缝访问远程文件系统通过NFS
解决方法:
      使用基础设施的数据容器代理访问
讨论
      这种技术建立在数据容器技术之上。
下图给出了这个抽象的概念:
dk3.png

      NFS服务器暴露内部目录的文件夹/出口,这是安装在主机绑定。Docker主机再将这个文件夹使用NFS协议mount到/mnt文件夹。然后,一个所谓的基础设施容器被创建,它结合了安装文件夹。
     这似乎有点过度设计乍一看,但好处是,它提供了一个间接层就Docker容器而言:他们需要做的是安装卷从预先约定的基础设施的容器,谁是负责基础设施可以担心的内部管道,可用性,网络等。
     彻底处理NFS是超出了本书的范围。然而,我们去通过一台主机上建立这样一个共享的步骤(即NFS服务器的元素在同一主机作为Docker容器)。这已经在Ubuntu 14.04测试。
     想象一下,你想分享你的主机/opt/test/db,其中包含的文件mybigdb.db。
     使用root,安装NFS服务器创建/export目录,并开放权限:
apt-get install nfs-kernel-server mkdir /export chmod 777 /export
     现在挂载db目录/opt/test/db到/export
$ mount --bind /opt/test/db /export
     现在你应该可以看到 /opt/test/db中的挂载的内容
     现在加入这一行到您的etc/exports文件中
/export       [#A]127.0.0.1([#B]ro,fsid=0,insecure,no_subtree_check,async)
      A -对于这个概念证明的例子中我们对127.0.0.1,这违背了对象有点安装在本地。 在真实的场景中,你会锁定下来的一类IP地址,如192.168.1.0/24的。 如果你真的很喜欢玩火,你可以打开它的世界,而不是127.0.0.1!
     B -为安全起见,我们安装件只读这里,*但是你可以用RW更换RO安装读写。 请记住,如果你这样做,那么你就需要异步标志出现后添加no_root_squash会标志 - 但考虑安全性在此之前沙坑外面去!
挂载NFS上的目录/ mnt目录,出口,我们在指定的文件系统的/ etc / exports的上面,然后重新启动NFS服务,拿起变化: 
$ mount -t nfs 127.0.0.1:/export /mnt
$ exportfs -a
$ service nfs-kernel-server restart
     现在您已经准备好运行基础设施的容器:
$ docker run -ti --name nfs_client --privileged -v /mnt:/mnt busybox /bin/true
      TODO:检查一个以上要求
      现在,我们可以运行 - 没有特权,或底层实现知识 - 目录,我们希望访问:
$ docker run -ti --volumes-from nfs_client debian /bin/bash root@079d70f79d84:/# ls /mnt myb root@079d70f79d84:/# cd /mnt root@079d70f79d84:/mnt# touch asd touch: cannot touch `asd': Read-only file system
     提示:如果你有很多这些容器来管理使用的运营效率的命名约定,你可以通过命名约定管理操作更容易,例如——名为nfs_client_opt_database_live容器暴露/opt/database/live路径。
这种模式的一个共享资源,在多个容器中使用的其他人使用的共享资源,是一个强大的,可以使开发工作流程更简单。
原文地址

SELinux防护KVM安全

OpenSkill 发表了文章 0 个评论 3964 次浏览 2015-08-23 01:40 来自相关话题

      SELinux最初是由美国安全局NSA发起的项目,是基于强制访问控制(MAC)策略的,为每一个主体和客户都提供了个虚拟的安全“沙箱”,只允许进程操作安全策略中明确允许的文件。当Linux开启了SELinux安全策略,所有的主体对客户的访问必须同时满 ...查看全部
se1.jpg

      SELinux最初是由美国安全局NSA发起的项目,是基于强制访问控制(MAC)策略的,为每一个主体和客户都提供了个虚拟的安全“沙箱”,只允许进程操作安全策略中明确允许的文件。当Linux开启了SELinux安全策略,所有的主体对客户的访问必须同时满足传统的自主访问控制(DAC)和SELinux提供的强制访问控制(MAC)策略。
 
      在虚拟化环境下,通常是多个VM运行在同一个宿主机(物理机)上,通常由同一个用户启动多个VM管理进程(如:qemu-kvm或者vmx等),而这些VM可能为不同的租户服务,如果其中一个VM由于某些脆弱性被恶意控制了,而hypervisor层有缺陷,攻击者就有机会利用被控制的VM发起对同宿主机或其它VM进行恶意攻击。如下图:宿主机中的SELinux安全策略阻止了VM的Attack行为。
se2.png


SELinux与KVM


      sVirt 项目集成SELinux强制访问控制 (MAC) 安全和基于 Linux 的KVM虚拟化。
确认SELinux策略正常开启
se3.png

创建img文件
     通过dd命令创建两个大小为20GB的img文件,作为虚拟机的磁盘:
dd if=/dev/zero of=/opt/vm/vm01.img bs=1M count=20480
dd if=/dev/zero of=/opt/vm/vm02.img bs=1M count=20480
      查看img文件安全上下文
se4.png

     从上图可知两个img文件的安全上下文,其中用户域为unconfined_u,表示不限制用户;角色域为object_r通常表示普通文件或目录;类型域为usr_t;MCS为s0;
qemu-kvm命令配合VNC​
/usr/libexec/qemu-kvm -cpu qemu64 \
-drive file=/opt/vm/vm01.img \
-m 2048 \
-cdrom \
/opt/CentOS-6.5-x86_64-bin-DVD1.iso \
-vnc :1

/usr/libexec/qemu-kvm \
-cpu qemu64 \
-drive file=/opt/vm/vm02.img \
-m 2048 \
-cdrom \
/opt/CentOS-6.5-x86_64-bin-DVD1.iso \
-vnc :2
     给两个img文件安装上CentOS-6.5-x86_64操作系统并处于运行状态,此时的两个img文件的安全上下文还是与之前的保持不变。(注:实际在部署KVM虚拟机里以上步骤不是必须,这里是为了演示SELinux安全上下文的变化而考虑的)
virt-manager启动KVM虚拟机
     结束qemu-kvm进程,用专用的virsh或virt-manager工具(这里以图形工具virt-manager为例)启动两个虚拟机,先ssh –X连接到宿主机,再执行virt-manager命令:
se5.png

     在弹出的窗口里“新建”一个虚拟机,输入名称,单选“Import existing disk image”根据向导创建并启动虚拟机:
se6.png

     当两个虚拟机都通过virt-manager启动之后管理窗口如下:
se7.png

确认安全上下文变化
     此时再看一下两个img文件的安全上下文,除了角色域object_r没有变化之外,用户域、类型域、MCS都发生了变化
se8.png

     再确认一下对应进程的安全上下文:
se9.png

     可以看出img文件的MCS与进程的MCS是严格对应的,且对虚拟机进行重启操作时会自动给进程和img文件重新分配MCS。这种安全机制可以严格控制威胁的范围,提高云平台的安全性。


SELinux阻止非法访问


     介绍一下MCS不同时阻止相互访问,将/bin/bash拷贝一个为/opt/test_sh,并查看一下当前的安全上下文
se10.png

     由于在SELinux的默认安全策略里,使用svirt_t类型的入口程序必须类型为qemu_exec_t,这里修改一下test_sh的类型:
se11.png

MCS为s0:c0,c1的操作
     以特定的SELinux安全策略来运行,这里切换一下类型为svirt_t和MCS为s0:c0,c1,并查看当前用户的安全上下文以确认,之后通过echo命令向/tmp/test文件(由于SELinux安全策略限制,此时只能向/tmp目录下写新建文件)里随便写内容,写成功后再查看一下/tmp/test的安全上下文。MCS都是一致的
se12.png

MCS为s0:c0,c2的操作
      再以特定的SELinux安全策略来运行,这里切换一下类型为svirt_t和MCS为s0:c0,c2,并查看当前用户的安全上下文以确认,之后通过echo命令向/tmp/test文件(这个文件是前一步创建的)里随便写内容,由于安全策略的限制会写入失败,提示:Permission denied(下图红线部分)。确认文件MCS与当前环境的MCS是不一致的。
se13.png


来点感动自己的鸡汤


      所有被SELinux安全策略阻止的操作都会有相应的日志记录,当系统auditd服务启动时会记录在audit.log日志,否则记录在message日志里。
se14.png

XEN 、 VMware ESXi、Hyper-V 以及 KVM 特点比较

OpenSkill 发表了文章 0 个评论 13115 次浏览 2015-08-22 16:55 来自相关话题

XEN 与 VMware ESXi,Hyper-V 以及 KVM 特点比较       XEN 有简化虚拟模式,不需要设备驱动,能够保证每个虚拟用户系统相互独立,依赖于 service domains 来完成一些功能; Vmware ...查看全部
xnh.png


XEN 与 VMware ESXi,Hyper-V 以及 KVM 特点比较


      XEN 有简化虚拟模式,不需要设备驱动,能够保证每个虚拟用户系统相互独立,依赖于 service domains 来完成一些功能; Vmware ESXI 与 XEN 比较类似,包含设备驱动以及管理栈等基本要素,硬件支持依赖于 VMware 创建的驱动; Hyper-V 是基于 XEN 管理栈的修改; KVM 与 XEN 方式不同,KVM 是以 Linux 内核作为管理工具。
虚拟机的体系结构


XEN 体系结构


XEN 体系结构图如下:
xk1.png

      Xen是一个开放源代码虚拟机监视器,由剑桥大学开发。Xen的缺点是操作系统必须进行显式地修改(“移植”)以在Xen上运行(但是提供对用户应用的兼容性),所以比较麻烦。使得Xen无需特殊硬件支持,就能达到高性能的虚拟化。Linux的官方内核在较早之前已经去掉了对Xen的支持。

      一个 XEN 虚拟机环境主要由以下几部分组成:
XEN Hypervisor; Domain 0 —— Domain Management and Control(XEN DM&C); Domain U Guest(Dom U) PV Guest HVM Guest
       Xen 三部分组成之间关系图
xk2.png

XEN Hypervisor :
XENHypervisor 是介于操作系统和硬件之间的一个软件描述层。它负责在各个虚拟机之间进行 CPU 调度和内存分配。XEN Hypervisor 不仅抽象出虚拟机的硬件,同时还控制着各个虚拟机的执行。XEN Hypervisor 不会处理网络、存储设备、视频以及其他 I/O.
Domain 0:
Domain 0 是一个修改过的 Linux kernel,是唯一运行在 Xen Hypervisor 之上的虚拟机,它拥有访问物理 I/O 资源的权限,同时和系统上运行的其他虚拟机进行交互。Domain 0 需要在其它 Domain 启动之前启动。
Domain U:
运行在 Xen Hypervisor 上的所有半虚拟化(paravirtualized)虚拟机被称为“Domain U PV Guests”,其上运行着被修改过内核的操作系统,如 Linux、Solaris、FreeBSD 等其它 UNIX 操作系统。所有的全虚拟化虚拟机被称为“Domain U HVM Guests”,其上运行着不用修改内核的操作系统,如 Windows 等。


Hyper-V 体系结构


Hyper-V 体系结构图如下:
xk3.png

      Hyper-V 是微软提出的一种系统管理程序虚拟化技术,采用微内核的架构,兼顾了安全性和性能的要求。Hyper-V 底层的 Hypervisor 运行在最高的特权级别下,微软将其称为 ring -1(而 Intel 则将其称为 root mode),而虚机的 OS 内核和驱动运行在 ring 0,应用程序运行在 ring 3 下,这种架构就不需要采用复杂的 BT(二进制特权指令翻译)技术,可以进一步提高安全性。从架构上讲 Hyper-V 只有“硬件-Hyper-V-虚拟机”三层,本身非常小巧,代码简单,且不包含任何第三方驱动,所以安全可靠、执行效率高,能充分利用硬件资源,使虚拟机系统性能更接近真实系统性能。

      Hyper-V 支持分区层面的隔离。分区是逻辑隔离单位,受虚拟机监控程序支持,并且操作系统在其中执行。Microsoft 虚拟机监控程序必须至少有一个父 / 根分区,用于运行 64 位版本的 Windows Server 2008 操作系统。虚拟化堆栈在父分区中运行,并且可以直接访问硬件设备。随后,根分区会创建子分区用于承载来宾操作系统。根分区使用虚拟化调用应用程序编程接口 (API) 来创建子分区。

     分区对物理处理器没有访问权限,也不能处理处理器中断。相反,它们具有处理器的虚拟视图,并运行于每个来宾分区专用的虚拟内存地址区域。虚拟机监控程序负责处理处理器中断,并将其重定向到相应的分区。Hyper-V 还可以通过输入输出内存管理单元 (IOMMU) 利用硬件加速来加快各个来宾虚拟地址空间相互之间的地址转换。IOMMU 独立于 CPU 使用的内存管理硬件运行,并用于将物理内存地址重新映射到子分区使用的地址。从系统的结构图,我们可以看出来 Hyper-V 与 Xen 的架构很相似。


Vmware ESXI 体系结构


Vmware ESXI 体系结构图如下:
xk4.png

      VMWare (Virtual Machine ware)是一个“虚拟PC”软件公司。它的产品可以使你在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。与“多启动”系统相比,VMWare采用了完全不同的概念。多启动系统在一个时刻只能运行一个系统,在系统切换时需要重新启动机器。VMWare是真正“同时”运行,多个操作系统在主系统的平台上,就象标准Windows应用程序那样切换。而且每个操作系统你都可以进行虚拟的分区、配置而不影响真实硬盘的数据,你甚至可以通过网卡将几台虚拟机用网卡连接为一个局域网,极其方便。安装在VMware操作系统性能上比直接安装在硬盘上的系统低不少,因此,比较适合学习和测试。

      由上图我们可以看出来管理工具也是直接嵌入到了 ESXi vmKernel 中,没有再分化出单独的管理工具,这一点与 Xen 是相区别的。


KVM 体系结构


KVM 体系结构图如下:
xk5.png

      KVM 是一个独特的管理程序,通过将 KVM 作为一个内核模块实现,在虚拟环境下 Linux 内核集成管理程序将其作为一个可加载的模块可以简化管理和提升性能。在这种模式下,每个虚拟机都是一个常规的 Linux 进程,通过 Linux 调度程序进行调度。
    
      KVM是指基于Linux内核(Kernel-based)的虚拟机(Virtual Machine)。KVM最大的好处就在于它是与Linux内核集成的,所以速度很快。KVM的宿主操作系统必须是Linux,支持的客户机操作系统包括Linux、Windows、Solaris和BSD,运行在支持虚拟化扩展的x86和x86_64硬件架构上,这意味着KVM不能运行在老式CPU上,新CPU如果不支持虚拟化扩展也不能运行(如英特尔的Atom处理器)。


KVM、Xen、VMWare的对比


xk6.png

通过以上四种虚拟机的体系结构图,我们可以看出他们在整个系统中的位置,以及相互之间的区别。
本文基于互联网整理转载分享  参考原文1  参考原文2

使用elasticsearch的marvel插件sense报错

Ansible 回复了问题 2 人关注 2 个回复 7111 次浏览 2015-08-21 20:45 来自相关话题

虚拟机是怎么实现的?

OpenSkill 发表了文章 0 个评论 3199 次浏览 2015-07-25 21:55 来自相关话题

      1997年,斯坦福的Mendel Rosenblum带着Edouard Bugnion, Scott Devine在SOSP上发了篇论文,叫做Disco: running commodity operating systems on scalabl ...查看全部
      1997年,斯坦福的Mendel Rosenblum带着Edouard Bugnion, Scott Devine在SOSP上发了篇论文,叫做Disco: running commodity operating systems on scalable multiprocessors (http://www.stanford.edu/class/cs240/readings/disco.pdf)。发了之后,我想他们应该是觉得这个主意太好了,就开了家公司,名叫VMWare。
 
      这篇论文起名叫Disco(迪士高)是因为虚拟机本身不是一个新的东西,大概在上世纪70年代就有了。作者们为了表示敬意,或者是显示这是一个复古的东西,就把这个项目取名为disco。这篇论文介绍了虚拟机关键技术,用来回答这个问题再合适不过了。(多年之后,OSDI上的另一篇论文(Memory Resource Management in VMware ESX Server)介绍了一些VMWare的改进。近年来论文越来越多。)
 
      当初他们为什么要做虚拟机?简单说就是,新硬件层出不穷,但是OS赶不上。当初,他们想在Stanford的ccNUMA机器上跑IRIX(一个操作系统)。可是IRIX跑不起来。他们觉得修改OS或者写一个新的OS太难了(因为一个操作系统从出生到成熟要很长的时间,无数BUG要FIX,无数的新功能要增加。。。那样人家博士要怎么毕业。。)。所以,他们决定用虚拟机。
 
      对于他们的项目,虚拟机大致有下面这些好处:
1、只要对商业OS做简单地修改,就能让他们在多个VM(Virtual Machine)间共享内存。
2、Flexible。除了论文里的IRIX,实际上其他的OS也能跑。
3、扩展性好。系统可以以虚拟机为单位扩展。
4、fault-containment。每一个VM都是一个几乎独立的个体,一个坏了,不影响另一个。
5、新老软件可共存。比如,新的软件只能在Linux-3.15跑。你可以用两个VM,一个是Linux2.6,一个是Linux-3.15。
      这篇文章回答下面这几个实现虚拟技术的关键问题:
1、VMM(Virtual Machine Monitor, 或者叫hypervisor)是怎么管住Guest OS的?或者说,皇上(VMM)是怎么防止大臣(OS)夺权的?
2、有那么多个操作系统一起运行,内存是怎么管理的?
3、多个VM之间是怎么分享资源的?或者说,1GB内存怎么当2GB用?


VMM(Virtual Machine Monitor, 或者叫hypervisor)是怎么管住Guest OS的?或者说,皇上(VMM)是怎么防止大臣(OS)夺权的?


k1.png

      要理解VMM是怎么工作的,我们得先了解没有VMM的时候,系统是怎么工作的。在没有VMM的时候,计算机系统中的”应用”可分为用户进程(比如VIM)和操作系统。他们分别运行在不同的模式中(mode)。我们用一个类比来解释系统中的模式(mode)。模式这个机制是用来限制一段指令所在的环境的权限的,它是需要处理器的支持的。MIPS结构当时有三个模式:用户模式(user mode),长官模式(supervisor mode,原谅我的翻译…)和内核模式(kernel mode)。这三种模式分别对应于人类社会里的民宅、官衙和金銮殿。显而易见,在金銮殿里的人拥有的权限最高,民宅里的最低。我们可以说,在没有VMM时,用户进程住在民宅里,县衙空着,OS住在金銮殿里(如图)。用户可以直接做一些不用什么特权的事情(unprivileged instructions),比如计算1+1。做这些事情不经过OS。但是,有些要特权才能做的事情,一定要经过OS。比如保存正在编辑的文档到硬盘。访问硬盘是特权操作是因为硬盘是共享的资源,要有人管着,不能让人乱来。试想,要是人人都能读写档案馆的档案,那不就乱套了。
k2.png

      VIM(用户进程)不能直接写磁盘上的文件。VIM必须请求在金銮殿里的操作系统来做。怎么请求呢?通过系统调用(system call)。系统调用的过程是这样的:比如要调用的是write(fd, buf, len, off),首先把fd, buf, len, off放到stack里,然后再把一个write()函数对应的号码(system call number)放到stack里,最后调用一个特殊的指令使CPU进入内核模式(图中的圈1)。在x86结构中,这个指令是int(中断)。在MIPS结构中,这个指令是trap。这个指令会引导CPU执行一段代码(trap handler),依照stack里的system call number 找到对应的函数(在这里是write()的实现),然后调用这个函数(函数的参数在刚才的stack里)。在这里函数里,操作系统调用文件所在的文件系统里的write()实现,文件系统使用磁盘的驱动来最终实现。所以文件的操作完成后,操作系统调用与trap功能相反的一个指令,回到VIM程序的指令里(图中的圈2)。
k3.png

      操作系统维护自己的特权的过程大概就是这样。但是这个特权等级到底是怎么实现的呢?我们可以想像CPU里有一个特权状态(privileged state bit)。状态为开(On)的时候,CPU的特权等级高,你可以做任何事,包括转到低特权状态。关(Off)的时候,你所能做的事情就所限了。那怎么从off状态转到on状态呢?你必须到执行CPU的特殊指令,这个指令会把你带到一个特定的地方执行操作系统的指令,检查你是不是有进入高特权状态的权限。这就像是在机场,你可以很容易地从登机口到售票大厅,可是你要从售票大厅到登机口,你就得过安检。另外,为什么操作系统就能有高特权呢?Hmm…因为操作系统一开始就把那占了,之后运行的应用程序就只能听它使唤了。
 
      现在,终于要说VMM(virtual machine monitor, 或者叫hypervisor)是怎么实现的了。如下图:
k4.png

      现在VMM进了金銮殿,有了最高的特权。操作系统被放到了官衙里(但是它自己并不知道)。用户进程还是在民宅里住着。比如,现在用户进程VIM调用write(),会发生什么?用户进程会trap到VMM(拥有kernel mode)里去。但是,VMM并不知道如何处理write()。所以,VMM接下来会调用OS的里对应的trap handler,这个handler会执行文件系统的write(),然后用驱动来写磁盘。这一切的操作都在VMM的监视下进行。怎么监视?操作系统实际上是在虚拟CPU(Virtual CPU)上运行的。VCPU有一套自己的(假的)寄存器。VMM盯着这些寄存器。在操作系统的trap handler完成之后,它会调用trap的反操作(想返回user mode)。但是,这个操作实际上回使CPU回到VMM,由VMM最后返回到用户进程。
 
      为什么VMM能够知道操作系统的trap handler在哪?系统中先有VMM。当你在VMM上安装操作系统的时候,操作系统会尝试调用特权指令安装trap handler。因为有最高特权的VMM实际上是监视着这一切的,所以它可以记录下trap handler的位置就行了。
 
      总的说来,虚拟机占据了CPU的最高特权,使得在更低特权等级的操作系统无法进行有害操作。


有那么多个操作系统一起运行,内存是怎么管理的?


      在没有VMM的时候,系统中有两种内存地址:虚拟地址(virtual address)和物理地址(physical address)。从虚拟地址到物理地址的转换有两种方式。方式一:在TLB(translate lookside buffer,硬件实现)查找。方式二:在页表(page table)中查找,找到之后把结果放到TLB中去。系统会先尝试方式一,要是找不到(TLB miss),就用方式二。
k5.png

      在有了VMM之后,系统中有三种内存地址:虚拟地址(virtual address),物理地址(physical address)和机器地址(machine address)。机器地址才是真正与内存条上的地址一一对应的。物理地址只是操作系统认为的物理地址。
k6.png

      当操作系统试着要使用特权指令来完成一个虚拟地址到物理地址的转换时(TLB miss),VMM就介入了(VMM监视着所有对特权寄存器的操作)。VMM会先使用操作系统内的代码来先完成虚拟地址到物理地址的转化(因为VMM并不知道这个映射关系)。然后,操作系统认为自己已经完成了转化,尝试去更新TLB(特权操作)。这个时候,VMM会介入,用一个叫个pmap的映射表找到物理地址对应的机器地址,用机器地址替换掉物理地址,然后把TLB更新为虚拟地址到机器地址的映射。之后,所有对这个虚拟地址的访问都会被转换为对相应机器地址的访问。


多个VM之间是怎么分享资源的?或者说,1GB内存怎么当2GB用?


      我们知道,每一个虚拟机都要占用大量的内存空间。在内存有限的情况下,怎么在一台机器运行更多的虚拟机?幸运的是,不用的虚拟机之间在内存中数据可能会完全一致(比如,系统文件在内存中的缓存)。如要我们可以只在内存中保留一份数据,我们就行节省很多空间。Disco使用虚拟IO设备和虚拟网络设备来节省内存空间。
k7.png

虚拟IO设备:
当两个虚拟机从同一个磁盘上读同一个文件时,VMM会intercept DMA,然后就会发现这两个VM在使用同样的数据。这份数据只需要在机器内存里保存一份,然后修改pmap,使得两个VM的物理地址指向同一个机器地址就可以了。当任何一个VM更新这份数据,VMM会给它一份新的拷贝,原来的那份不做更改(copy on write机制)。
虚拟网络设备:
当使用NFS从VM1向VM2复制文件时,文件并没有被真正地复制。虚拟网络设备会更新VM2上的pmap,使之指向在内存中的文件,使得VM2上的操作系统认为自己已经有了这个文件。
后来,VMWare还有用hash来找相同的内存页然后再共享的技术。
原文地址

为什么运行docker命令返回"/var/run/docker.sock"权限拒绝?

Ansible 发表了文章 0 个评论 17014 次浏览 2015-07-24 00:51 来自相关话题

现象# docker ps FATA[0000] Get http:///var/run/docker ...查看全部

现象

# docker ps
FATA[0000] Get http:///var/run/docker.sock/v1.16/containers/json:
dial unix /var/run/docker.sock: permission denied.
Are you trying to connect to a TLS-enabled daemon without TLS?

分析解决

首先你得确认/var/run/docker.sock文件是否存在


# ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 sty 28 11:53 /var/run/docker.sock

解决方案现在很清楚了,通过添加你的登陆用户到docker用户组来解决这个问题,如下所示:


# sudo gpasswd -a ${USER} docker

/etc/group文件内容应该可以看出变化了


# cat /etc/group | grep ^docker

下面我们打开一个新的终端来检查登陆用户是否加入到了docker用户组,应该存在于如下命令结果中


# groups

如果你的登陆用户还没有加入到docker用户组,你可以尝试重启机器。如果你可以正常重启docker容器,就不需要重启服务器了。


# sudo service docker.io restart

然后你运行docker ps应该就没有问题了!