在局域网内部署 Docker Registry 可以极大的提升平时 pull、push 镜像的速度,从而缩短自动化操作的过程。同时也可以缓解带宽不足的问题,真是一举多得。本文将从创建单机的 Docker Registry 开始,逐步完成局域网内可用的 Docker Registry 的创建,并重点解释如何使用 IP 地址访问 Registry 的方法。

注意,本文假设你已经在使用的 OS 中安装了 docker 引擎。

创建本机使用的 Docker Registry

这是一个非常简单的过程,简单到只需要运行一个 docker 容器就可以了:

  1. $ docker run -d -p : --restart=always --name registry \
  2. -v `pwd`/registry:/var/lib/registry \
  3. registry:

查看一下 5000 端口是否已被监听:

看起来还不错,让我们向本地的 Registry 中推送一个镜像试试。
先找个镜像,打上自己的 tag:

  1. $ docker pull ubuntu
  2. $ docker tag ubuntu localhost:/myubuntu:

从上图我们可以看到,两个镜像完全是一样的,只不过我们创建的 tag 名称不一样而已。
接下来把镜像 push 到本地的 Registry 中:

  1. $ docker push localhost:/myubuntu:

上图显示 push 操作成功了,那再看看文件系统发生了什么变化:

在我们挂载的 ~/registry 目录的子目录中出现了保存镜像 myubuntu 的目录,在这个目录下保存了镜像相关的数据。
最后我们看看能不能从自己的库中 pull 镜像。先把本地的镜像 localhost:5000/myubuntu:20170520 删除掉:

  1. $ docker rmi localhost:/myubuntu:

然后从本地的库中 pull 镜像:

  1. $ docker pull localhost:/myubuntu:

是不是 pull 操作已经成功啦!

创建局域网内可用的 Docker Registry

前面创建的 Registry 可以在局域网内使用吗?我们来做个试验。
运行 Registry 的机器 IP 为:192.168.171.156,我们在局域网中的另一台机器上创建 tag 并执行推送命令:

推送失败了!原因是为了保证安全,跨机的镜像推送操作默认采用的都是 https 协议。也就是说,为了在局域网内使用 Docker Registry, 我们必须配置 https 版的 Registry 服务器。

选择通过 IP 地址访问 registry

由于种种原因,笔者无法为这台 Docker Registry Server 提供一个有效的域名。好在它的 IP 地址是固定的,因此决定通过 IP 地址来访问这台 Registry 服务器。假设这台机器的 IP 地址为:10.32.2.140,下面的描述都以此 IP 地址为例。

创建自签名的证书

既然是在局域网中使用,因此不会大动干戈的去购买 https 证书,自己生成一个自签名的就足够了。但这也存在一个缺点,就是需要在作为客户端的 docker daemon 中安装这个根证书,本文的稍后部分会介绍这一步骤。

在 ubuntu 系统中,下面的命令会在 dcerts 目录下生成秘钥和自签名的证书:

  1. openssl req \
  2. -newkey rsa: -nodes -sha256 \
  3. -keyout dcerts/domain.key \
  4. -x509 -days \
  5. -out dcerts/domain.crt

注意,在执行此命令前需要在当前目录下创建 dcerts 目录。此命令的细节本文就不解释了,有兴趣的同学去查 openssl 命令的帮助文档。

生成证书时,openssl 要求我们输入相关的信息。比如地域和公司、部门的信息。比较重要的是 Common Name,如果你是要为某个域名生成证书,那么这里就应该是你的域名。我们使用的是 IP 地址,所以我就想当然的把 IP 地址放在了这里。很遗憾的是这并不正确!如果拿此时生成的证书去配置 Docker Registry,我们将无法完成 pull/push 操作。配置的 Registry 根本无法在局域网中使用。
此处是一个很隐晦的 openssl 配置问题,当我们使用 IP 地址作为访问服务器的名称时就会碰到。解决的方法也很简单,就是在生成证书的配置文件中指定 subjectAltName 。打开文件 /etc/ssl/openssl.cnf,在 [v3_ca] 节点添加配置项:
subjectAltName = IP:10.32.2.140

保存并退出,然后重新执行上面生成证书的命令。

运行 https 版的 Registry

有了前面创建的证书,我们就可以运行新版的 Registry 了:

  1. $ docker run -d -p : \
  2. --restart=always \
  3. --name registry \
  4. -v `pwd`/dstorage:/var/lib/registry \
  5. -v `pwd`/dcerts:/certs \
  6. -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  7. -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  8. registry:

命令中我们把证书所在的目挂载到了容器的 /certs 目录。然后分别指定了容器的环境变量 REGISTRY_HTTP_TLS_CERTIFICATE 和 REGISTRY_HTTP_TLS_KEY,这两个环境变量会引用我们常见的秘钥文件和证书文件。
好了,到目前为止新版的 Docker Registry 已经可以提供服务了。

在 client 端设置根证书

为了快速、方便和省钱,我们没有去购买商业版的证书。这种方式的弊端是:必须把我们生成的根证书安装到每一个需要访问 Registry 服务器的客户端上。具体做法如下:
把前面生成的证书文件 dcerts/domain.crt 复制到需要访问 Registry 服务器的机器上。放到目录 /etc/docker/certs.d/10.32.2.140:5000/ 中,并重命名为 ca.crt。当然这个目录需要你自己创建。最后重新启动 docker 服务:

  1. $ sudo systemctl restart docker.service // 不同的系统重启服务的命令可能不一样。

