局域网内部署 Docker Registry
<p><span style="font-family: Microsoft YaHei; font-size: 15px">在局域网内部署 Docker Registry 可以极大的提升平时 pull、push 镜像的速度,从而缩短自动化操作的过程。同时也可以缓解带宽不足的问题,真是一举多得。本文将从创建单机的 Docker Registry 开始,逐步完成局域网内可用的 Docker Registry 的创建,并重点解释如何使用 IP 地址访问 Registry 的方法。</span></p><p><span style="font-family: Microsoft YaHei; font-size: 15px">注意,本文假设你已经在使用的 OS 中安装了 docker 引擎。</span></p>
<h1><span style="font-family: Microsoft YaHei; font-size: 18pt">创建本机使用的 Docker Registry</span></h1>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">这是一个非常简单的过程,简单到只需要运行一个 docker 容器就可以了:</span></p>
<div class="cnblogs_code">
<pre>$ docker run -d -p <span style="color: rgba(128, 0, 128, 1)">5000</span>:<span style="color: rgba(128, 0, 128, 1)">5000</span> --restart=always --<span style="color: rgba(0, 0, 0, 1)">name registry \
</span>-v `<span style="color: rgba(0, 0, 255, 1)">pwd</span>`/registry:/var/lib/<span style="color: rgba(0, 0, 0, 1)">registry \
registry:</span><span style="color: rgba(128, 0, 128, 1)">2</span></pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">查看一下 5000 端口是否已被监听:</span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522191535398-513222693.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">看起来还不错,让我们向本地的 Registry 中推送一个镜像试试。</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">先找个镜像,打上自己的 tag:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ docker pull ubuntu
$ docker tag ubuntu localhost:</span><span style="color: rgba(128, 0, 128, 1)">5000</span>/myubuntu:<span style="color: rgba(128, 0, 128, 1)">20170520</span></pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522191612851-1755284256.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">从上图我们可以看到,两个镜像完全是一样的,只不过我们创建的 tag 名称不一样而已。</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">接下来把镜像 push 到本地的 Registry 中:</span></p>
<div class="cnblogs_code">
<pre>$ docker push localhost:<span style="color: rgba(128, 0, 128, 1)">5000</span>/myubuntu:<span style="color: rgba(128, 0, 128, 1)">20170520</span></pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522191653726-1171584606.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">上图显示 push 操作成功了,那再看看文件系统发生了什么变化:</span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522191737835-905752712.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">在我们挂载的 ~/registry 目录的子目录中出现了保存镜像 myubuntu 的目录,在这个目录下保存了镜像相关的数据。</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">最后我们看看能不能从自己的库中 pull 镜像。先把本地的镜像 localhost:5000/myubuntu:20170520 删除掉:</span></p>
<div class="cnblogs_code">
<pre>$ docker rmi localhost:<span style="color: rgba(128, 0, 128, 1)">5000</span>/myubuntu:<span style="color: rgba(128, 0, 128, 1)">20170520</span></pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">然后从本地的库中 pull 镜像:</span></p>
<div class="cnblogs_code">
<pre>$ docker pull localhost:<span style="color: rgba(128, 0, 128, 1)">5000</span>/myubuntu:<span style="color: rgba(128, 0, 128, 1)">20170520</span></pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">是不是 pull 操作已经成功啦!</span></p>
<h1><span style="font-family: Microsoft YaHei; font-size: 18pt">创建局域网内可用的 Docker Registry</span></h1>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">前面创建的 Registry 可以在局域网内使用吗?我们来做个试验。</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">运行 Registry 的机器 IP 为:192.168.171.156,我们在局域网中的另一台机器上创建 tag 并执行推送命令:</span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522191850304-1473107322.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">推送失败了!原因是为了保证安全,跨机的镜像推送操作默认采用的都是 https 协议。也就是说,为了在局域网内使用 Docker Registry, 我们必须配置 https 版的 Registry 服务器。</span></p>
<h2><span style="font-family: Microsoft YaHei; font-size: 18px">选择通过 IP 地址访问 registry</span></h2>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">由于种种原因,笔者无法为这台 Docker Registry Server 提供一个有效的域名。好在它的 IP 地址是固定的,因此决定通过 IP 地址来访问这台 Registry 服务器。假设这台机器的 IP 地址为:10.32.2.140,下面的描述都以此 IP 地址为例。</span></p>
<h2><span style="font-family: Microsoft YaHei; font-size: 18px">创建自签名的证书</span></h2>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">既然是在局域网中使用,因此不会大动干戈的去购买 https 证书,自己生成一个自签名的就足够了。但这也存在一个缺点,就是需要在作为客户端的 docker daemon 中安装这个根证书,本文的稍后部分会介绍这一步骤。</span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">在 ubuntu 系统中,下面的命令会在 dcerts 目录下生成秘钥和自签名的证书:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">openssl req \
</span>-newkey rsa:<span style="color: rgba(128, 0, 128, 1)">4096</span> -nodes -<span style="color: rgba(0, 0, 0, 1)">sha256 \
</span>-keyout dcerts/<span style="color: rgba(0, 0, 0, 1)">domain.key \
</span>-x509 -days <span style="color: rgba(128, 0, 128, 1)">356</span><span style="color: rgba(0, 0, 0, 1)"> \
</span>-out dcerts/domain.crt</pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">注意,在执行此命令前需要在当前目录下创建 dcerts 目录。此命令的细节本文就不解释了,有兴趣的同学去查 openssl 命令的帮助文档。</span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522192100226-413613752.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">生成证书时,openssl 要求我们输入相关的信息。比如地域和公司、部门的信息。比较重要的是 Common Name,如果你是要为某个域名生成证书,那么这里就应该是你的域名。我们使用的是 IP 地址,所以我就想当然的把 IP 地址放在了这里。很遗憾的是这并不正确!如果拿此时生成的证书去配置 Docker Registry,我们将无法完成 pull/push 操作。配置的 Registry 根本无法在局域网中使用。</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">此处是一个很隐晦的 openssl 配置问题,当我们使用 IP 地址作为访问服务器的名称时就会碰到。解决的方法也很简单,就是在生成证书的配置文件中指定 subjectAltName 。打开文件 /etc/ssl/openssl.cnf,在 节点添加配置项:</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">subjectAltName = IP:10.32.2.140 </span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522192219398-430702204.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">保存并退出,然后重新执行上面生成证书的命令。</span></p>
<h1><span style="font-family: Microsoft YaHei; font-size: 18pt">运行 https 版的 Registry</span></h1>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">有了前面创建的证书,我们就可以运行新版的 Registry 了:</span></p>
<div class="cnblogs_code">
<pre>$ docker run -d -p <span style="color: rgba(128, 0, 128, 1)">5000</span>:<span style="color: rgba(128, 0, 128, 1)">5000</span><span style="color: rgba(0, 0, 0, 1)"> \
</span>--restart=<span style="color: rgba(0, 0, 0, 1)">always \
</span>--<span style="color: rgba(0, 0, 0, 1)">name registry \
</span>-v `<span style="color: rgba(0, 0, 255, 1)">pwd</span>`/dstorage:/var/lib/<span style="color: rgba(0, 0, 0, 1)">registry \
</span>-v `<span style="color: rgba(0, 0, 255, 1)">pwd</span>`/dcerts:/<span style="color: rgba(0, 0, 0, 1)">certs \
</span>-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/<span style="color: rgba(0, 0, 0, 1)">domain.crt \
</span>-e REGISTRY_HTTP_TLS_KEY=/certs/<span style="color: rgba(0, 0, 0, 1)">domain.key \
registry:</span><span style="color: rgba(128, 0, 128, 1)">2</span></pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">命令中我们把证书所在的目挂载到了容器的 /certs 目录。然后分别指定了容器的环境变量 REGISTRY_HTTP_TLS_CERTIFICATE 和 REGISTRY_HTTP_TLS_KEY,这两个环境变量会引用我们常见的秘钥文件和证书文件。</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">好了,到目前为止新版的 Docker Registry 已经可以提供服务了。</span></p>
<h1><span style="font-family: Microsoft YaHei; font-size: 18pt">在 client 端设置根证书</span></h1>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">为了快速、方便和省钱,我们没有去购买商业版的证书。这种方式的弊端是:必须把我们生成的根证书安装到每一个需要访问 Registry 服务器的客户端上。具体做法如下:</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">把前面生成的证书文件 dcerts/domain.crt 复制到需要访问 Registry 服务器的机器上。放到目录 /etc/docker/certs.d/10.32.2.140:5000/ 中,并重命名为 ca.crt。当然这个目录需要你自己创建。最后重新启动 docker 服务:</span></p>
<div class="cnblogs_code">
<pre>$ <span style="color: rgba(0, 0, 255, 1)">sudo</span> systemctl restart docker.service <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 不同的系统重启服务的命令可能不一样。</span></pre>
</div>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">终于大功告成了,让我们往 Registry 中推送一个镜像吧:</span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522192424507-779885161.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">看,redis:3.2 已经被 tag 为 10.32.2.140:5000/myredis:20170520,并推送到了局域网中的 Docker Registry Server 中。</span><br><span style="font-family: Microsoft YaHei; font-size: 15px">为了验明正身,我们还是到 10.32.2.140 上去看一下文件存储的状态:</span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px"><img src="http://images2015.cnblogs.com/blog/952033/201705/952033-20170522192512913-278656592.png"></span></p>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">从这张图中我们可以看到,myredis:20170520 真的已经被 Registry 保存到文件系统中了。</span></p>
<h1><span style="font-family: Microsoft YaHei; font-size: 18pt">总结</span></h1>
<p><span style="font-family: Microsoft YaHei; font-size: 15px">由于安全性的考虑,配置局域网内可用的 Docker Registry 稍微有点麻烦。尤其是使用 IP 地址的配置方式,需要配置证书的 subjectAltName 才能正常工作。但完成配置后,使用局域网内的 Registry 还是很爽的。希望本文对有类似需求的朋友们有所帮助。</span></p>
</div>
<div id="MySignature" role="contentinfo">
<div>作者:sparkdev</div>
<div>出处:http://www.cnblogs.com/sparkdev/</div>
<div>本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。</div><br><br>
来源:https://www.cnblogs.com/sparkdev/p/6890995.html
頁:
[1]