加入收藏 | 设为首页 | 会员中心 | 我要投稿 泉州站长网 (https://www.0595zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 云计算 > 正文

细说构建微服务的开源技术之 Docker

发布时间:2022-06-01 11:19:32 所属栏目:云计算 来源:互联网
导读:Docker 是最近在云计算领域出现的新技术。目前,Docker 和以其为代表的容器技术的热度已经改过了之前的 OpenStack。Docker 以及其所代表的容器技术的流行,即使因为软件技术的进步,更是由于其符合云计算对软件领域所带来新思想。在如今的互联网和企业应用开

 
五、Docker 的实现
 
接下来要介绍 Docker 所使用的几个重要技术:namespaces、cgroups、LXC 和 AUFS。
 
namespaces
 
Linux 容器通过 Kernel 的 namespaces 技术,为一个或一组进程创建独立的pid、net等 namespaces,从而与其它进程相互隔离。下面将介绍 namespaces 都会对哪些资源进行分组控制以实现相互隔离:
 
pidnamespace
 
不同容器中进程是通过 pid namespace 隔离开的,且不同容器中可以有相同 pid。具有以下特征:
 
每个 namespace 中的 pid 是有自己的 pid=1 的初始进程
每个 namespace 中的进程只能影响自己的同一个 namespace 或子 namespace 中的进程
因为/proc包含正在运行的进程,因此在容器中的/proc目录只能看到自己 namespace 中的进程
因为 namespace 允许嵌套,父 namespace 可以影响子 namespace 的进程,所以子 namespace 的进程可以在父 namespace 中看到,但是具有不同的 pid
netnamespace
 
如果仅仅隔离了进程空间,还是会有问题。比如如果你在多个容器中运行 Apache 服务器,那只能有一个服务器使用 80 端口。对此你有两个选择,让每个 Apache 服务器使用不同的端口,或者隔离网络空间。
 
netnamespace 使得每个容器都有自己的loloopback 接口。同时,还有一个通常被命名为eth0的网络接口,通过这个接口,容器可以和 host 或其它容器进行通信。eth0interface 会被分配一个 172.17.0.XXX 的 IP 地址,容器之间可以通过这个 IP 地址相互通信。
 
同时,容器的这个eth0网卡在 Host 中的名字是一个类似vethdfb7的略显古怪的名字。这个网卡会和docker0网卡桥接在一起。
 
ipcnamespace
 
ipcnamepace 对于不熟悉 Unix 的人(包括之前的我)吸引力不是很大。毕竟,现在进程之间的通信多数是通过网络实现的。但实际上,Unixipc有着十分广泛的应用,比如管道就是ipc的一种。对ipc就不做过多介绍了,总之 Linux Kernel namespaces 可以让不同容器的ipc相互隔离。
 
mntnamespace
 
如名所示,mntnamespace 是处理挂载点的。mntnamespace 可以使不同容器拥有不同的挂载的文件系统和 root 目录。在一个mntnamespace 挂载的文件系统只能被同一个 namespace 里的进程所见。
 
utsnamespace
 
utsnamespace 用于控制 hostname 的隔离。
 
有了以上几种隔离,一个容器就可以对外展现出一个独立计算机的能力,并且不同容器内的资源在操作系统层面实现了隔离。 然而不同 namespace 之间资源还是相互竞争的,仍然需要类似 ulimit 来管理每个容器所能使用的资源 - Docker 采用的是 cgroup。
 
参考文献
1 http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part
 
cgroups
 
namespaces 对进程分组以实现资源隔离,但这隔离还是不够的。一个进程可以通过占用过度的硬件资源的方式去影响另一个分组中的进程。所以,要想实现完善的资源隔离,不仅要对资源分组,还要能对这一组内的进程所使用的资源进行约束。cgroups 就是用来实现这个目的的。cgroups 的全称是 Control Groups,在 2003 年由 Google 的工程师实现,在 2007 年加入 Linux Kernel。cgroups 可限制进程对 CPU、内存、块存储和网络的使用。这里不对 cgroups 的使用方法作介绍,感兴趣的同学可以参考如下:
 
SysAdminCasts.com: Introduction to Linux Control Groups (Cgroups)
Docker.com: Runtime Metrics
虽然 cgroups 提供了对 IO 资源使用的约束的功能,但 Docker 目前(1.3)尚未提供支持。
 
内存
 
cgroups 可以控制进程所能使用的内存和 swap 空间的大小。通过-m参数,Docker 可以限制容器所能使用的最大内存数:
 
复制
docker run -m 128m -d container_img cmd_name
1.
CPU
 
Docker 可以通过 cgroups 限制容器所能使用的 CPU 资源。在执行docker run命令时可以通过参数--cpu-shares(-c)、--cpuset对 CPU 做出限制。
 
--cpu-shares(-c)
 
-c设置的是一个相对值,这个值将影响到此容器内的进程所能使用的 CPU 时间片。新运行的 Docker 容器默认使用 1024,对一个单独的 Docker 的容器来说,这个值没有任何意义。当启动两个 Docker 容器的时候,这两个容器将平分 CPU 时间片。如果两个容器,一个不指定-c,另一个设置为-c 512,那前者将使用大致 2/3 的计算能力,另一个将使用大致 1/3 的计算能力。但是-c对容器所能使用 CPU 的运行频率等没有任何影响。
 
--cpuset
 
可让你指定 Docker 容器中的进程运行在第几块 CPU 上。后面跟一个数组或用逗号分隔的多个数字0,1,2。比如下列命令将会使你的容器运行在第一个 CPU 核心上。
 
复制
docker run -i -t --cpuset 0 ubuntu:14.04
 
注:cgroups 使用的是一种伪文件系统形式的接口。这个伪文件系统实际存在于内存中,但映射在目录中。用户通过在这个目录中写入文件来对 cgroups 进行操作。
 
AUFS
 
注:最新的 Docker 使用 BTRFS 替代 AUFS,但所要实现的功能相同
 
AUFS 的全称是 Another Union File System。AUFS(包括其它 UFS)的一个重要能力是能使两个目录结构合二为一。这有什么用呢?Docker 的镜像都是有多个层组成的,最上层是一个可读写的,而下面的层则是只读的。通过 AUFS 的目录融合的能力,实现了既可随意读写,又保证了下层的内容安全的目的。见下图可以有一个形象的认识。下图中的 bootfs 层包含了 Linux Kernel。在其上是某个特定的 Linux 发行版本的不同于 Kernel 的文件层,在下图中是 Debian。再往上有包含 emacs 和 Apache 的两个层。这些层在容器运行时都是只读的。最上面就是容器运行时可读写的层了。上面的层可以只读访问下面的层里的文件。这样的层次结构可以通过 Dockerfile 来创建。
 
那这样的一个结构有什么样的好处呢?主要有下面几点:
 
节省磁盘和内存的存储空间
 
节省磁盘存储空间是因为不同的容器镜像之间可以共享相同的层。例如,两个不同的 Java 应用的容器镜像,它们都是基于 Ubuntu 14.04 和 JDK7。那在同一台 Host 中,这两个镜像就会使用相同的 Ubuntu 14.04 和 JDK7 的层。
 
节省内存空间是因为 Linux 为了加快磁盘访问,会将一些磁盘上的文件加载到内存中。所以,节省磁盘空间的同时也就可以间接地解释内存的使用。
 
加快部署速度
 
同样,可共享的镜像层能加快部署速度。因为相同的层不用被重复下载部署。
 
允许对文件任意改动
 
上传可读写的层可以对下面的只读层中的文件做任意修改,但这其实是 copy-on-write,所以,这种修改对下面的层其实是安全的。
 

(编辑:泉州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!