使用 openssl 签发证书

签发 CA

  • 如果已有 CA ,可略过

    • Ubuntu
    1
    2
    3
    
    $ openssl genrsa -out ca.key 4096
    # go 1.15 以上版本被识别的 ssl 证书需配置 SANs,申请证书时需通过 addext 指定
    $ openssl req -x509 -new -nodes -sha512 -days 36500  -addext "subjectAltName = DNS:*" -key ca.key  -out ca.crt -subj "/C=CN/O=decent/CN=*"
    
    • Centos7
    1
    2
    3
    
    $ openssl genrsa -out ca.key 4096
    # Centos7 使用低版本 openssl,不支持 -addext 参数,需使用其他方式配置 subjectAltName
    $ ALTNAME="DNS:*" openssl req -x509 -new -nodes -sha512 -days 36500 -key ca.key  -out ca.crt -subj "/C=CN/O=decent/CN=*"
    
  • PS:申请证书时需通过 -addext 设置 SANs,否则 docker 从此仓库拉取镜像时会报错

1
2
$ d pull XXX.registry.local.XXX.XXX.cn:5001/xiang/sample-http-server:1.0
Error response from daemon: Get "https://XXX.registry.local.XXX.XXX.cn:5001/v2/": x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0

签发 registry 使用的证书

  • 生成证书申请
1
2
3
4
5
6
7
# DOMAIN 变量配置问 registry 将来要用的域名
$ DOMAIN=XXX.registry.local.XXX.XXX.cn
$ mkdir registry_certs
# 生成证书申请(Ubuntu)
$ openssl req -newkey rsa:4096 -nodes -sha256 -subj "/CN=${DOMAIN}" -addext "subjectAltName = DNS:${DOMAIN}" -keyout registry_certs/${DOMAIN}.key -out registry_certs/${DOMAIN}.csr
# 生成证书申请(Centos7)
$ ALTNAME="DNS:${DOMAIN}" openssl req -newkey rsa:4096 -nodes -sha256 -subj "/CN=${DOMAIN}" -keyout registry_certs/${DOMAIN}.key -out registry_certs/${DOMAIN}.csr
  • 签发证书

    • 通过一条命令签发证书
    1
    2
    
    # 签发证书
    $ openssl x509 -req -days 35600 -extfile <(printf "subjectAltName=DNS:${DOMAIN}")  -in registry_certs/${DOMAIN}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out registry_certs/${DOMAIN}.crt 
    
    • Ubuntu 20+ openssl 不支持使用 -extfile < print 的方式申请证书,需通过写入文件并指定文件的方式签发证书
    1
    2
    
    $ echo "subjectAltName=DNS:$DOMAIN" > altsubj.ext
    $ openssl x509 -req -days 35600 -extfile altsubj.ext  -in registry_certs/${DOMAIN}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out registry_certs/${DOMAIN}.crt
    
  • 验证证书是否支持 SANs

1
2
3
$ openssl x509 -in XXX.registry.local.XXX.XXX.cn.crt -noout -text |grep "Subject Alternative Name" -A 1
            X509v3 Subject Alternative Name:
                DNS:XXX.registry.local.XXX.XXX.cn

带证书启动 registry

  • 参数说明:
    • -v `pwd`/data:/var/lib/registry:指定 registry 数据持久化路径
    • -v `pwd`/certs:/certs:将宿主机的证书文件 mount 进 container 中
    • -e REGISTRY_HTTP_ADDR=0.0.0.0:5001:变更 registry 监听的端口
    • -p 5001:5001:将 registry 监听的端口映射至宿主机
    • -e REGISTRY_HTTP_TLS_CERTIFICATE/REGISTRY_HTTP_TLS_KEY:指定 registry 启动时监听证书文件的路径,即宿主机的 certs 目录 mount 进 container 后的路径
1
2
3
4
5
6
7
8
$ docker run -d -p 5001:5001 --restart=always --name registry \
  -v /etc/localtime:/etc/localtime
  -v `pwd`/data:/var/lib/registry \
  -v `pwd`/certs:/certs \
  -e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/XXX.registry.local.XXX.XXX.cn.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/XXX.registry.local.XXX.XXX.cn.key \
  --name decent-registry-local  registry:2.7.1

docker 客户端配置信任 ca

  • 由于 registry 证书是自签的,所以使用此仓库的 docker 客户端需进行配置以信任 ca
1
2
$ mkdir -p /etc/docker/certs.d/XXX.registry.local.XXX.XXX.cn:5001
$ scp XXX@xxx.xxx.xxx.xxx:/usr/local/platform/cafile/ca.crt /etc/docker/certs.d/XXX.registry.local.XXX.XXX.cn:5001/
  • 重启 docker
1
2
$ sudo systemctl daemon-reload 
$ sudo systemctl restart docker

containerd 客户端配置信任 ca

  • 由于 registry 证书是自签的,所以使用此仓库的 containerd 客户端需进行配置以信任 ca

    • 更改 containerd ca 配置
    1
    2
    3
    4
    5
    6
    7
    
    $ vim /etc/containerd/config.toml
    [plugins]
      [plugins."io.containerd.grpc.v1.cri"]
        ############# 新增 ######################
        [plugins."io.containerd.grpc.v1.cri".registry.configs."XXX.registry.local.XXX.XXX.cn:5001".tls]
          ca_file = "/etc/containerd/certs.d/ca.crt"
        ############# end #######################
    
    • 客户端指定路径下存储 ca
    1
    2
    
    $ mkdir -p /etc/containerd/certs.d/
    $ scp XXX@xxx.xxx.xxx.xxx:/usr/local/platform/cafile/ca.crt /etc/containerd/certs.d/
    
    • 重启 containerd
    1
    
    $ sudo systemctl daemon-reload && sudo systemctl restart containerd
    

podman 客户端配置信任 ca

  • 配置方式与 docker 完全一致
1
2
$ mkdir -p /etc/docker/certs.d/XXX.registry.local.XXX.XXX.cn:5001
$ scp XXX@xxx.xxx.xxx.xxx:/usr/local/platform/cafile/ca.crt /etc/docker/certs.d/XXX.registry.local.XXX.XXX.cn:5001/

使用

  • 上传/拉取镜像
1
2
3
$ docker tag xxx/kubia:v20210110 XXX.registry.local.XXX.XXX.cn:5001/xxx/kubia:v20210110
$ docker push XXX.registry.local.XXX.XXX.cn:5001/xxx/kubia:v20210110
$ docker pull XXX.registry.local.XXX.XXX.cn:5001/xxx/kubia:v20210110
  • 查看镜像仓库
    • curl 使用 -k 不校验证书是否可信
1
2
3
4
5
6
# 查看镜像列表
$ curl https://XXX.registry.local.XXX.XXX.cn:5001/v2/_catalog -k
{"repositories":["xxx/kubia"]}
# 查看镜像版本
$ curl https://XXX.registry.local.XXX.XXX.cn:5001/v2/xxx/kubia/tags/list -k
{"name":"xxx/kubia","tags":["v20210110"]}

参考