部署 Docker 介绍以及其相关术语、底层原理和技术

chareice · 2014年10月13日 · 最后由 BaBaFeng 回复于 2017年04月01日 · 20368 次阅读
本帖已被设为精华帖!

原文发表在 Pilehub http://pilehub.org/t/docker/23

英文原文: Understanding Docker

Docker 是啥

Docker 是一个程序运行、测试、交付的开放平台,Docker 被设计为能够使你快速地交付应用。在 Docker 中,你可以将你的程序分为不同的基础部分,对于每一个基础部分都可以当做一个应用程序来管理。Docker 能够帮助你快速地测试、快速地编码、快速地交付,并且缩短你从编码到运行应用的周期。

Docker 使用轻量级的容器虚拟化平台,并且结合工作流和工具,来帮助你管理、部署你的应用程序。

在其核心,Docker 实现了让几乎任何程序都可以在一个安全、隔离的容器中运行。安全和隔离可以使你可以同时在机器上运行多个容器。

容器轻量级的特性,意味着你可以得到更多的硬件性能。

围绕着容器的虚拟化工具和平台,可以在以下几个方面为你提供帮助:

  • 帮助你把应用程序 (包括其余的支持组件) 放入到 Docker 容器中。
  • 分发和转移你的容器至你的团队其它成员来进行进一步的开发和测试。
  • 部署这些应用程序至你的生产环境,不论是本地的数据中心还是云平台。

我可以用 Docker 做啥

快速交付你的应用程序

Docker 可以为你的开发过程提供完美的帮助。Docker 允许开发者在本地包含了应用程序和服务的容器进行开发,之后可以集成到连续的一体化和部署工作流中。

举个例子,开发者们在本地编写代码并且使用 Docker 和同事分享其开发栈。当开发者们准备好了之后,他们可以将代码和开发栈推送到测试环境中,在该环境进行一切所需要的测试。从测试环境中,你可以将 Docker 镜像推送到服务器上进行部署。

开发和拓展更加简单

Docker 的以容器为基础的平台允许高度可移植的工作。Docker 容器可以在开发者机器上运行,也可以在实体或者虚拟机上运行,也可以在云平台上运行。

Docker 的可移植、轻量特性同样让动态地管理负载更加简单。你可以用 Docker 快速地增加应用规模或者关闭应用程序和服务。Docker 的快速意味着变动几乎是实时的。

达到高密度和更多负载

Docker 轻巧快速,它提供了一个可行的、 符合成本效益的替代基于虚拟机管理程序的虚拟机。这在高密度的环境下尤其有用。例如,构建你自己的云平台或者 PaaS,在中小的部署环境下同样可以获取到更多的资源性能。

Docker 的主要组成有哪些

Docker 有两个主要的部件:

  • Docker: 开源的容器虚拟化平台。
  • Docker Hub: 用于分享、管理 Docker 容器的 Docker SaaS 平台。

Docker 的架构是怎样的

Docker 使用客户端-服务器 (client-server) 架构模式。Docker 客户端会与 Docker 守护进程进行通信。Docker 守护进程会处理复杂繁重的任务,例如建立、运行、发布你的 Docker 容器。Docker 客户端和守护进程可以运行在同一个系统上,当然你也可以使用 Docker 客户端去连接一个远程的 Docker 守护进程。Docker 客户端和守护进程之间通过 socket 或者 RESTful API 进行通信。

arch

Docker 守护进程

如上图所示,Docker 守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过 Docker 客户端间接和其通信。

Docker 客户端

Docker 客户端,实际上是docker的二进制程序,是主要的用户与 Docker 交互方式。它接收用户指令并且与背后的 Docker 守护进程通信,如此来回往复。

Docker 的内部

要理解 Docker 的内部构建,必须知道以下三种部件:

  • Docker 镜像 (Docker images)。
  • Docker 仓库 (Docker registeries)。
  • Docker 容器 (Docker containers)。

Docker 镜像

