Docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
来自官网:
Docker是一个用于开发,交付和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助Docker,您可以以与管理应用程序相同的方式来管理基础架构。通过利用Docker的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。
Docker是个平台,一个开放平台,一个用于开发、交付和运行应用程序的开放平台,这个平台让我们更加快速、高效的实现应用程序开发、环境部署和软件交付。
来自官网:
Docker平台(The Docker platform)
Docker提供了在松散隔离的环境(称为容器)中打包和运行应用程序的功能。隔离和安全性使您可以在给定主机上同时运行多个容器。容器是轻量级的,因为它们不需要管理程序的额外负担,而是直接在主机的内核中运行。这意味着与使用虚拟机相比,可以在给定的硬件组合上运行更多的容器。您甚至可以在实际上是虚拟机的主机中运行Docker容器!
Docker提供了工具和平台来管理容器的生命周期:
- 使用容器开发应用程序及其支持组件。
- 容器成为分发和测试您的应用程序的单元。
- 准备就绪后,可以将应用程序作为容器或协调服务部署到生产环境中。无论您的生产环境是本地数据中心,云提供商还是二者的混合体,其工作原理都相同。
Docker concepts
Docker是供开发人员和系统管理员 使用容器构建,运行和共享应用程序的平台。使用容器部署应用程序称为容器化。容器不是新的,但用于轻松部署应用程序的容器却是新的。
容器化越来越受欢迎,因为容器是:
- 灵活:即使最复杂的应用程序也可以容器化。
- 轻量级:容器利用并共享了主机内核,在系统资源方面比虚拟机更有效。
- 可移植性:您可以在本地构建,部署到云并在任何地方运行。
- 松散耦合:容器是高度自给自足并封装的容器,使您可以在不破坏其他容器的情况下更换或升级它们。
- 可扩展:您可以在数据中心内增加并自动分布容器副本。
- 安全:容器将积极的约束和隔离应用于流程,而无需用户方面的任何配置。
镜像和容器(Images and containers)
从根本上说,一个容器不过是一个正在运行的进程,并对其应用了一些附加的封装功能,以使其与主机和其他容器隔离。容器隔离的最重要方面之一是每个容器都与自己的专用文件系统进行交互。该文件系统由Docker 映像提供。映像包括运行应用程序所需的一切-代码或二进制文件,运行时,依赖项以及所需的任何其他文件系统对象。
容器与虚拟机(Containers and virtual machines)
容器在Linux上本地运行,并与其他容器共享主机的内核。它运行一个离散进程,不占用任何其他可执行文件更多的内存,从而使其轻巧。
相比之下,虚拟机(VM)运行具有“ 虚拟机管理程序”对主机资源的虚拟访问权的成熟“来宾”操作系统。通常,VM会产生大量开销,超出了应用程序逻辑所消耗的开销。
我们通常说的Docker容器或者Docker镜像就是Docker的松散隔离的环境,每个Docker容器都是独立的一个环境,里面可以包含我们应用程序运行时需要的完整环境,也可以是单独的某个配置好的应用程序,这样当我们在其他服务器上使用这个相同的环境或配置时就可以直接拉取这个Docker容器,而不用再次安装和配置,极大简化环境部署与软件应用成本。
Docker容器的运行依赖与Docker引擎,那么Docker引擎又是什么呢?
来自官网:
Docker引擎(Docker Engine)
Docker引擎(Docker Engine)是具有以下主要组件的客户端-服务器应用程序:
- 服务器是一种长期运行的程序,称为守护程序进程(
dockerd
命令)。- REST API,它指定程序可以用来与守护程序进行通信并指示其操作的接口。
- 命令行界面(CLI)客户端(
docker
命令)。CLI使用Docker REST API通过脚本或直接CLI命令来控制Docker守护程序或与Docker守护程序进行交互。许多其他Docker应用程序都使用基础API和CLI。
守护程序创建和管理Docker 对象,例如图像,容器,网络和卷。
Docker守护程序(Docker daemon)
Docker守护程序(
dockerd
)侦听Docker API请求并管理Docker对象,例如图像,容器,网络和卷。守护程序还可以与其他守护程序通信以管理Docker服务。Docker客户端(Docker client)
Docker客户端(
docker
)是许多Docker用户与Docker交互的主要方式。当您使用诸如之类的命令时docker run
,客户端会将这些命令发送到dockerd
,以执行这些命令。该docker
命令使用Docker API。Docker客户端可以与多个守护程序通信。
即Docker引擎由Docker守护进程(Docker daemon)、REST API与**Docker客户端(Docker cli)**三个主要部分组成,它们是Docker架构中重要组成部分之一,更加详细的介绍可以参考 Docker体系架构 。
了解了Docker是什么,Docker容器是什么,Docker的重要组成部分Docker引擎。
Docker到底可以干什么呢?
之前已经说过,Docker是一个用于开发、交付和运行应用程序的开放平台,这个平台让我们更加快速、高效的实现应用程序开发、环境部署和软件交付。
那么Docker能做的是:
来自官网:
我可以将Docker用于什么?
快速,一致地交付您的应用程序
Docker通过允许开发人员使用提供您的应用程序和服务的本地容器在标准化环境中工作,从而简化了开发生命周期。容器非常适合持续集成和持续交付(CI / CD)工作流程。
请考虑以下示例方案:
- 您的开发人员在本地编写代码,并使用Docker容器与同事共享他们的工作。
- 他们使用Docker将其应用程序推送到测试环境中,并执行自动和手动测试。
- 当开发人员发现错误时,他们可以在开发环境中修复它们,然后将它们重新部署到测试环境中以进行测试和验证。
- 测试完成后,将修复程序推送给生产环境就像将更新的映像推送到生产环境一样简单。
响应式部署和扩展
Docker基于容器的平台允许高度可移植的工作负载。Docker容器可以在开发人员的本地笔记本电脑上,数据中心内的物理或虚拟机上,云提供商上或混合环境中运行。
Docker的可移植性和轻量级的特性还使您可以轻松地动态管理工作负载,并根据业务需求指示实时扩展或关闭应用程序和服务。
在同一硬件上运行更多工作负载
Docker轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行且经济高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker非常适合高密度环境以及中小型部署,而您需要用更少的资源做更多的事情。
哲学三连问:Docker是什么?Docker用来干什么?还剩下Docker怎么来的。
Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。
来自官网:
底层技术(The underlying technology)
Docker用Go编写,并利用Linux内核的多个功能来交付其功能。
命名空间(Namespaces)
Docker使用一种称为
namespaces
提供容器的隔离工作区的技术。运行容器时,Docker会为该容器创建一组 名称空间。这些名称空间提供了一层隔离。容器的每个方面都在单独的名称空间中运行,并且其访问仅限于该名称空间。
Docker Engine在Linux上使用以下名称空间:
- **
pid
命名空间:**进程隔离(PID:进程ID)。- **
net
命名空间:**管理网络接口(NET:网络)。- **
ipc
命名空间:**管理访问IPC资源(IPC:进程间通信)。- **
mnt
命名空间:**管理文件系统挂载点(MNT:摩)。- **
uts
命名空间:**隔离内核和版本标识符。(UTS:Unix时间共享系统)。对照组(Control groups)
Linux上的Docker Engine还依赖于另一种称为控制组 (
cgroups
)的技术。cgroup将应用程序限制为一组特定的资源。控制组允许Docker Engine将可用的硬件资源共享给容器,并有选择地实施限制和约束。例如,您可以限制特定容器可用的内存。联合文件系统(Union file systems)
联合文件系统或UnionFS是通过创建图层进行操作的文件系统,使其非常轻便且快速。Docker Engine使用UnionFS为容器提供构建模块。Docker Engine可以使用多个UnionFS变体,包括AUFS,btrfs,vfs和DeviceMapper。
容器格式(Container format)
Docker Engine将名称空间,控制组和UnionFS组合到一个称为容器格式的包装器中。默认容器格式为
libcontainer
。将来,Docker可能会通过与BSD Jails或Solaris Zones等技术集成来支持其他容器格式。
Docker整体构成可以参考 Docker体系架构 。
说了这么多,Docker有什么缺点呢?
局限
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等用户数据不便收集
针对1、2,有windows base应用的需求的基本可以pass了; 3、4、5主要是看用户的需求,到底是需要一个container还是一个VM, 同时也决定了docker作为 IaaS 不太可行。
针对6、7虽然是docker本身不支持的功能,但是可以通过其他手段解决(disk quota, mount --bind)。总之,选用container还是vm, 就是在隔离性和资源复用性上做权衡。
另外即便docker 0.7能够支持非AUFS的文件系统,但是由于其功能还不稳定,商业应用或许会存在问题,而AUFS的稳定版需要kernel 3.8, 所以如果想复制dotcloud的成功案例,可能需要考虑升级kernel或者换用ubuntu的server版本(后者提供deb更新)。这也是为什么开源界更倾向于支持ubuntu的原因(kernel版本)
Docker并非适合所有应用场景,Docker只能虚拟基于Linux的服务。Windows Azure 服务能够运行Docker实例,但到目前为止Windows服务还不能被虚拟化。
可能最大的障碍在于管理实例之间的交互。由于所有应用组件被拆分到不同的容器中,所有的服务器需要以一致的方式彼此通信。这意味着任何人如果选择复杂的基础设施,那么必须掌握应用编程接口管理以及集群工具,比如Swarm、Mesos或者Kubernets以确保机器按照预期运转并支持故障切换。
Docker在本质上是一个附加系统。使用文件系统的不同层构建一个应用是有可能的。每个组件被添加到之前已经创建的组件之上,可以比作为一个文件系统更明智。分层架构带来另一方面的效率提升,当你重建存在变化的Docker镜像时,不需要重建整个Docker镜像,只需要重建变化的部分。
可能更为重要的是,Docker旨在用于弹性计算。每个Docker实例的运营生命周期有限,实例数量根据需求增减。在一个管理适度的系统中,这些实例生而平等,不再需要时便各自消亡了。
针对Docker环境存在的不足,意味着在开始部署Docker前需要考虑如下几个问题。首先,Docker实例是无状态的。这意味着它们不应该承载任何交易数据,所有数据应该保存在数据库服务器中。
其次,开发Docker实例并不像创建一台虚拟机、添加应用然后克隆那样简单。为成功创建并使用Docker基础设施,管理员需要对系统管理的各个方面有一个全面的理解,包括Linux管理、编排及配置工具比如Puppet、Chef以及Salt。这些工具生来就基于命令行以及脚本。
参考文档:
https://docs.docker.com/get-started/overview/
https://baike.baidu.com/item/docker/13344470
https://www.jianshu.com/p/b975eeb582d6
Docker 基础了解:
菜鸟教程 https://www.runoob.com/docker/docker-resources.html