介绍
提供的用例是无限的,需求一直存在。Docker 提供了一种高效、快速的方式,可以在系统和机器之间快速移植应用程序。它轻巧灵活,允许您快速封装应用程序并在其自己的安全环境中运行(通过 Linux 容器:LXC)。
在这篇 DigitalOcean 文章中,我们旨在全面介绍 Docker:这是近年来涌现的最令人兴奋和强大的开源项目之一。Docker 可以帮助您解决很多问题,试图用一句话概括其功能是不公平的。
术语表
1. Docker
2. Docker 项目及其主要部分
3. Docker 元素
- Docker 容器
- Docker 镜像
- Dockerfile
4. 如何安装 Docker
5. 如何使用 Docker
- 起步
- 使用镜像
- 使用容器
Docker
无论是从开发机到远程服务器用于生产,还是打包一切以便在其他地方使用,将应用程序堆栈及其依赖项一起移植并使其无故障运行始终是一个挑战。事实上,这个挑战是巨大的,到目前为止,解决方案并没有真正成功地服务于大众。
简而言之,作为一个项目,Docker 为您提供了一整套高级工具,可以将构成应用程序的一切内容跨系统和机器(虚拟或物理)传输,并带来了更多的巨大好处。
Docker 通过**Linux 容器**(例如命名空间和其他内核特性)实现了强大的应用程序(因此也是进程和资源)封装。它的进一步功能来自项目自身的部分和组件,这些部分和组件提取了用于安全地包含进程的系统和应用程序管理的低级 Linux 工具/ API 的所有复杂性。
Docker 项目及其主要部分
Docker 项目(由 dotCloud 在 2013 年 3 月开源)包括几个主要部分(应用程序)和元素(这些部分使用的元素),它们大多建立在 Linux 内核和第三方(例如 LXC、device-mapper、aufs 等)已经存在的功能、库和框架之上。
主要 Docker 部分
- docker 守护程序:用于管理宿主机上的 Docker(LXC)容器
- docker CLI:用于命令和与 docker 守护程序通信
- docker 镜像索引:用于存储 Docker 镜像的仓库(公共或私有)
主要 Docker 元素
- Docker 容器:包含应用程序的目录
- Docker 镜像:容器或基本操作系统(例如 Ubuntu)的快照
- Dockerfile:自动化构建镜像的脚本
Docker 元素
以下元素由构成 Docker 项目的应用程序使用。
Docker 容器
使用 Docker 进行应用程序移植的整个过程完全依赖于容器的传输。
Docker 容器基本上是可以像任何其他目录一样打包(例如 tar 存档),然后在各种不同的机器和平台(宿主机)上共享和运行。唯一的依赖是宿主机已调整为运行容器(即已安装 Docker)。这里的封装是通过Linux 容器(LXC)实现的。
LXC(Linux 容器)
Linux 容器可以被定义为各种内核级特性的组合(即 Linux 内核可以执行的操作),它们允许在其自己的环境中管理应用程序(及其使用的资源)。通过利用某些特性(例如命名空间、chroots、cgroups 和 SELinux 配置文件),LXC 包含应用程序进程,并通过限制资源、不允许访问其父文件系统(访问父命名空间)等方式帮助管理这些进程。
Docker 与其容器使用 LXC,但也带来了更多的功能。
Docker 容器
Docker 容器具有几个主要特性。
它们允许:
- 应用程序可移植性
- 进程隔离
- 防止与外部环境干扰
- 管理资源消耗
等等,需要的资源远少于用于隔离应用程序部署的传统虚拟机。
它们不允许:
- 干扰其他进程
- 导致“依赖地狱”
- 或在不同系统上无法运行
- 容易受到攻击并滥用所有系统资源
等等(还有更多)。
基于 LXC 并依赖于 LXC,从技术角度来看,这些容器就像一个目录(但是一个经过设计和格式化的目录)。这允许容器的可移植性和逐步构建。
每个容器都像洋葱一样分层,容器内的每个操作都包括将另一个块(实际上是文件系统内的简单更改)放在前一个块的顶部。各种工具和配置使得这种设置在整体上能够和谐地工作(例如联合文件系统)。
这种容器方式允许的极大好处是轻松启动和创建新的容器和镜像,因此它们保持轻量级(由于它们是逐步和分层构建的)。由于一切都基于文件系统,像版本控制系统(VCS)一样,进行快照和时间回滚都是廉价的(即非常容易完成/不占用大量资源)。
每个Docker 容器都是从一个Docker 镜像开始的,这为其他应用程序和层提供了基础。
Docker 镜像
Docker 镜像构成了 Docker 容器的基础,所有的一切都是从这里开始形成的。它们与默认的操作系统磁盘镜像非常相似,用于在服务器或台式计算机上运行应用程序。
拥有这些镜像(例如 Ubuntu 基础镜像)可以在不同系统之间实现无缝移植。它们提供了一个坚实、一致和可靠的基础,其中包含了运行应用程序所需的一切。当一切都是自包含的,系统级别的更新或修改的风险被消除时,容器就不会受到可能使其失效的外部暴露的影响,从而避免了依赖地狱。
随着在基础镜像上添加更多层(工具、应用程序等),可以通过提交这些更改来形成新的镜像。当从保存的(即提交的)镜像创建新容器时,一切都会从上次中断的地方继续进行。而联合文件系统在处理容器时将所有层合并为一个单一实体。
在使用 docker CLI 时,可以明确指定这些基础镜像以直接创建新容器,或者可以在 Dockerfile 中指定这些镜像以进行自动化镜像构建。
Dockerfiles
Dockerfiles 是包含一系列连续的指令、方向和命令的脚本,用于执行以形成新的 Docker 镜像。每个执行的命令都会转化为洋葱的一个新层,形成最终的产品。它们基本上取代了手动重复执行所有操作的过程。当一个 Dockerfile 执行完成时,你最终会形成一个镜像,然后你可以使用它来启动(即创建)一个新的容器。
如何安装 Docker
最初,Docker 只能在 Ubuntu 上使用。如今,可以在基于 RHEL 的系统(例如 CentOS)和其他系统上部署 Docker。
让我们快速浏览一下 Ubuntu 的安装过程。
Ubuntu 安装说明
获取 Docker 的最简单方法,除了使用预构建的应用程序镜像之外,就是选择一个 64 位的 Ubuntu 14.04 VPS。
更新你的 droplet:
sudo apt-get update sudo apt-get -y upgrade
确保支持 aufs:
sudo apt-get install linux-image-extra-`uname -r`
将 Docker 存储库密钥添加到 apt-key 以进行软件包验证:
sudo apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
将 Docker 存储库添加到 Apt 源:
echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee /etc/apt/sources.list.d/docker.list
使用新添加的存储库更新存储库:
sudo apt-get update
最后,下载并安装 Docker:
sudo apt-get install docker-engine
Ubuntu 的默认防火墙(UFW:简化防火墙)默认拒绝所有转发流量,而 Docker 需要这些流量。
使用 UFW 启用转发:
使用 nano 文本编辑器编辑 UFW 配置。
sudo nano /etc/default/ufw
向下滚动并找到以 DEFAULT_FORWARD_POLICY 开头的行。
将:
DEFAULT_FORWARD_POLICY="DROP"
替换为:
DEFAULT_FORWARD_POLICY="ACCEPT"
按下 CTRL+X 并按 Y 保存并关闭。
最后,重新加载 UFW:
sudo ufw reload
若要获取完整的安装说明,请查看 Docker 官方文档中的安装部分。
如何使用 Docker
一旦你安装了 Docker,它直观的使用体验使得与它一起工作非常容易。此时,你应该已经在后台运行 Docker 守护程序。如果没有,使用以下命令来运行 Docker 守护程序。
运行 Docker 守护程序:
sudo docker -d &
使用语法:
使用 Docker(通过 CLI)需要传递一系列选项和命令,然后是参数。请注意,Docker 需要 sudo 权限才能工作。
sudo docker [option] [command] [arguments]
注意: 以下说明和解释旨在作为指南使用,以便让你对使用和处理 Docker 有一个整体的了解。最好的熟悉方法是在一个新的 VPS 上进行实践。不要害怕破坏任何东西 - 实际上,确实破坏一些东西吧!使用 Docker,你可以轻松保存你的进度并从那里继续。
开始
让我们开始看看 Docker 有哪些可用命令。
询问 Docker 所有可用命令的列表:
sudo docker
当前(截至 0.7.1 版本)所有可用命令:
attach 附加到正在运行的容器 build 从 Dockerfile 构建容器 commit 从容器的更改创建新镜像 cp 从容器文件系统复制文件/文件夹到主机路径 diff 检查容器文件系统的更改 events 从服务器获取实时事件 export 将容器内容流式传输为 tar 存档 history 显示镜像的历史记录 images 列出镜像 import 从 tarball 的内容创建新的文件系统镜像 info 显示系统范围的信息 insert 在镜像中插入文件 inspect 返回容器的低级信息 kill 终止正在运行的容器 load 从 tar 存档加载镜像 login 注册或登录到 Docker 注册服务器 logs 获取容器的日志 port 查找 NAT 到 PRIVATE_PORT 的公共端口 ps 列出容器 pull 从 Docker 注册服务器拉取镜像或存储库 push 将镜像或存储库推送到 Docker 注册服务器 restart 重新启动正在运行的容器 rm 删除一个或多个容器 rmi 删除一个或多个镜像 run 在新容器中运行命令 save 将镜像保存为 tar 存档 search 在 Docker 索引中搜索镜像 start 启动已停止的容器 stop 停止正在运行的容器 tag 将镜像标记为存储库 top 查找容器的运行进程 version 显示 Docker 版本信息 wait 阻塞直到容器停止,然后打印其退出代码
查看系统范围的信息和 Docker 版本:
# 获取 Docker 的系统范围信息: sudo docker info # 获取 Docker 版本: sudo docker version
使用镜像
正如我们长时间讨论的那样,开始使用任何 Docker 容器的关键是使用镜像。在 docker 镜像索引 上有许多免费可用的镜像,而 CLI 允许简单地访问查询镜像存储库并下载新的镜像。
当你准备好时,你也可以在那里分享你的镜像。有关详细信息,请参阅下面的“推送”部分。
搜索 Docker 镜像:
# 用法:sudo docker search [镜像名称] sudo docker search ubuntu
这将为您提供一个非常长的列表,其中包含与查询 Ubuntu 匹配的所有可用镜像。
下载(拉取)镜像:
在构建/创建容器之前或之后,您需要在容器将存在的主机机器上有一个镜像。为了下载镜像(可能是在“搜索”之后),您可以执行 pull 来获取一个。
# 用法:sudo docker pull [镜像名称] sudo docker pull ubuntu
列出镜像:
您可以使用“images”列出系统上的所有镜像,包括您通过提交创建的镜像(有关详细信息,请参见下文)。这提供了所有可用镜像的完整列表。
# 示例:sudo docker images sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE my_img latest 72461793563e 36 seconds ago 128 MB ubuntu 12.04 8dbd9e392a96 8 months ago 128 MB ubuntu latest 8dbd9e392a96 8 months ago 128 MB ubuntu precise 8dbd9e392a96 8 months ago 128 MB ubuntu 12.10 b750fe79269d 8 months ago 175.3 MB ubuntu quantal b750fe79269d 8 months ago 175.3 MB
提交更改到镜像:
当您使用容器并继续对其执行操作(例如下载和安装软件,配置文件等)时,为了使其保持其状态,您需要“提交”。提交确保下次使用时(即镜像),一切都会从上次离开的地方继续进行。
# 用法:sudo docker commit [容器 ID] [镜像名称] sudo docker commit 8dbd9e392a96 my_img
分享(推送)镜像:
虽然现在可能还为时过早 - 在我们的文章中,当您创建了自己的容器并希望与世界其他地方共享时,您可以使用推送将**您的**镜像列在所有人都可以下载和使用的索引中。
请记住“提交”您的所有更改。
# 用法:sudo docker push [用户名/镜像名称] sudo docker push my_username/my_first_image
注意: 您需要在 index.docker.io 上注册以将镜像推送到 Docker 索引。
使用容器
当您使用镜像“运行”任何进程时,您将得到一个容器。当进程不在运行时,此容器将是一个**非运行**容器。尽管如此,所有这些容器都将驻留在您的系统上,直到您通过 rm 命令将它们删除。
列出所有当前容器:
默认情况下,您可以使用以下命令列出所有正在运行的容器:
sudo docker ps
要获取正在运行和非运行的容器列表,使用:
sudo docker ps -l
创建新容器
目前不可能在不运行任何内容(即命令)的情况下创建一个容器。要创建一个新容器,您需要使用一个基础镜像并指定要运行的命令。
# 用法:sudo docker run [镜像名称] [要运行的命令] sudo docker run my_img echo "hello" # 为容器命名而不是使用长 ID # 用法:sudo docker run -name [名称] [镜像名称] [命令] sudo docker run -name my_cont_1 my_img echo "hello"
这将输出“hello”,然后您将回到原来的位置(即您的主机 shell)。
由于在创建容器后无法更改要运行的命令(因此在“创建”期间指定一个命令),通常会使用进程管理器甚至自定义启动脚本来执行不同的命令。
运行容器:
当您创建一个容器并且它停止(无论是由于其进程结束还是您明确停止它),您可以使用“run”再次使用与创建它时相同的命令使容器工作。
# 用法:sudo docker run [容器 ID] sudo docker run c629b7d70666
记得如何找到容器吗?请参阅上面的列出它们的部分。
停止容器:
要停止容器的进程运行:
# 用法:sudo docker stop [容器 ID] sudo docker stop c629b7d70666
保存(提交)容器:
如果您想保存容器的进度和更改,您可以使用上面解释的“提交”将其保存为一个镜像。
此命令将您的容器转换为一个**镜像**。
请记住,使用 Docker,提交是廉价的。不要犹豫使用它们来创建镜像以保存您对容器的进度,或者在需要时回滚(例如,像时间快照一样)。
删除容器:
使用容器的 ID,您可以使用 rm 删除一个容器。
# 用法:sudo docker rm [容器 ID] sudo docker rm c629b7d70666
您可以通过阅读他们的官方文档了解更多关于 Docker 的信息。