Docker 镜像是一个只读的模板。举个例子,一个镜像可以包含一个运行在 Apache 上的 Web 应用和其使用的 Ubuntu 操作系统。

镜像是用来创建容器的。Docker 提供了简单的放来来建立新的镜像或者升级现有的镜像,你也可以下载别人已经创建好的镜像。Docker 镜像是 Docker 的 构造 部分。

Docker 仓库

Docker 仓库用来保存镜像。可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。公有的 Docker 仓库名字是Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是你自己创建的,或者你也可以在别人的镜像基础上创建。Docker 仓库是 Docker 的 分发 部分。

Docker 容器

Docker 容器和文件夹很类似。一个 Docker 容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台。Docker 容器是 Docker 的 运行 部分。

Docker 的工作原理

到目前为止,我们学习到了:

  1. 我们可以建立一个容纳应用程序的容器。
  2. 我们可以从 Docker 镜像创建 Docker 容器来运行我们的应用程序。
  3. 我们可以通过 Docker Hub 或者我们自己的 Docker 仓库分享 Docker 镜像。

Docker 镜像是如何工作的

我们已经看到了,Docker 镜像是 Docker 容器运行时的只读模板。每一个镜像由一系列的层 (layers) 组成。Docker 使用UnionFS来将这些层联合到一二镜像中。Union 文件系统允许独立文件系统中的文件和文件夹 (称之为分支) 被透明覆盖,形成一个单独连贯的文件系统。

这一段的原文:We've already seen that Docker images are read-only templates from which Docker containers are launched. Each image consists of a series of layers. Docker makes use of union file systems to combine these layers into a single image. Union file systems allow files and directories of separate file systems, known as branches, to be transparently overlaid, forming a single coherent file system.

