「Docker」- 部署一个Registry服务器

更新日期:2019年07月10日

先在机器上安装Docker,然后运行registry镜像。

本文只是一个简单的介绍,详细参考「Configuring a registry」手册。隔离数据中心的部署参考「Considerations for air-gapped registries.」手册。

# 搭建简易的Registry服务

部署本地Registry服务

启动一个Registry容器:

#!/bin/sh

docker run -d -p 5000:5000 --restart=always --name registry registry:2

至此容器已经启动。

!!!上面的示例仅适用于测试环境的Registry配置。生产环境的Registry必须受TLS保护,理想情况下应使用「访问控制」机制。 「本文后续内容」及「configuration guide」以部署生产就绪的注册表。

从Docker Hub复制镜像到本地Registry中

从Docker Hub拉取镜像到本地,然后重新打标,然后推送到本地的Registry中:

#!/bin/sh

# 拉取
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

停止本地Registry服务

#!/bin/sh

# 停止
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证书。

使用正常证书

#!/bin/sh

# 启动容器,并指定镜像
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

证书颁发者可以为你提供中间证书。在这种情况下,必须将证书与中间证书连接在一起以形成证书包。进行一步额外的操作:

#!/bin/sh

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服务有两个方案:

	* 使用HTTP协议;
	* 使用自签名证书;

参考「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

Run the registry as a service

负载均衡的一些考虑

Load balancing considerations

# 限制访问

除了内网访问之外,应该给Registry加上访问限制。

#1 使用Basic Auth认证

在进行这一步骤之前需要先配置TLS先。然后才能进行如下操作:

#!/bin/sh

# 生成基础认证
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


ToC

# 搭建简易的Registry服务

部署本地Registry服务

从Docker Hub复制镜像到本地Registry中

停止本地Registry服务

# 修改基本配置

# 运行外部可访问的Registry服务

使用正常证书

支持Let’s Encrypt证书

# 使用不安全的Registry服务(仅测试)

作为服务来运行Registry

负载均衡的一些考虑

# 限制访问

#1 使用Basic Auth认证

#2 更多高级认证

使用Compose文件部署Registry服务

有网闸的Registry服务

参考文献