本文阐释了怎样部署私有的 Docker Registry 服务 —— 或为公司私用,或公开给其他用户使用。例如,你公司可能需要私人的 Registry 来支持持续集成(CI)。又或,你的公司可能有大量镜像方式的产品或服务,你想以公司品牌的方式来整体提供和呈现。
Docker 公共的 Registry 里维护有一个默认的 registry 镜像可以用以协助该部署过程。该 Registry 镜像对本地测试足矣,但不能用于生产环境。对于生产环境,应以 docker/distribution 为基础,自行配置并构建自定义 Registry 镜像。
注意:本文中的例子在 Ubuntu 14.04 下编写及测试。如果你在不同的操作系统中运行 Docker,你或许需要“翻译”这些命令,以适合你运行环境的需要。
本节中,将创建一个 Container 来运行 Docker 的官方 Registry 镜像。你将推送(Push)一个镜像到这个 Registry 服务器,然后再从该 Registry 中拉取(Pull)同一个镜像。
这是个很好的练习,有助于理解客户端与本地 Registry 的基本交互。
1. 安装 Docker。
2. 从 Docker 公共 Registry 中运行 hello-world 镜像。
run 命令自动从 Docker 的官方镜像库中将 hello-world 镜像 pull 下来。
3. 在 localhost 上启动 Registry 服务。
这将在 DOCKER_HOST 上启动一个 Registry 服务,并在 5000 端口监听。
4. 列出镜像。
这个列表应当包括一个由先前运行而得来的 hello-world
镜像。
5. 为本地 repoistory 重新标记 hello-world
镜像。
此命令使用 [REGISTRYHOST/]NAME[:TAG]
格式为 hello-world:latest
重新打标。 REGISTRYHOST
在此例中是 localhost
。在 Mac OSX 环境中,得把 localhost
换成 $(boot2docker ip):5000
。
6. 列出新镜像。
可以看到,新镜像已经出现在列表中。
7. 推送新镜像到本地 Registry 中。
8. 使用 curl
命令及 Docker Registry 服务 API v2 列出 Registry 中的镜像:
也可以通过在浏览器中访问以下地址来获取这些信息:
http : //localhost:5000/v2/hello-mine/tags/list
9. 从你的本地环境中移除所有未使用的镜像:
此命令仅用于说明目的;移除镜像强制 run
从 Registry 而不是从本地缓存拉取。如果在这之后运行 docker images
,在你的镜像列表中,应该看不到任何 hello-world
或 hello-mine
的实例。
10. 试运行 hello-mine
。
命令 run
运行失败,因为你的新镜像在 Docker 公共 Registry 中是不存在的。
11. 现在,尝试指定镜像的 Registry 来运行镜像:
如果你在这之后运行 docker images
, 你会发现里面多了一个 hello-mine
的实例。
Docker 的官方镜像只为简单的测试或除错准备。其配置对多数生产环境来讲都不适用。例如,任何能访问服务器 IP 的客户端,都能推送及拉取镜像。参看下一节,获取使该镜像做好生产环境准备的信息。
当部署一个用于生产环境发布的 Registry 时,须考虑如下因素:
backend storage | 应在何处存储镜像? |
---|---|
access and/or authentication | 用户是否应拥有全部或受控的访问权限?这取决于你为公众提供镜像服务,还是只为公司内部提供。 |
debugging | 当问题或状况发生时,是否有解决这些它们的方法。日志由于可以看到问题动向,这使其很有用。 |
caching | 快速提取镜像可能至关重要,如果依赖镜像进行测试、构建,或有其他自动化系统的话。 |
我们可以配置 Registry 功能特性,用以调整适配这些因素。可以在命令行里指定选项来干这个,或者更通常地,用一个 Registry 配置文件来完成此事。配置文件是 YAML 格式的。
Docker 的官方 Repository 镜像用以下配置文件做了预置:
这个配置非常基本,可以看到这在生产环境下会有一些问题。例如, http
区块详述了运行 Registry 的主机的 HTTP 服务器配置,但服务器没有使用甚至是最低要求的传输层安全性(TLS)配置。接下来我们将配置这些东西。
在本节中,将在服务器上配置 TLS,使能通过 https
协议来通信。在服务器上启用 TLS 是在企业防火墙内运行 Registry 推荐的最低安全配置。达成这一目标的方法之一就是构建你自己的 Registry 镜像。
1. 下载 Registry 源码 。
当然,也可以使用 git clone
命令。
2. 把下载的包解压到本地目录。
解压后创建 distribution
目录。
3. 进入 distribution
目录。
4. 新建 certs
子目录。
5. 使用 SSL 生成自签名证书。
此命令将提示你回答一些基本的信息,用于创建证书。
6. 列出 certs
目录的内容。
当你构建这个 Container 时, certs
目录及其内容也会自动被复制。
distribution
软件库在 cmd
子目录中包含有示例 Registry 配置。在本节中,您可以编辑这些配置之一,以添加 TLS 支持。
1. 编辑 ./cmd/registry/config.yml
文件。
2. 定位到 http
区块。
3. 给服务器的自签名证书新增一个 tls
区块:
提供 Container 内到证书的路径。如果你希望跨 Layer 使用两步认证,那么你可以增加一个 clientcas
区块选项。
4. 保存并关闭该文件。
1. 构建你的 Registry 镜像。
2. 运行你的新镜像。
观察启动时的信息。你应该可以看到 tls
在运行。
3. 使用 curl
验证可以通过 https
连接。
本节介绍了如何使用 docker-compose
,在 nginx
代理背后运行版本 1 和 2 并存的 Registry 服务。并存的 Registry 服务都用 localhost:5000
访问。如果 docker
客户端版本小于 1.6,那么 Nginx 将其请求路由到 1.0 版本的 Registry 服务。从更新版本客户端发来的请求,将路由到 2.0 版本的 Registry 服务。
此过程使用您在上面最后一个过程中创建的 distribution
目录。该目录包含有一个 compose
配置示例。
1. 在你 distribution
目录所在主机上打开一个新的终端窗口。
2. 获取 docker-compose
二进制可执行文件。
此命令将二进制可执行文件安装到 /usr/local/bin
目录。
3. 添加可执行权限到二进制文件。
1. 移除早先的镜像。
该步骤是一个内部管理步骤。这可以防止你在这个例子里错误地选取了旧的镜像。
2. 编辑 distribution/cmd/registry/config.yml
文件,并移除 tls
区块。
如果沿用了前面例子里的东西,你就会有一个 tls
区块。
4. 保存变更并关闭文件。
1. 进入 distribution/contrib/compose/nginx
目录。
该目录包含了 Nginx 及 Registry 的配置文件。
2. 使用 SSL 生成自签名证书。
此命令将提示你回答一些问题,供证书创建使用。
3. 编辑 Dockerfile
并添加以下行。
当你全部搞完的时候,这个文件看上去像下面。
4. 保存并关闭 Dockerfile
文件。
5. 编辑 registry.conf
文件并增加以下配置。
这是一个 nginx
配置文件。
6. 保存并关闭 registry.conf
文件。
1. 进到 distribution/contrib/compose
目录
此目录包含单一个 docker-compose.yml
配置。
此配置按 nginx/Dockerfile
所指定,构建一个新的 nginx
镜像。1.0 版本的 Registry 来自 Docker 的官方公开镜像。Registry 2.0 镜像将从你前面用到的 distribution/Dockerfile
来构建。
2. 获取 Registry 1.0 镜像。
Compose 的配置是在本地寻找此镜像。如果你不做这步,那后面的步骤会失败。
3. 构建 nginx
,Registry 2.0 镜像,以及
此命令将输出其执行过程,直到运行结束。
4. 启动使用了 Compose 的配置。
5. 在另一个终端,显示运行中的配置。
1. 检查一下你 nginx
服务器上的 TLS。
2. 标记 v1
registry 镜像。
3. 将其推送到 localhost。
如果你在使用 1.6 版本的 Docker 客户端,这将推送镜像到 v2
registry。
4. 使用 curl
来列出 Registry 中的镜像。
本例参照引用了分配给 2.0 Registry 服务的特定端口。早些时候,在使用 docker ps
命令显示正在运行的容器时,你应该看到过这个端口。