搭建安全的私有Docker镜像仓库

网上有些文章写这个,但是要么告诉你直接加insecure registries,要么直接用CA作为服务的证书了,可以说很粗暴了,有些直接必须要求你设置CN,不能用IP地址。这些距离一个理想的纯私有环境的镜像仓库部署有不小差距,因此有了此文。

1. 期望

  1. 不需要通过设置insecure_registies的方式,在客户端随意pull/push一个私有镜像仓库源中的镜像
  2. ca证书不要直接用于registry服务的认证
  3. 不要用域名,用IP设置服务证书

2. 环境说明

  • Host1: 172.31.40.155 (镜像仓库地址)
  • Host2: 172.31.22.100 (验证客户端)
  • OS: Ubuntu
  • Docker: 18.03.1-ce
  • Registry:2

3. 快速部署一个镜像仓库

地址:registry:2
部署镜像仓库,在172.31.40.155上执行

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

172.31.40.155测试下:

docker tag ubuntu localhost:5000/ubuntu
docker push localhost:5000/ubuntu

一切很ok,但是当你在172.31.22.100上docker pull 172.31.40.155:5000/ubuntu 时,会告诉你:

Get https://172.31.40.155:5000/v1/_ping: http: server gave HTTP response to HTTPS client

这时候你可以选择用不安全的方式fix掉,具体方式就是:
/etc/docker/目录下,创建daemon.json文件。在文件中写入:

{
    "insecure-registries": [
        "172.31.40.155:5000"
    ]
}

重启docker,服务正常使用。
但是这种方案,并不被鼓励,而且最头疼的是:

  1. 以后每一个节点都要添加配置记录,然后重启Docker
  2. 每增加一个registry都要改所有的Node中的配置,然后全部Node重启Docker

嗯,无法忍受。

4. 使用HTTPS

  1. 生成CA根证书:

    • 生成CA私钥(.key)

      openssl genrsa -out ca.key 2048
    • 生成CA证书请求(.csr)

      openssl req -new -key ca.key -out ca.csr
    • 自签名得到根证书(.crt)

      openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
  2. 分发CA根证书到全部节点:

    scp ca.crt root@ip-172-31-22-100:/usr/local/share/ca-certificates/ca.crt
  3. 各个节点信任CA证书,各个节点上执行:

    update-ca-certificates
  4. 产生镜像服务使用的服务证书,以下命令在registry节点上执行

    • 生成服务私钥(.key)

      openssl genrsa -out /cert/service.key 4096
    • 生成证书请求(.csr)

      openssl req -subj "/" -sha256 -new -key /cert/service.key -out /cert/service.csr
    • 准备extfile文件

      cat > /cert/extfile.cnf <<EOF
      > subjectAltName = IP:172.31.40.155
      > EOF
    • 用CA根证书签名得到证书(.crt)

      openssl x509 -req -days 36500 -sha256 -in /cert/service.csr -CA /usr/local/share/ca-certificates/ca.crt -CAkey ca.key  -CAcreateserial -out service.crt -extfile /cert/extfile.cnf
  5. 重新部署registry服务(先把之前的registry容器杀掉,清掉daemon.json):

    docker run -d -p 5000:5000 --privileged=true -v ~/certs:/root/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/root/certs/service.crt -e REGISTRY_HTTP_TLS_KEY=/root/certs/service.key registry:2
  6. 测试:
    所有client节点均可以pull/push 该registry的镜像。


All,希望对您有帮助。

猜你喜欢

转载自blog.csdn.net/xialingming/article/details/81291543