本文绝大部分篇幅是翻译了docker registry的官方文档1,如有问题,请各位不吝指正。好,废话不多说,请见正文。
在你部署一个registry
之前,你需要首先在你的主机上安装一个Docker
. Registry
是一个跑在Docker
里面的registry
镜像的实例。
本次主题提供了部署和配置registry
的基础信息。如需详尽的配置信息,请查看配置指南。
如果你有一个air-gapped
数据中心,请查阅air-gapped registry条件
部署本地registry
使用下面的命令启动一个registry container:
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
之后,该registry 就可以正常工作了。
警告:这个案例只是用来展示
registry
配置的,只适用于测试。一个产品级的registry
必须受TLS
保护,而且必须启用权限控制。继续阅读,参照配置指南去部署一个产品级的registry
。
从Docker Hub上下载一个镜像到你的registry
你可以从Docker Hub
上下载一个镜像,然后推送到你的registry
中。以下展示了从Docker Hub
上下载ubuntu:16:04
镜像,然后重新打上my-ubuntu
的标签,然后将他推送到本地registry中。最终,删除本地的ubuntu:16:04
,my-ubuntu
镜像,然后从本地的registry 中下载ubuntu:16:04
镜像。
- 从
Docker Hub
中下载ubuntu:16:04
镜像:
$ docker pull ubuntu:16.04
- 为
ubuntu:16.04
重新打上localhost:5000/my-ubuntu
标签。这条命令为已经存在的镜像创建了一个额外的标签。如果标签的前部是一本IP地址和端口号,当推送镜像时,Docker 会解析这为一个registry的地址。
$ docker tag ubuntu:16.04 localhost:5000/my-ubuntu
- 推送镜像到跑在本地
5000
端口的registry
:
$ docker push localhost:5000/my-ubuntu
- 删除本地缓存的
ubuntu:16:04
和localhost:5000/my-ubuntu
镜像,测试从你的registry中拉取镜像。拉取镜像并不会从你的registry中移除镜像。
$ docker image remove ubuntu:16.04
$ docker image remove localhost:5000/my-ubuntu
- 从你的registry中拉取
localhost:5000/my-ubuntu
镜像
$ docker pull localhost:5000/my-ubuntu
停止运行你的registry
使用和停止其他容器相同的docker container stop
命令来停止你的registry
。
$ docker container stop registry
使用docker container rm 命令来移除此container
$ docker container stop registry && docker container rm -v registry
基础配置
你可以使用docker run
命令来传输额外的或者修改过的配置项到container
中。
以下章节提供基础的配置registry
的指导。如需详细信息,请查阅registry 配置指南。
自动启动registry
如果你想将registry 成为你常驻基础设施的一部分,你应该设置registry
随Docker
重启或者存在而重启。以下例子展示了通过设置 --restart always
配置项定义了registry
的重启策略。
$ docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
registry:2
自定义启动端口
如果你已经使用了5000
端口,或者你想运行多个本地registry
,用来分隔关注的领域,你可以自定义registry的端口。下面例子中定义了一个名字为registry-test
,跑在5001
端口上的registry
。请记住, -p
的第一个部分是主机的关口,第二个部分是容器的端口。容器中,registry
默认监听5000
端口。
$ docker run -d \
-p 5001:5000 \
--name registry-test \
registry:2
如果你想要改变容器中registry
默认监听的端口,你可以定义一个环境变量REGISTRY_HTTP_ADDR
来改变默认端口设置。下面的命令可以是registry
监听容器中的5001
端口:
$ docker run -d \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \
-p 5001:5001 \
--name registry-test \
registry:2
自定义存储
自定义存储位置
默认情况下,你的registry数据会以docker volume
的形式保存在主机的文件系统。如果你希望改变你的registry内容的存储位置,譬如你已经有块挂载到指定目录的SSD
或者SAN
,你可以决定只用一个挂载点来代替。一个挂载点是强依赖Docker
主机的文件系统的,但是在很多情境下很好用。下面的例子展示了绑定本地的/mnt/registry
到registry容器中的 /var/lib/registry/
.
$ docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /mnt/registry:/var/lib/registry \
registry:2
自定义存储后端
默认情况下,无论你使用挂载点或者volume形式,registry 都会将数据保存在本地的文件系统中。你可以使用存储驱动存储registry的数据到Amazon S3 bucket, Google Cloud Platform, 或者其他存储后端。如需获取更多信息,请访问存储配置选项。
运行一个外部可访问的registry
只运行一个本地可访问的registry 会有使用限制。为了使你的 registry可以对外访问,你可以首先配置TLS 安全访问。
本例是将启动容器作为一种服务来提供出去。
获取证书
下面的例子假设:
- 你的registry地址是https://myregistry.domain.com/.
- 你的DNS,路由,防火墙设置可以通过主机的443端口你的registry
- 你已经从CA哪里获取了一个认证
如果你想使用中级证书代替,详情查阅下文中级证书。
新建一个证书目录。
$ mkdir -p certs
拷贝.crt
和.key
文件到新建的certs
目录中。接下来的步骤假设认证文件domain.crt
和domain.key
.
停止当前正在跑的registry。
$ docker container stop registry
重启registry,使其使用TLS
证书。下面的命令挂载本机certs/
目录到容器中的/certs/
目录, 而且设置环境变量告诉容器在那里发现domain.crt
和domain.key
问加你。registry跑在443
端口,为默认的HTTPS
端口。
$ docker run -d \
--restart=always \
--name registry \
-v "$(pwd)"/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-p 443:443 \
registry:2
Docker 客户端现在可以使用registry的外部地址,推送和下载镜像到你的registry中。下面的命令可以证明:
$ docker pull ubuntu:16.04
$ docker tag ubuntu:16.04 myregistrydomain.com/my-ubuntu
$ docker push myregistrydomain.com/my-ubuntu
$ docker pull myregistrydomain.com/my-ubuntu
使用中级证书
一个证书发行者可以提供给你中级证书。这种情况下,你可以讲你的证书和中级证书串成一个bundle(不知道怎么翻译这个词~~)。你可以使用如下命令:
$ cat domain.crt intermediate-certificates.pem > certs/domain.crt
现在你可以使用这个证书bundle,就如上一个例子当中那样。
支持 Let’s Encrypt
registry支持使用 Let’sEncrypt 获得浏览器信任的证书。详细信息请查阅 Let’s Encrypt 和 registry 配置的相关章节。
使用不安全的registry(仅供测试使用)
使用自签证书也是有可能的,或者以一种不被信任的方式使用registry。除非你已经对你的自签证书做好验证,否则这只供测试使用。详情查看使用不安全的registry。
docker-compose
总结以上,可以使用docker-compose 配置文件启动一个安全的docker registry。
version: '3'
services:
registry:
image: registry:2
ports:
- 443:443
environment:
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: 'Registry Realm'
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_DELETED_ENABLED: 'true'
REGISTRY_HTTP_ADDR: 0.0.0.0:443
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/registry.crt
REGISTRY_HTTP_TLS_KEY: /certs/registry.key
volumes:
- /docker/registry:/var/lib/registry
- ./certs:/certs
- ./auth:/auth
启动命令:
$ docker-compose up -d
操作要点
- 生成ca证书,启动tls连接
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout certs/domain.key -out certs/domain.crt
- unknown authority 解决
可以采用将证书内容添加操作系统的CA信任库中/etc/pki/tls/certs/ca-bundle.crt
或者将CA证书放到/etc/docker/certs.d/<registry>/
目录中 - 限制访问,可以使用双向SSL方法或者密码的方法
- 采用密码方式
docker run --rm --entrypoint htpasswd registry:2 -Bbn root passw0rd > auth/htpasswd
- 采用双向SSL 方式
太复杂,暂时不介绍
参考
- https://blog.csdn.net/yucdsn/article/details/85267056
- https://www.jianshu.com/p/781b3e27793c
- https://www.cnblogs.com/xcloudbiz/articles/5526262.html
- http://www.cnblogs.com/guogangj/p/4118605.html
- http://dockone.io/article/1277