数据结构论坛

首页 » 分类 » 问答 » 深入解析Docker架构原理
TUhjnbcbe - 2024/10/12 16:26:00
中科公益爱心 http://www.jk100f.com/baidianfengzixun/zhiliaowuqu/43734.html

深入解析Docker架构原理

Docker年08月10日

一、Docker简介

什么是Docker?Docker的英文翻译是”搬运工“的意思,他搬运的东西就是我们常说的集装箱Container,Container里面装的是任意类型的App,我们的开发人员可以通过Docker将App变成一种标准化的、可移植的、自管理的组件,我们可以在任何主流的操作系统中开发、调试和运行。

从概念上来看Docker和我们传统的虚拟机比较类似,只是更加轻量级,更加方便使用

Docker和虚拟机主要的区别有一下几点:

1.虚拟化技术依赖的是物理CPU和内存,是硬件级别的;而我们的Docker是构建在操作系统层面的,利用操作系统的容器化技术,所以Docker同样的可以运行在虚拟机上面2.虚拟机中的系统就是我们常说的操作系统镜像,比较复杂;而Docker比较轻量级,我们可以使用Docker部署一个独立的Redis,就像类似于在虚拟机当中安装一个Redis应用,但是我们用Docker部署的应用是完全隔离的。3.在传统的虚拟化技术是通过快照来保存的;而Docker引用了类似于源码的管理机制,将容器的快照历史版本一一记录下来,切换成本之低4.传统的虚拟化技术在构建系统的时候非常复杂;而Docker可以通过一个简单的Dockerfile文件来构建整个容器,更重要的是Dockerfile可以手动编写,这样应用开发人员可以通过发布Dockerfile来定义应用的环境和依赖,这样对于持续交付非常有利

DockerEngineDockerEngine是一个C/S架构的应用程序,主要包含下面几个组件;

常驻后台进程Dockerd一个用来和Dockerd交互的RESTAPIServer命令行CLI接口,通过和RESTAPI进行交互

Docker架构

Docker使用了C/S体系架构,Docker客户端与Docker守护进程通信,Docker守护进程负责构建,运行和分发Docker容器。Docker客户端和守护进程可以在同一个系统上运行,也可以将Docker客户端连接到远程Docker守护进程。Docker客户端和守护进程使用RESTAPI通过UNIX套接字或网络接口进行通信。

DockerDamonDockerD用来监听DockerAPI的请求和管理Docker对象,比如镜像、容器、网络和VolumeDockerClientdockerclient是我们和Docker进行交互的最主要的方式方法,比如可以通过dockerrun来运行一个容器,然后我们的这个client会把命令发送给上面的DockerDockerRegistry用来存储Docker镜像的仓库,DockerHub是Docker官方提供的一个公共仓库,而且Docker默认也是从DockerHub上查找镜像的,当然你也可以很方便的运行一个私有仓库,当我们使用dockerpull或者dockerrun命令时,就会从我们配置的Docker镜像仓库中去拉取镜像,使用dockerpush命令时,会将我们构建的镜像推送到对应的镜像仓库中Images镜像,镜像是一个制度模板,带有Docker容器的说明,一般来说的,镜像会基于另外的一些基础镜像上面安装一个Nginx服务器,这样就可以构建一个属于我们自己的镜像了Containers容器,容器是一个镜像的可运行的实例,可以使用DockerRESTAPI或者CLI来操作容器,容器的实质是进程,但与直接在宿主执行的实例进程不同,容器进程属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间、甚至自己的用户ID。容器内的经常是运行在一个隔离的环境里,使用起来,就好像在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全

二、Docker核心概念

①Dockernamespace

Linux内核2.4.19中开始陆续引用了namespace概念。目的是将某个特定的全局系统资源(globalsystemresource)通过抽象方法使得namespace中的进程看起来拥有它们自己的隔离的全局系统资源实例命名空间是Linux内核强大的特性。每个容器都有自己的命名空间,运行在其中的应用都是在独立操作系统中运行一样。命名空间保证了容器之间彼此互不影响

②DockerCGroups