终于大功告成了,让我们往 Registry 中推送一个镜像吧:

看,redis:3.2 已经被 tag 为 10.32.2.140:5000/myredis:20170520,并推送到了局域网中的 Docker Registry Server 中。
为了验明正身,我们还是到 10.32.2.140 上去看一下文件存储的状态:

从这张图中我们可以看到,myredis:20170520 真的已经被 Registry 保存到文件系统中了。

总结

由于安全性的考虑,配置局域网内可用的 Docker Registry 稍微有点麻烦。尤其是使用 IP 地址的配置方式,需要配置证书的 subjectAltName 才能正常工作。但完成配置后,使用局域网内的 Registry 还是很爽的。希望本文对有类似需求的朋友们有所帮助。

局域网内部署 Docker Registry的更多相关文章

  1. 部署 Docker Registry 并配置认证登录

    文章目录 搭建 Docker Registry 创建本地映射目录 启动 Docker Registry 配置 Docker Registry 配置 Docker Registry 认证 启动带认证的 ...

  2. ubuntu docker方式部署docker registry v2

    生成自己签名的证书 生成签名的过程需要根据提示输入一些参数,需要注意的时Common Name的时候需要输入一个自己需要的域名,如果时内部域名记得访问的时候需要修改hosts. mkdir /data ...

  3. 【云计算】docker registry v2简介

    ubuntu docker方式部署docker registry v2 2016-03-03 17:36 by JackieHan, 4 阅读, 0 评论, 收藏,  编辑 生成自己签名的证书 生成签 ...

  4. docker registry 镜像删除

    registry:2.5.0版本的镜像,将镜像默认存放在了/var/lib/registry 目录下 /var/lib/registry/docker/registry/v2/repositories ...

  5. 在centos下部署docker内网私服

    Docker内网私服:docker-registry with nginx & ssl on centos docker-registry既然也是软件应用,自然最简单的方法就是使用官方提供的已 ...

  6. 部署私有Docker Registry

    安装部署一个私有的Docker Registry是引入.学习和使用Docker这门技术的必经之路之一.尤其是当Docker被所在组织接受,更多人.项目和产品开始接触和使用Docker时,存储和分发自制 ...

  7. 将vue项目部署在Linux的Nginx下,并设置为局域网内访问

    1. 下载 wget http://nginx.org/download/nginx-1.12.2.tar.gz 2. 解压缩 tar -zxvf linux-nginx-1.12.2.tar.gz ...

  8. Linux系统如何在离线环境或内网环境安装部署Docker服务和其他服务

    如何在离线环境或纯内网环境的Linux机器上安装部署Docker服务或其他服务.本次我们以Docker服务和Ansible服务为例. 获取指定服务的所有rpm包 保证要获取rpm包的机器能够上网. 本 ...

  9. IIS部署网站局域网内无法访问

    今天在局域网发布一个网站时遇到了个问题,在本机上可以访问,但局域网内其他机子访问此IP地址时无法显示,这个问题以前也遇到过,现在总结一下处理方法 检查两个方面: IIS网站身份验证 在IIS中选择要发 ...

随机推荐

  1. Alamofire源码解读系列(十二)之时间轴(Timeline)

    本篇带来Alamofire中关于Timeline的一些思路 前言 Timeline翻译后的意思是时间轴,可以表示一个事件从开始到结束的时间节点.时间轴的概念能够应用在很多地方,比如说微博的主页就是一个 ...

  2. 在IIS上部署你的ASP.NET Core项目

    概述 与ASP.NET时代不同,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角色转发请求到Kest ...

  3. JSP/Servlet------------------------->>动态网页开发基础(一)

    动态网页:是指在服务器端运行的,使用程序语言设计的交互式网页,它们会根据某种条件的变化,返回不同的网页内容. 动态网站可以实现交互功能,如用户注册.信息发布.产品展示.订单管理等等: 动态网页并不是独 ...

  4. Spring+SpringMVC+MyBatis+easyUI整合优化篇(九)数据层优化-jdbc连接池简述、druid简介

    日常啰嗦 终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和da ...

  5. AngularJS路由跳转

    AngularJS是一个javascript框架,通过AngularJS这个类库可以实现目前比较流行的单页面应用,AngularJS还具有双向数据绑定的特点,更加适应页面动态内容. 所谓单页面应用就是 ...

  6. 文本处理sed常用操作

    文本处理sed常用操作 linux sed (stream editor) is a Unix utility that parses and transforms text, using a sim ...

  7. linux 线程编程详解

    1.线程的概念: 线程和进程有一定的相似性,通常称为轻量级的进程 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等.但同一进程中的多个线程都有自身控制流 (它 ...

  8. JavaWeb开发之Servlet

    1. Servlet有关概念和前置知识 1.1 什么是动态网页 如果浏览器在不同时刻或不同条件下访问web服务器上的某个页面,浏览器所获得的页面内容可以发生变化,那么这个页面就称之为动态页面. 动态网 ...

  9. 深入理解MVC

    首先我们来看看MVC架构的示意图:             和访问者交互的是控制层(Controller层),控制器(controller)是同类交互的集合,每一个交互的操作,都对应了一个动作(act ...

  10. Patterns for application development with ASP.NET Core

    此文章翻译自 NDC { London } 16-20 January 2017 上, Damian Edwards和David Fowler的演讲,如果翻译不周,请大家指出错误. Logging 生 ...