正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立 (在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。现在你不用重新发布整个镜像,只需要升级。层使得分发 Docker 镜像变得简单和快速。

每个镜像都是从一个基础的镜像开始的,比如ubuntu,一个基础的 Ubuntu 镜像,或者是fedora,一个基础的 Fedora 镜像。你可以使用你自己的镜像作为新镜像的基础,例如你有一个基础的安装了 Apache 的镜像,你可以使用该镜像来建立你的 Web 应用程序镜像。

注: Docker 通常从 Docker Hub 获取基础镜像。

Docker 镜像从这些基础的镜像创建,通过一种简单、具有描述性的步骤,我们称之为 指令 (instructions)。 每一个指令会在镜像中创建一个新的层,指令可以包含这些动作:

  • 运行一个命令。
  • 增加文件或者文件夹。
  • 创建一个环境变量。
  • 当运行容器的时候哪些程序会运行。

这些指令存储在Dockerfile文件中。当你需要建立镜像的时候,Docker 可以从Dockerfile中读取这些指令并且运行,然后返回一个最终的镜像。

Docker 仓库是如何工作的

Docker 仓库是 Docker 镜像的存储仓库。你可以推送你的镜像到你的 Docker 仓库中。

通过 Docker 客户端,你可以从 Docker 仓库中搜索镜像。

Docker 容器是如何工作的

一个 Docker 容器包含了一个操作系统、用户添加的文件和元数据 (meta-data)。我们可以看到,每个容器都是从镜像建立的。镜像告诉 Docker 容器内包含了什么,当容器启动时运行什么程序,还有许多配置数据。Docker 镜像是只读的。当 Docker 运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。

当你运行 docker 容器时发生了什么

不论你使用docker命令或者是 RESTful API,Docker 客户端都会告诉 Docker 守护进程运行一个容器。

$ sudo docker run -i -t ubuntu /bin/bash

让我们来分析这个命令。Docker 客户端使用docker命令来运行,run参数表名客户端要运行一个新的容器。Docker 客户端要运行一个容器需要告诉 Docker 守护进程的最小参数信息是:

  • 这个容器从哪个镜像创建,这里是ubuntu,基础的 Ubuntu 镜像。
  • 在容器中要运行的命令,这里是/bin/bash,在容器中运行 Bash shell。

那么运行这个命令之后在底层发生了什么?

按照顺序,Docker 做了这些事情:

  • 拉取ubuntu镜像: Docker 检查ubuntu镜像是否存在,如果在本地没有该镜像,Docker 会从 Docker Hub 下载。如果镜像已经存在,Docker 会使用它来创建新的容器。
  • 创建新的容器: 当 Docker 有了这个镜像之后,Docker 会用它来创建一个新的容器。
  • 分配文件系统并且挂载一个可读写的层: 容器会在这个文件系统中创建,并且一个可读写的层被添加到镜像中。
  • 分配网络/桥接接口: 创建一个允许容器与本地主机通信的网络接口。
  • 设置一个 IP 地址: 从池中寻找一个可用的 IP 地址并且服加到容器上。
  • 运行你指定的程序: 运行指定的程序。
  • 捕获并且提供应用输出: 连接并且记录标准输出、输入和错误让你可以看到你的程序是如何运行的。

你现在拥有了一个运行着的容器!从这里开始你可以管理你的容器,与应用交互,应用完成之后,可以停止或者删除你的容器。

底层技术

Docker 使用 Go 语言编写,并且使用了一系列 Linux 内核提供的性能来实现我们已经看到的这些功能。

命名空间 (Namespaces)

Docker 充分利用了一项称为namespaces的技术来提供隔离的工作空间,我们称之为 container(容器)。当你运行一个容器的时候,Docker 为该容器创建了一个命名空间集合。

这样提供了一个隔离层,每一个应用在它们自己的命名空间中运行而且不会访问到命名空间之外。

一些 Docker 使用到的命名空间有:

  • pid命名空间: 使用在进程隔离 (PID: Process ID)。
  • net命名空间: 使用在管理网络接口 (NET: Networking)。
  • ipc命名空间: 使用在管理进程间通信资源 (IPC: InterProcess Communication)。
  • mnt命名空间: 使用在管理挂载点 (MNT: Mount)。
  • uts命名空间: 使用在隔离内核和版本标识 (UTS: Unix Timesharing System)。

群组控制

Docker 还使用到了cgroups技术来管理群组。使应用隔离运行的关键是让它们只使用你想要的资源。这样可以确保在机器上运行的容器都是良民 (good multi-tenant citizens)。群组控制允许 Docker 分享或者限制容器使用硬件资源。例如,限制指定的容器的内容使用。

联合文件系统

联合文件系统 (UnionFS) 是用来操作创建层的,使它们轻巧快速。Docker 使用 UnionFS 提供容器的构造块。Docker 可以使用很多种类的 UnionFS 包括 AUFS, btrfs, vfs, and DeviceMapper。

容器格式

Docker 连接这些组建到一个包装中,称为一个 container format(容器格式)。默认的容器格式是libcontainer。Docker 同样支持传统的 Linux 容器使用LXC。在未来,Docker 也许会支持其它的容器格式,例如与 BSD Jails 或 Solaris Zone 集成。

接下来。。。

可以实践一些Docker命令使用: Docker 入门使用教程 Docker 化应用: 一个 Hello World 与容器同行

翻译很用心,赞

谢谢,看完之后基本理解了 docker 是个啥玩意,有空玩一下 👏

好顶赞,有空我也翻译一些~ :plus1:

这篇文章我翻译了四个小时,还真有人看完了,好开心😄 😄

不错,关注它一段时间了!貌似不错!

密切关注。

小磊子,我膜拜你!嗷嗷的膜拜你。。。

赞一个

xcvxvxcvcx

suse 11 sp2 现在可以使用吗?

隔离粒度与 heroku 的隔离部署环境很类似

层使得奋发 Docker 镜像变得简单和快速。 debug 😆

:plus1: 感谢

fsword 为什么 Ruby 程序员应该了解和掌握 Docker 中提及了此贴 06月17日 10:41

我无耻的抄袭了你得翻译

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册