构建
参考 Configuring a registry 手册,以获取更加详细的说明;
https://docs.docker.com/registry/configuration/
参考 Considerations for air-gapped registries. 手册,以获取隔离数据中心的部署方法
https://docs.docker.com/registry/deploying/#considerations-for-air-gapped-registries
先在机器上安装 Docker,然后运行 registry 镜像;
搭建 Registry 服务
Docker 公开 Register 代码,我们能够自行运行 Register,搭建私有服务,放在防火墙之后,但是没有用户界面,只能通过 API 访问;
运行服务
运行一个 Register 服务非常简单:docker run -p 5000:5000 registry:2,该命令启动一个 Registry 2.0 的容器,并将5000端口绑定到宿主机上。如果你的 Registry 低于 2.0 版本,则可以使用迁移工具「docker/migrator」来升级;
从 Docker 1.3.1 开始,需要在启动 Docker 守护进程的命令中添加--insecure-registry localhost:5000标志,并重启守护进程,才能使用本地 Registry 服务;
启动 Registry 容器:
docker run -d -p 5000:5000 --restart=always --name registry registry:2 # 通过环境变量,能够覆盖配置。 # 环境变量的格式为:针对某个配置文件变量,使用 _ 连接层级,并将变量名替换为大写,并前缀 REGISTRY_; # 例如 proxy.remoteurl 用环境变量表示则为 REGISTRY_PROXY_REMOTEURL
至此容器已经启动;
上面的示例仅适用于测试环境的 Registry 配置。生产环境的 Registry 必须受 TLS 保护,理想情况下应使用「访问控制」机制。「本文后续内容」及「configuration guide」以部署生产就绪的注册表;
推送镜像
测试新的 Registry 服务:
1)找到镜像 ID 值:docker images your/image
2)为镜像打标签:docker tag image_id docker.example.com:5000/jam/static_web
3)推送新的镜像:docker push docker.example.com:5000/jam/static_web
4)运行新的镜像:docker run -t -i docker.example.com:5000/jam/static_web
有关 Registry 的配置及管理参考官方的「Docker Registry | Docker Documentation」部署说明;
从 Docker Hub 拉取镜像到本地,然后重新打标,然后推送到本地的 Registry 中:
# 拉取 docker pull ubuntu:16.04 # 打标 docker tag ubuntu:16.04 localhost:5000/my-ubuntu # 推到本地 Registry 中 docker push localhost:5000/my-ubuntu # 删除镜像 docker image remove ubuntu:16.04 docker image remove localhost:5000/my-ubuntu # 从 Registry 中拉去镜像 docker pull localhost:5000/my-ubuntu
停止服务
# 停止 docker container stop registry # 停止并删除 Registry 服务 docker container stop registry && docker container rm -v registry # 通过 -v 选项删除孤立的卷
修改基本配置
通过为docker run指定选项来控制某些行为,详细参考「registry configuration reference」手册;
自动启动容器:在「Docker 重启」或者「容器退出」时自动启动容器,则可以使用--restart=always选项;
修改端口号:使用-p 5001:5000选项修改暴露的端口号。使用-e REGISTRY_HTTP_ADDR=0.0.0.0:5001修改内部端口号;
自定义存储位置:默认使用 Docker 卷来存储 Registry 数据,如果要自定义路径,则可以使用-v选项指定挂载路径。也可以使用其他的后端存储,参考「storage configuration options」手册;
运行外部可访问的 Registry 服务
本地可访问的 Registry 功能有限。如果想外部可访问,则要先配置 TLS 证书;
使用正常证书
# 启动容器,并指定镜像 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 pull ubuntu:16.04 docker tag ubuntu:16.04 myregistrydomain.com/my-ubuntu docker push myregistrydomain.com/my-ubuntu
证书颁发者可以为你提供中间证书。在这种情况下,必须将证书与中间证书连接在一起以形成证书包。进行一步额外的操作:
cat domain.crt intermediate-certificates.pem > certs/domain.crt
支持 Let’s Encrypt 证书
Registry 支持使用 Let’s Encrypt,来自动获取浏览器可信证书。有关 Let’s Encrypt 的更多信息,请参阅「Let’s Encrypt/How It Works」以及「registry configuration」相关部分;
使用不安全的 Registry 服务(仅测试)
不安全的 Registry 服务有两个方案:
1)使用 HTTP 协议;
2)使用自签名证书;
参考「run an insecure registry」部分的详细说明;
# 使用 HTTP 协议:使用 HTTP 协议的 Registry 服务就不再介绍,因为没法在公网部署。主要是因为不安全的 Register 服务无法使用 Basic Auth 认证,换作其他高级认证更麻烦,资源不允许;
# 使用自签名证书:这里介绍一下在 Linux 中使用自签名证书的 Registry 服务的部署,使用 Basic Auth 认证,并提供公网访问:
#!/bin/sh # 我们使用 registry.d3rm.org 作为 CN 值 ################################################################################ # 创建证书 ################################################################################ mkdir -p certs openssl req \ -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \ -x509 -days 365 -out certs/domain.crt # 注意 CN 名为域名,这里使用 registry.d3rm.org 作为 CN 值; ################################################################################ # 指示 Docker 信任 CA ################################################################################ mkdir -pv /etc/docker/certs.d/registry.d3rm.org:5000/ cp certs/domain.crt /etc/docker/certs.d/registry.d3rm.org:5000/ca.crt systemctl restart docker.service # !!!这里的操作分为两此,Client 和 Server 都要进行该操作。否则会产生「X509 errors」错误,这 # 个错误通常都是由于整数配置不正确导致的; ################################################################################ # 使用 TLS 启动 Registry 服务 ################################################################################ mkdir auth docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v "$(pwd)"/auth:/auth \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -v "$(pwd)"/certs:/certs \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ registry:2 ################################################################################ # 测试 ################################################################################ docker login registry.d3rm.org:5000 docker push registry.d3rm.org:5000/dockerfile-from-image
作为服务来运行 Registry
负载均衡的一些考虑
限制访问
除了内网访问之外,应该给 Registry 加上访问限制;
使用 Basic Auth 认证
在进行这一步骤之前需要先配置 TLS 先。然后才能进行如下操作:
# 生成基础认证 htpasswd -Bbn testuser testpassword > auth/htpasswd # 停止容器 docker container stop registry # 启动容器并指定基础认证 docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v "$(pwd)"/auth:/auth \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -v "$(pwd)"/certs:/certs \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ registry:2 # 至此,拉去镜像会失败,需要提供用户名密码来登录 docker login myregistrydomain.com:5000 # 注意事项: # X509 errors: X509 错误通常表示尝试使用自签名证书,并且未正确配置 Docker 守护程序;
#2 更多高级认证
可以在 Registry 的前端加入一些代理,实现更高级的认证,参考「recipes list」手册;
Registry 还支持委派身份验证,将用户重定向到特定的受信任口令服务器。这种方法设置起来比较复杂,只有在需要完全配置 ACL,并且需要对 Registry 集成到全局授权和身份验证系统的更多控制时才有意义。参考「background information」和「configuration information here」手册;
此方法要求你实现自己的身份验证系统或利用第三方实现;
使用 Compose 文件部署 Registry 服务
「Deploy your registry using a Compose file」
有网闸的 Registry 服务
参考「Considerations for air-gapped registries」手册
参考文献
Docker/Deploy a registry server
How to Setup Docker Private Registry on CentOS 7.x / RHEL 7.x
Docker/Configuring a registry