基于证书访问的Docker Registry的搭建

楔子

我们一般测试开发的时候,都习惯于直接从公共镜像仓库hub.docker.com拉取所需镜像,但是实际生产环境中可能涉及自建镜像和网络等各方面的原因,这个时候或许预先搭建自己的镜像仓库可能会更方便些,如下就来讲讲基于证书访问的docker registry的搭建流程。

创建自签名证书

首先,不管是Registry客户端还是服务器端都默认已经安装docker、openssl等工具。另外这儿Registry Server和客户端是一台主机且IP是10.0.2.15,域名vienfu.dockerhub.com,因此要做域名的解析配置:

echo "10.0.2.15 vienfu.dockerhub.com" >> /etc/hosts

然后开始创建自签名证书:

mkdir -p /root/certs.d
cd /root/certs.d
openssl req -newkey rsa:2048 -nodes -sha256 -keyout ./domain.key -x509 -days 365 -out ./domain.crt  # 根据提示依次填入所需信心,注意Common Name处要填入之前被解析的域名vienfu.dockerhub.com

# 客户端证书拷贝
mkdir -p /etc/docker/certd.d/vienfu.dockerhub.com:5000
cp /root/certs.d/domain.crt /etc/docker/certd.d/vienfu.dockerhub.com:5000/ca.crt

# 如果后续欲通过curl证书访问registry接口,还需要做如下操作:
cat /root/certs.d/domain.crt >> /etc/ssl/certs/ca-certificates.crt

以上所有操作完成后,重启dockersystemctl restart docker

创建Registry容器

首先,可以预先拉取registry镜像:

docker pull registry:2

如果考虑到持久化和镜像的删除问题,可以预先做如下操作:

mkdir -p /root/docker_image_mgr/registry

cat << EOF >> /root/docker_image_mgr/config.yml
version: 0.1
log:
  fields:
    service: registry
storage:
  delete:
    enabled: true  # 其中delete.enabled是为镜像删除设置的字段
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3
EOF

启动registry容器:

docker run -d -p 5000:5000 --name my-registry -v /root/docker_image_mgr/registry:/var/lib/registry -v /root/docker_image_mgr/config.yml:/etc/docker/config.yml -v /root/certs.d:/root -e REGISTRY_HTTP_TLS_CERTIFICATE=/root/domain.crt -e REGISTRY_HTTP_TLS_KEY=/root/domain.key registry:2

# 启动之后,docker ps看一下启动状态
root@kolla:~# docker ps
CONTAINER ID        IMAGE                                     COMMAND                  CREATED             STATUS              PORTS                               NAMES
ed96182fa77d        registry:2                                "/entrypoint.sh /etc/"   15 hours ago        Up 15 hours         0.0.0.0:5000->5000/tcp              my-registry

如此Registry Server启动完成,下面不妨测试一下可否向该Registry Server上传镜像。

docker tag hello-world vienfu.dockerhub.com:5000/hello-world:test
docker push vienfu.dockerhub.com:5000/hello-world:test

简单通过curl命令来查看镜像是否上传:

root@kolla:~#curl -X GET https://vienfu.dockerhub.com:5000/v2/_catalog
{"repositories":["hello-world"]}

如此我们看到镜像也的确上传成功了。

仓库加鉴权

出于安全考虑,一般在认证之后还需要做一个鉴权来控制用户的访问权限,这儿仅介绍最基本的鉴权方式:用户名和密码访问模式。

首先创建一个用户及访问的密码,这儿假设用户名和密码分别是vienfu、Fch19880810

mkdir -p /root/auth
docker run --entrypoint htpasswd registry:2 -Bbn vienfu Fch19880810 > /root/auth/htpasswd

然后把之前起的容器停掉并且删除:

docker stop my-registry
docker rm my-registry

最后启动一个带鉴权的registry容器:

docker run -d -p 5000:5000 --name my-registry \
-v /root/auth:/auth \
-v /root/docker_image_mgr/registry:/var/lib/registry \
-v /root/docker_image_mgr/config.yml:/etc/docker/registry/config.yml \
-v /root/certs.d:/root \
-e "REGISTRY_AUTH=htpasswd" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/root/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/root/domain.key \
registry:2

那也不妨测试一下,实际上我们不难发现,这个时候如果我们直接docker push来上传镜像会失败,这是因为设置了鉴权访问的参数需要先做如下操作:

docker login vienfu.dockerhub.com:5000 # 根据提示输入之前设置的用户名和密码

如此我们再通过docker push上传镜像就ok啦,最后也通过curl命令来查看一下吧:

root@kolla:~# curl -u vienfu:Fch19880810 -X GET https://vienfu.dockerhub.com:5000/v2/_catalog
{"repositories":["hello-world"]}

好啦,自此私有镜像仓库的搭建工作算是完成了。

结语

以上完整讲述了私有镜像仓库的搭建流程,但实际生产环境中可能会涉及高可用、异地数据同步及一致性等问题,这些问题都需要我们去一一解决(这儿暂不做这方面的展开);另外,企业级应用还可以考虑使用Harbor,它会提供一整套的解决方案包括用户管理、操作界面、镜像签名、漏扫、高可用等一系列功能,刚兴趣的同学可参照我的另两篇博客:基于NFS后端存储搭建Harbor和基于CEPH后端存储搭建Harbor。

你可能感兴趣的:(基于证书访问的Docker Registry的搭建)