Docker是一种容器技术,允许开发人员将应用程序与相关的依赖关系打包在一起以形成可移植的镜像。镜像是一个只读的模板,用于创建Docker 容器。编排是一种将多个容器组织在一起以形成分布式应用程序的技术。
一、什么是 Docker、镜像、编排
Docker是一种容器技术,允许开发人员将应用程序与相关的依赖关系打包在一起以形成可移植的镜像,并通过容器来部署这些镜像。
镜像是一个只读的模板,用于创建Docker 容器。镜像是由操作系统、应用程序和其他相关依赖项打包而成,在Docker中使用多层文件系统来存储,并且镜像之间可以通过共享层文件来提高效率。Docker镜像是由一系列的层组成的,每一层都是对上一层的增量修改。每一层都有一个少数的ID,可以通过加密哈希算法或者随机数生成。docker镜像的所有层都是只读的,不能被修改,只能通过创建新的层来改变。Docker容器是基于Docker镜像运行的实例,它在镜像的最上面添加了一个可读写的容器层。容器层保存了容器运行时的所有数据变化,如新建文件,修改文件等。删除容器后,容器层也会被删除,而基础镜像则保持不变。Docker使用了栈式层管理和写时复制的技术来实现镜像和容器的存储。栈式层管理是指每一层都是从下往上,以栈的方式组合在一起,组成镜像或者容器的根文件系统。写时复制是指当需要修改某一层的数据时,不直接修改原始数据,而是将修改后的数据保存在一个新的层中。这样可以提高效率和安全性,也可以实现镜像层之间的共享。
编排是 Docker 容器中的一个重要概念,它是一种将多个容器组织在一起以形成分布式应用程序的技术。在 Docker 中,编排描述了容器如何协同工作以支持应用程序。例如,可以通过 Docker Compose 工具来定义和运行多个容器,使它们能够相互通信以实现应用程序的功能。Docker编排通常包括以下方面:
- 容器编排:为多个容器指定数量、配置和启动顺序,并保证它们之间的关系。
- 网络编排:将容器组建成一个网络,并配置容器之间的通信策略。
- 存储编排:为容器配置卷(volume)或者本地主机的文件目录,并关联到不同的容器中。
二、Docker详细介绍
1、简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。一个完整的Docker有以下几个部分组成:
- DockerClient客户端
- Docker Daemon守护进程
- Docker Image镜像
- DockerContainer容器
2、起源
Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上,基于go语言并遵从Apache2.0协议开源。
Docker自2013年以来非常火热,无论是从 github 上的代码活跃度,还是Redhat在RHEL6.5中集成对Docker的支持,就连 Google 的 Compute Engine 也支持 docker 在其之上运行。
一款开源软件能否在商业上成功,很大程度上依赖三件事——成功的 user case(用例),活跃的社区和一个好故事。 dotCloud 之家的 PaaS 产品建立在docker之上,长期维护且有大量的用户,社区也十分活跃,接下看看docker的故事。
- 环境管理复杂:从各种OS到各种中间件到各种app,一款产品能够成功作为开发者需要关心的东西太多,且难于管理,这个问题几乎在所有现代IT相关行业都需要面对。
- 云计算时代的到来:AWS的成功,引导开发者将应用转移到 cloud 上,解决了硬件管理的问题,然而中间件相关的问题依然存在(所以openstack HEAT和 AWS cloudformation 都着力解决这个问题)。开发者思路变化提供了可能性。
- 虚拟化手段的变化:cloud 时代采用标配硬件来降低成本,采用虚拟化手段来满足用户按需使用的需求以及保证可用性和隔离性。然而无论是KVM还是Xen在 docker 看来,都在浪费资源,因为用户需要的是高效运行环境而非OS,GuestOS既浪费资源又难于管理,更加轻量级的LXC更加灵活和快速。
- LXC的移动性:LXC在 linux 2.6 的 kernel 里就已经存在了,但是其设计之初并非为云计算考虑的,缺少标准化的描述手段和容器的可迁移性,决定其构建出的环境难于迁移和标准化管理(相对于KVM之类image和snapshot的概念)。docker 就在这个问题上做出实质性的革新。这是docker最独特的地方。
面对上述几个问题,docker设想是交付运行环境如同海运,OS如同一个货轮,每一个在OS基础上的软件都如同一个集装箱,用户可以通过标准化手段自由组装运行环境,同时集装箱的内容可以由用户自定义,也可以由专业人员制造。这样,交付一个软件,就是一系列标准化组件的集合的交付,如同乐高积木,用户只需要选择合适的积木组合,并且在最顶端署上自己的名字(最后一个标准化组件是用户的app)。这也就是基于docker的PaaS产品的原型。
3、特性
在docker的网站上提到了docker的典型场景:
- Automating the packaging and deployment of applications(使应用的打包与部署自动化)
- Creation of lightweight, private PAAS environments(创建轻量、私密的PAAS环境)
- Automated testing and continuous integration/deployment(实现自动化测试和持续的集成/部署)
- Deploying and scaling web apps, databases and backend services(部署与扩展webapp、数据库和后台服务)
由于其基于LXC的轻量级虚拟化的特点,docker相比KVM之类最明显的特点就是启动快,资源占用小。因此对于构建隔离的标准化的运行环境,轻量级的PaaS(如dokku),构建自动化测试和持续集成环境,以及一切可以横向扩展的应用(尤其是需要快速启停来应对峰谷的web应用)。
- 构建标准化的运行环境,现有的方案大多是在一个baseOS上运行一套puppet/chef,或者一个image文件,其缺点是前者需要base OS许多前提条件,后者几乎不可以修改(因为copy on write 的文件格式在运行时rootfs是read only的)。并且后者文件体积大,环境管理和版本控制本身也是一个问题
- PaaS环境是不言而喻的,其设计之初和dotcloud的案例都是将其作为PaaS产品的环境基础
- 因为其标准化构建方法(buildfile)和良好的REST API,自动化测试和持续集成/部署能够很好的集成进来
- 因为LXC轻量级的特点,其启动快,而且docker能够只加载每个container变化的部分,这样资源占用小,能够在单机环境下与KVM之类的虚拟化方案相比能够更加快速和占用更少资源
4、局限
Docker并不是全能的,设计之初也不是KVM之类虚拟化手段的替代品,简单总结几点:
- Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用
- LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
- 隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库
- 网络管理相对简单,主要是基于namespace隔离
- cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费)
- Docker对disk的管理比较有限
- container随着用户进程的停止而销毁,container中的log等用户数据不便收集
5、原理
Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。同VM的方式不同,LXC 其并不是一套硬件虚拟化方法——无法归属到全虚拟化、部分虚拟化和半虚拟化中的任意一个,而是一个操作系统级虚拟化方法,理解起来可能并不像VM那样直观。所以可以从虚拟化到docker要解决的问题出发,看看docker是怎么满足用户虚拟化需求的。用户需要考虑虚拟化方法,尤其是硬件虚拟化方法,需要借助其解决的主要是以下4个问题:
- 隔离性:每个用户实例之间相互隔离,互不影响。 硬件虚拟化方法给出的方法是VM,LXC给出的方法是container,更细一点是kernel namespace
- 可配额/可度量:每个用户实例可以按需提供其计算资源,所使用的资源可以被计量。硬件虚拟化方法因为虚拟了CPU,memory可以方便实现,LXC则主要是利用cgroups来控制资源
- 移动性:用户的实例可以很方便地复制、移动和重建。硬件虚拟化方法提供snapshot和image来实现,docker(主要)利用AUFS实现
- 安全性:这个话题比较大,这里强调是host主机的角度尽量保护container。硬件虚拟化的方法因为虚拟化的水平比较高,用户进程都是在KVM等虚拟机容器中翻译运行的,然而对于LXC,用户的进程是lxc-start进程的子进程,只是在Kernel的namespace中隔离的,因此需要一些kernel的patch来保证用户的运行环境不会受到来自host主机的恶意入侵,dotcloud(主要是)利用kernel grsec patch解决的
延伸阅读1:Docker安全中心
在新的功能中有硬件的部分,可以 跨任何基础架构,允许开发和随后的升级中的数字编码签名。构建在Docker Trust框架之上用来进行镜像发布者认证,同时进行新的镜像扫描和官方漏洞检测,以便能够更好地理解容器内部是什么。命名空间是本周发布的另外一个Docker安全升级。允许IT运用来为基于用户群组的容器指派授权,约束了主机的访问根源,并指定了系统管理员,限制了群组对于指定服务的访问。镜像扫描对于Docker Hub上的所有官方版本都可用,同时命名空间和硬件签名则在Docker的实验渠道提供。安全问题仍旧是容器采纳要解决的最大问题,尤其是如果大量容器是便携的,IDC研究经理Larry Carvalho说道。通过硬件解决这个问题很明智,因为这样更难以介入,并且提供了未来可能被使用的大量容器的效率。