Docker容器使用Linuxnamespace来隔离其运行环境,使得容器中的进程看起来就像在一个独立的环境中运行。但是光有运行环境隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络、磁盘、CPU以及内存等。关于其目的,是为了防止它占用了太多的资源而影响到其它进程;另一方面,在系统资源耗尽的时候,Linux内核会触发OOM(outofmemorykiller,OOM会在系统内存耗尽的情况下跳出来,选择性的干掉一些进程以求释放一些内存)这会让一些被杀掉的进程成了无辜的替死鬼,因此为了让容器中的进程更加可控,Docker使用Linuxcgroups来限制容器中的进程允许使用的系统资源LinuxCgroup可以让系统中所运行任务(进程)的用户定义组分配资源—比如CPU时间、系统内存、网络带宽

③DockerUnionFS

UnionFS顾名思义,可以把文件系统上多个目录(分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。

要理解unionFS,我们首先需要先了解bootfs和rootfs1.bootfilesystem(bootfs)包含操作系统bootloader和kernel。用户不会修改这个文件系统,一旦启动成功后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放内存。同样的内核版本不同Linux发行版,其bootfs都是一直的2.rootfilesystem(rootfs)包含典型的目录结构(/dev/,/proc,/bin,/etc,/lib,/usr,/tmp)Linux系统在启动时,rootfs首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了

假设Dockerfile内容如下

FROMubuntu:14.04ADDrun.sh/VOLUME/dataCMD[./run.sh]联合文件系统对应的层次结构如下图所示

图中的顶上两层,是Docker为Docker容器新建的内容,而这两层属于容器范畴。这两层分别为Docker容器的初始层(initLayer)与可读写层(Read-writeLayer)

初始层:大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等。读写层:Docker容器内的进程只对可读可写层拥有写权限,其它层进程而言都是只读的(Read-Only)。关于VOLUME以及容器的host、hostname、resolv.conf文件都会挂载到这里

FROMubuntu:14.04设置基础镜像,此时会使用Ubuntu:14.04作为基础镜像ADDrun.sh/将Dockerfile所在目录下的run.sh加至镜像的根目录,此时新一层的镜像只有一项内容,即根目录下的run.shVOLUME/data设置镜像的存储,此VOLUME在容器内部的路径为/data。此时并未在新一层的镜像中添加任何文件,但是更新了镜像的json文件,以便通过此镜像启动容器时获取这方面的信息(下面会有详细的介绍)CMD[“./run.sh”]设置镜像的默认执行入口,此命令同样不会在新建镜像中添加任何文件,仅仅在上一层镜像json文件的基础上更新新的镜像的json文件三、Docker存储驱动

Docker最开始采用AUFS作为文件系统,也得益于AUFS分层的概念,实现了多个Container可以共享一个image。但是由于AUFS未并入Linux内核,且只支持Ubuntu,考虑到兼容性问题,在Docker0.7版本中引入了存储驱动,目前,Docker支持AUFS、Btrfs、Devicemapper、OverlayFS、ZFS五种存储驱动。

原理说明

写时复制(CoW)所有驱动都用到的技术————写时复制,Cow全称copy-on-write,表示只是在需要写时才去复制,这个是针对已有文件的修改场景。比如基于一个image启动多个Container,如果每个Container都去分配一个image一样的文件系统,那么将会占用大量的磁盘空间。而CoW技术可以让所有的容器共享image的文件系统,所有数据都从image中读取,只有当要对文件进行写操作时,才从image里把要写的文件复制到自己的文件系统进行修改。所以无论有多少个容器共享一个image,所做的写操作都是对从image中复制到自己的文件系统的副本上进行,并不会修改image的源文件,且多个容器操作同一个文件,会在每个容器的文件系统里生成一个副本,每个容器修改的都是自己的副本,互相隔离,互不影响。使用CoW可以有效的提高磁盘的利用率。

用时分配(allocate-on-demand)写是分配是用在原本没有这个文件的场景,只有在要新写入一个文件时才分配空间,这样可以提高存储资源的利用率。比如启动一个容器,并不会因为这个容器分配一些磁盘空间,而是当有新文件写入时,才按需分配新空间。

存储驱动介绍

AUFS

AUFS(AnotherUnionFS)是一种UnionFS,是文件级的存储驱动。AUFS能透明覆盖一或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在科协层。在Docker中,只读层就是image,可写层就是Container。

OverlayFS

OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性;1)更简单地设计;2)从Linux3.18开始,就加入了Linux内核主线;3)速度更快因此,OverlayFS在Docker社区

1
查看完整版本: 深入解析Docker架构原理