搭建docker私服仓库(缓存代理仓库)

一、生成https通信需要的证书文件 这一步生成与仓库进行https通信时需要的证书文件,使用的工具是openssl,生成的过程如下:
搭建docker私服仓库(缓存代理仓库)
文章图片

文件 用途
ca.key ca私钥文件
ca.csr 根证书的签发申请文件
ca.crt/ca.cer 证书文件
ca.cnf 约束根证书只用于签发其他证书
site.key 仓库私钥
site.csr 仓库证书签发申请文件
site.crt/site.cer 仓库证书文件
site.cnf 约束仓库只用于服务器认证的配置文件
箭头上的文字代表所使用的openssl子命令,数字+“#”号表示步骤顺序。具体每一步使用的命令在下面有说明。
这个过程docker文档中也有一个例子。不过它使用的Common Name是localhost,而我们的仓库需要给其他机器访问,需要修改为对应的ip地址或者域名。
1、生成CA根证书
  1. 生成ca根证书秘钥文件ca.key
    openssl genrsa -out "ca.key" 4096

  2. 生成根证书签发申请文件ca.csr
    openssl req \ -new -key "ca.key" \ -out "ca.csr" -sha256 \ -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA'

  3. 创建根证书配置文件,命名为ca.cnf
    [root_ca] basicConstraints = critical,CA:TRUE,pathlen:1 keyUsage = critical, nonRepudiation, cRLSign, keyCertSign subjectKeyIdentifier=hash

  4. 签发根证书文件,生成ca.crt
    openssl x509 -req-days 3650-in "ca.csr" \ -signkey "ca.key" -sha256 -out "ca.crt" \ -extfile "ca.cnf" -extensions \ root_ca

2、生成仓库服务器https通信证书
  1. 生成一个私钥site.key
    openssl genrsa -out "site.key" 4096

  2. 生成服务器证书签证申请文件site.csr
    openssl req -new -key "site.key" -out "site.csr" -sha256 \ -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'

    划重点: 命令中的localhost需要替换为将来用于访问仓库的域名,例如:registry.local.com
  3. 创建配置文件site.cnf
    [server] authorityKeyIdentifier=keyid,issuer basicConstraints = critical,CA:FALSE extendedKeyUsage=serverAuth keyUsage = critical, digitalSignature, keyEncipherment subjectAltName = DNS:localhost, IP:127.0.0.1 subjectKeyIdentifier=hash

    划重点: localhost127.0.0.1要换为仓库的访问域名和ip地址,例如:registry.local.com
    192.168.10.100
  4. 用根证书签证服务器证书,生成site.crt证书文件
    openssl x509 -req -days 750 -in "site.csr" -sha256 \ -CA "ca.crt" -CAkey "ca.key"-CAcreateserial \ -out "site.crt" -extfile "site.cnf" -extensions server

二、在运行仓库的机器上运行官方仓库镜像library/registry
  1. 【搭建docker私服仓库(缓存代理仓库)】首先下载该镜像
    docker pull registry:2.6.2

  2. 运行
    这里有三种方式:
    • container(docker run)
    • service(docker service create)
    • stack(docker stack deploy)
    三种方式都可以,这里以stack为例,其他两种根据配置做对应参数填充即可。具体参考官方CLI对应命令的文档。
    但是运行之前,要先知道一个重要的文件,
    1. /etc/docker/registry/config.yml
      这是仓库程序的总配置文件,是一个yml格式的文本文件,可以配置的项很多。具体可以配置的项以及每一项的说明可以在官方文档找到。
      而这里我们需要配置的项有:
      # config.yml version: 0.1 storage: filesystem: rootdirectory: /var/lib/registry #镜像文件存放目录,这是默认值,不配置也可以,需要的可以自己修改 proxy: remoteurl: 上游仓库访问地址# 所代理的仓库,也就是本地仓库的上游仓库 http: addr: 0.0.0.0:443# 仓库绑定的ip地址与端口号 tls: certificate: /certs/site.crt# 仓库证书,就是上面我们用根证书签证过的服务器证书 key: /certs/site.key# 仓库私钥,就是用于生成证书的私钥(注意不是ca的私钥)

      划重点: 注意这个配置文件中所有用到的文件和目录都是从容器内部访问的,所以连同这个配置文件本身都需要挂载进容器。
    2. 不过这个文件并不是必须的,在配置文件中的每一项,都可以通过以一定规则命名的环境变量传递给容器来配置,这个规则是,以REGISTRY开头,之后按照配置文件的树形结构,每一级通过下划线_连接,例如仓库目录的环境变量是:
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/somewhere

      如果有数组值,则后跟下划线和索引如_0_1……
    3. 现在以stack为例,写一个compose文件来启动仓库。
      # registry-compose.yml version: '3.3' services: registry: image: registry:2.6.2 deploy: replicas: 1 ports: - 443:443 volumes: - /your/path/to/config.yml:/etc/docker/registry/config.yml - /your/path/to/repository:/var/lib/registry - /your/path/to/certs:/certs

三、配置客户端docker 现在要去访问私有仓库还需要几步
1、配置使用你的私有仓库为镜像,假设ip地址是192.168.10.100,则访问地址为
https://192.168.10.100

或者域名registry.local.com
https://registry.local.com

2、配置ca根证书
要把最开始用于签证服务器ca根证书放置到/etc/docker/certs.d/ip地址或domain/下,例如:
/etc/docker/certs.d/192.168.10.100/

划重点: 由于我们使用https的默认端口号443去访问,这里不需要添加端口号
192.168.10.100是一个文件夹,下同。
如果配置仓库镜像地址时,使用了域名,这里也要对应地用域名,总而言之,你用什么访问就配置成什么,目录没有的话自己创建
/etc/docker/certs.d/registry.local.com/

当然,如果你把443映射为其他端口,也需要在文件夹名称添加端口号
/etc/docker/certs.d/registry.local.com:5000/

如果你配错了,会报这个错误
Error response from daemon: Get https://192.168.10.100/v2/: x509: certificate signed by unknown authority

四、错误
  • 生成证书时site.cnf文件写错,要指定为你用于访问的域名和ip地址
Error response from daemon: Get https://192.168.10.100/v2/: x509: certificate is valid for 127.0.0.1, not 192.168.10.100

  • 生成证书时没有传cnf文件
Error response from daemon: Get https://192.168.10.100/v2/: x509: cannot validate certificate for 192.168.10.100 because it doesn't contain any IP SANs

    推荐阅读