Docker容器技术与微服务解决方案.docx
- 文档编号:6959308
- 上传时间:2023-01-13
- 格式:DOCX
- 页数:10
- 大小:297.64KB
Docker容器技术与微服务解决方案.docx
《Docker容器技术与微服务解决方案.docx》由会员分享,可在线阅读,更多相关《Docker容器技术与微服务解决方案.docx(10页珍藏版)》请在冰豆网上搜索。
Docker容器技术与微服务解决方案
Docker容器技术与微服务解决方案
一、前言
Docker是最近在云计算领域出现的新技术。
目前,Docker和以其为代表的容器技术的热度已经改过了之前的OpenStack。
Docker以及其所代表的容器技术的流行,即使因为软件技术的进步,更是由于其符合云计算对软件领域所带来新思想。
在如今的互联网和企业应用开发领域,微服务和DevOps是两个思想颇为深入人心。
而Docker技术的出现和其对整个容器技术及其生态圈发展的促进,解决了这个微服务和DevOps这两个思想实践中的很多难题,使得前面两种思想大规模地实现成为了可能。
所以,我们有必要地深入了解一下Docker这个技术,看看它会对云计算时代的软件开发产生什么样的影响。
本文将介绍如下内容
1.什么是容器技术
2.什么是Docker
3.Docker是如何实现的
4.为什么要使用Docker
至于Docker的用法,不在这里做介绍。
Docker的入门使用,可以前往Docker官网。
各种高级用法、技巧、经验,可以前往技术网站CSDN、InfoQ和CoreOS、CenturylinkLabs等这些使用Docker的云计算厂商的网站。
二、容器技术简介
容器技术有时会被称为轻量化虚拟技术。
但不同于基于Hypervisor的传统虚拟化技术,容器技术并不会虚拟硬件。
容器本身和容器内的进程都是运行在宿主Linux系统的内核之上。
但与直接运行的进程不同,运行在容器内的进程会被隔离和约束。
从而以直接运行的高效实现了虚拟技术的大部分效果。
容器技术的历史
容器技术并不是一个新鲜事物,早在1979年出现的在Unix系统中的chroot便是容器技术的雏形。
而随后出现的BSDJail、SolarisContainers和OpenVZ都算是容器技术的先驱。
但容器技术开始普及却是在2007年,这一年Google贡献出cgroups,并且从2.6.4开始,Linux内核包含了这一组件,随后容器技术开始逐渐普及。
但容器技术真正大放异彩则要等到2013年Docker0.10版本发布。
三、Docker简介
在Docker出现之前,不仅Google大量使用容器技术,国内的如淘宝也使用容器技术搭建了自己的应用平台。
影响力最大的开源PaaS解决方案CloudFoundry,也在使用自己的容器解决方案Warden。
而Docker发布之后,因其极有可能成为未来企业应用、互联网应用和云计算应用的开发、部署的中心角色,所以得到了几乎所有的业界大佬的追捧,Google、VMware、微软、RedHat等等都已全力推动Docker技术的发展。
同时,围绕Docker,出现了一系列以CoreOS为代表的新技术。
Docker的出现并非创造了一个新的容器技术,而是在LXC(LinuXContainer)注1、cgroups、namespaces技术之上所构建的一种技术:
∙Docker简化了容器的运行:
它通过一个简单的命令就能够运行起一个容器dockerrun[params][image][command(optional)]
∙Docker简化了容器镜像的构建和分发:
Docker提供了Dockerfile和dockercommit两种方式构建镜像,并且提供了Dockerimageregistry机制以保存和分发镜像
形象地解释
打一个比方,集装箱(容器)对于远洋运输(应用运行)来说十分重要。
集装箱(容器)能保护货物(应用),让其不会相互碰撞(应用冲突)而损坏,也能保障当一些危险货物发生规模不大的爆炸(应用崩溃)时不会波及其它货物(应用)但是把货物(应用)装载在集装箱(容器)中并不是一件简单的事情。
而出色的码头工人(Docker)的出现解决了这一问题。
它(Docker)使得货物装载到集装箱(容器)这一过程变得轻而易举。
对于远洋运输(应用运行)而言,用多艘小货轮(虚拟机)代替原来的大货轮(实体机)也能保证货物(应用)彼此之间的安全,但是和集装箱(容器)比,成本过高,但适合运输某些重要货物(应用)。
四、Docker的组成
Docker主要有DockerHub和Docker引擎组成。
前者是Docker官方提供的容器镜像仓库;后者运行在宿主机上,可分为服务器端和客户端两部分。
服务器端负责构建、运行和分发Docker容器等重要工作,客户端负责接收用户的命令和服务程序进行通信。
除了这两部分,Dockerfile也是不得不提的,它虽然不能算作一个独立的组件,但是却是Docker中很重要的部分。
通过Dockerfile,技术人员可以创建自己的Docker容器镜像。
Dockerfile起到了连接开发与运维的桥梁的作用,非常符合现在DevOps的潮流。
DockerHub
DockerHub是Docker官方所提供的一个镜像仓库。
在运行Docker容器或构建自己的容器镜像时,都会直接或间接地使用到DockerHub中的镜像。
DockerEngine
DockerEngine承载了Docker容器在宿主机上运行启停、Docker镜像的构建等功能等功能。
是我们接触最多的组件。
接下来简单介绍一下Docker常见的命令:
1.run运行一个容器,如果镜像不存在则先下载。
常用参数有-d、-t、-i等
2.pull下载容器镜像
3.start/stop启动/停止一个Docker容器
4.rm删除一个容器
5.rmi删除一个容器镜像
6.commit将容器中的修改提交至镜像中
7.logs显示容器运行的控制台输出
8.build从Dockerfile构建一个镜像
9.inspect显示容器运行参数,通过输入一个JSON格式的值来显示相应的结果
10. images显示当前宿主机上的所有镜像
Dockerfile
通过编写Dockerfile,我们可以构建自己的镜像。
看一个Dockerfile的例子:
1.FROM dockerfile/java:
oracle-java8
2.MAINTAINER Lifan Yang
3.ADD device.jar /device.jar
4.EXPOSE 8080
5.ENTRYPOINT java -jar /device.jar
FROM指令的意思是说你的镜像是基于一个什么镜像。
dockerfile/java:
oracle-java8是一个镜像的名字,它也是有一个基础镜像狗狗见。
其实它也是基于例如Ubuntu、CentOS这样的Base镜像。
关于Base镜像的制作方法,Docker官网上有介绍,需要专门的工具,这里不再作介绍。
MAINTAINER指令是可选的。
ADD指令是用来将一个文件或目录添加到Docker镜像中,前面是源文件,后面是目标文件。
源文件必须使用相对路径。
EXPOSE指令用来容器间暴露端口,其指定的端口也会被-P参数映射给宿主机的一个随机端口上。
ENTRYPOINT可以用来指定运行Docker容器时,在容器中执行的命令是什么。
如果需要运行多个命令,可以通过Supervisor来执行。
除了这些指令,还有一些常用的指令。
例如,用于在构建过程中执行命令的CMD指令;用于在容器中设置环境变量的ENV指令。
详细请见DockerfileReference
五、Docker的实现
接下来要介绍Docker所使用的几个重要技术:
namespaces、cgroups、LXC和AUFS。
namespaces
Linux容器通过Kernel的namespaces技术,为一个或一组进程创建独立的pid、net等namespaces,从而与其它进程相互隔离。
下面将介绍namespaces都会对哪些资源进行分组控制以实现相互隔离:
pidnamespace
不同容器中进程是通过pidnamespace隔离开的,且不同容器中可以有相同pid。
具有以下特征:
1.每个namespace中的pid是有自己的pid=1的初始进程
2.每个namespace中的进程只能影响自己的同一个namespace或子namespace中的进程
3.因为/proc包含正在运行的进程,因此在容器中的/proc目录只能看到自己namespace中的进程
4.因为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就不做过多介绍了,总之LinuxKernelnamespaces可以让不同容器的ipc相互隔离。
mntnamespace
如名所示,mntnamespace是处理挂载点的。
mntnamespace可以使不同容器拥有不同的挂载的文件系统和root目录。
在一个mntnamespace挂载的文件系统只能被同一个namespace里的进程所见。
utsnamespace
utsnamespace用于控制hostname的隔离。
有了以上几种隔离,一个容器就可以对外展现出一个独立计算机的能力,并且不同容器内的资源在操作系统层面实现了隔离。
然而不同namespace之间资源还是相互竞争的,仍然需要类似ulimit来管理每个容器所能使用的资源-Docker采用的是cgroup。
参考文献
1
cgroups
namespaces对进程分组以实现资源隔离,但这隔离还是不够的。
一个进程可以通过占用过度的硬件资源的方式去影响另一个分组中的进程。
所以,要想实现完善的资源隔离,不仅要对资源分组,还要能对这一组内的进程所使用的资源进行约束。
cgroups就是用来实现这个目的的。
cgroups的全称是ControlGroups,在2003年由Google的工程师实现,在2007年加入LinuxKernel。
cgroups可限制进程对CPU、内存、块存储和网络的使用。
这里不对cgroups的使用方法作介绍,感兴趣的同学可以参考如下:
1.SysAdminC:
IntroductiontoLinuxControlGroups(Cgroups)
2.D:
RuntimeMetrics
虽然cgroups提供了对IO资源使用的约束的功能,但Docker目前(1.3)尚未提供支持。
内存
cgroups可以控制进程所能使用的内存和swap空间的大小。
通过-m参数,Docker可以限制容器所能使用的最大内存数:
1.docker run -m 128m -d container_img cmd_name
CPU
Docker可以通过cgroups限制容器所能使用的CPU资源。
在执行dockerrun命令时可以通过参数--cpu-shares(-c)、--cpuset对CPU做出限制。
--cpu-shares(-c)
-c设置的是一个相对值,这个值将影响到此容器内的进程所能使用的CPU时间片。
新运行的Docker容器默认使用1024,对一个单独的Docker的容器来说,这个值没有任何意义。
当启动两个Docker容器的时候,这两个容器将平分CPU时间片。
如果两个容器,一个不指定-c,另一个设置为-c512,那前者将使用大致2/3的计算能力,另一个将使用大致1/3的计算能力。
但是-c对容器所能使用CPU的运行频率等没有任何影响。
--cpuset
可让你指定Docker容器中的进程运行在第几块CPU上。
后面跟一个数组或用逗号分隔的多个数字0,1,2。
比如下列命令将会使你的容器运行在第一个CPU核心上。
1.docker run -i -t --cpuset 0 ubuntu:
14.04
注:
cgroups使用的是一种伪文件系统形式的接口。
这个伪文件系统实际存在于内存中,但映射在目录中。
用户通过在这个目录中写入文件来对cgroups进行操作。
AUFS
注:
最新的Docker使用BTRFS替代AUFS,但所要实现的功能相同
AUFS的全称是AnotherUnionFileSystem。
AUFS(包括其它UFS)的一个重要能力是能使两个目录结构合二为一。
这有什么用呢?
Docker的镜像都是有多个层组成的,最上层是一个可读写的,而下面的层则是只读的。
通过AUFS的目录融合的能力,实现了既可随意读写,又保证了下层的内容安全的目的。
见下图可以有一个形象的认识。
下图中的bootfs层包含了LinuxKernel。
在其上是某个特定的Linux发行版本的不同于Kernel的文件层,在下图中是Debian。
再往上有包含emacs和Apache的两个层。
这些层在容器运行时都是只读的。
最上面就是容器运行时可读写的层了。
上面的层可以只读访问下面的层里的文件。
这样的层次结构可以通过Dockerfile来创建。
那这样的一个结构有什么样的好处呢?
主要有下面几点:
节省磁盘和内存的存储空间
节省磁盘存储空间是因为不同的容器镜像之间可以共享相同的层。
例如,两个不同的Java应用的容器镜像,它们都是基于Ubuntu14.04和JDK7。
那在同一台Host中,这两个镜像就会使用相同的Ubuntu14.04和JDK7的层。
节省内存空间是因为Linux为了加快磁盘访问,会将一些磁盘上的文件加载到内存中。
所以,节省磁盘空间的同时也就可以间接地解释内存的使用。
加快部署速度
同样,可共享的镜像层能加快部署速度。
因为相同的层不用被重复下载部署。
允许对文件任意改动
上传可读写的层可以对下面的只读层中的文件做任意修改,但这其实是copy-on-write,所以,这种修改对下面的层其实是安全的。
六、Docker的生态圈
Docker再好,单靠Docker自身是无法满足互联网和企业应用的各种复杂需求的。
好在Docker的出现带动了一些列技术的发展,形成了一个庞大的生态圈。
这个生态圈中的产品可大致分为如下几类:
容器编排管理
以GoogleKubernets和ApacheMesos为代表。
主要解决基于容器组成分布式集群应用的管理工作,例如对容器的运行状态的监控、容器自动化的故障恢复、基于容器的应用的扩容和缩容、服务发现。
基于容器的操作系统
以CoreOS和RedhatAtomic为代表。
它们抛弃了Linux上面传统的包管理机制,而使用Docker作为应用的运行平台。
同时精简系统。
CoreOS还引入了Ectd、Fleet等组件以更好地支持分布式系统。
基于容器的平台
PaaS平台不是什么新鲜的概念,但却一直处于发育不良的状态。
Docker的出现给PaaS的发展带来了新的机遇,Docker使得PaaS应用的部署有了统一的格式。
以Flynn和Deis为代表的新的PaaS技术平台都是以Docker为基础的。
网络
如今的一台服务器可以轻松应付几百上千的Docker容器同时运行在其中。
可以想见,在一个服务器集群中的Docker容器会有多少。
如果对这么多的Docker容器所使用的网络进行组织管理便成为新的挑战。
在这个领域主要有Pipework、Weave和Flannel等技术
配置管理工具
像Puppet、Ansible这样的配置管理工具早在Docker出现之前就已被广泛使用,但Docker的出现给这些技术带来了新的变化。
是否能更好地支持对Docker容器集群的配置管理决定了这些技术今后的发展。
七、总结
本文简单介绍了Docker出现的背景、意义,Docker的组成和背后的技术以及其所带动的生态圈。
但作为一个新出现并在快速发展的基础性的技术,一两篇文章显然只能让人有一个最基本的认识。
同时,任何技术也都有其两面性,Docker作为一个新技术在实践中也存在这个非常多的问题。
即便在国外,Docker的应用也是出于起步阶段。
所以还有很长的路要走。
但是从最近一年多的发展看,Docker无疑是一个非常有生命力的技术,必定会在今后的一段时间内成为一个热门、主流的技术。
虽然Docker的出现更多地是改变了服务器应用的部署和运维。
但作为开发者来说,部署和运维的模型会对开发也产生很重大的影响,而且Docker的出现能使开发人员更好地参与到运维中来,这将促使应用更快、更好地迭代和发布。
更重要地是,云计算毫无疑问是未来互联网和企业应用的发展方向,而Docker和其所代表的容器技术将在未来一段时间内成为云计算的基础性技术。
从这个角度来讲,Docker是我们每一个从业人员必须了解甚至熟练掌握的一门技术。
1.用Docker+Davmail换掉你的Outlook
2.Docker入门教程之10个镜像相关的API
3.Docker入门教程:
15个Docker基本命令及用法
4.Docker入门教程:
15个Docker进阶命令
5.云计算关注在转变:
从降低成本到以客户为导向
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Docker 容器 技术 微服 解决方案