【问题标题】:Pushing a local Docker image to a private repository with a self-signed certificate使用自签名证书将本地 Docker 映像推送到私有存储库
【发布时间】:2019-06-01 20:14:00
【问题描述】:

我正在尝试将映像(例如 foo/bar)从本地 Docker 注册表推送到在 OpenShift 3.11 上运行的注册表(实际上是 Minishift v1.33.0+ba29431)。

注册表位于 192.168.64.3:2376,它需要 HTTPS 连接。它使用自签名证书。

首先我复制新图像的标签:

docker tag foo/bar 192.168.64.3:2376/app/foo/bar

这成功了。然后我尝试推动:

$ docker push 192.168.64.3:2376/app/foo/bar
The push refers to repository [192.168.64.3:2376/app/foo/bar]
Get https://192.168.64.3:2376/v2/: x509: certificate signed by unknown authority

或者,当 Docker 被配置为允许在 192.168.64.0/24 中使用不安全的注册表时,它会与服务器进行 HTTP 通信,而不是禁用证书验证:

$ docker push 192.168.64.3:2376/app/foo/bar
The push refers to repository [192.168.64.3:2376/app/foo/bar]
Get http://192.168.64.3:2376/v2/: EOF

文档说,对于不安全的注册表,它应该“首先,尝试使用 HTTPS。如果 HTTPS 可用但证书无效,请忽略有关证书的错误。如果 HTTPS 不可用,则回退到 HTTP。”所以我不希望看到 EOF 错误。

我也无法告诉 Docker 使用 Minishift 证书,因为它突然失去了与本地 Docker 守护进程通信的能力(它应该使用 Unix 域套接字,而不是 tcp://localhost:2376):

$ export DOCKER_TLS_VERIFY="1"
$ export DOCKER_CERT_PATH="/Users/rzg/.minishift/certs"
$ docker push 192.168.64.3:2376/app/foo/bar
Cannot connect to the Docker daemon at tcp://localhost:2376. Is the docker daemon running?

这是我正在使用的 Docker 版本:

Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:39 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     false

【问题讨论】:

    标签: docker docker-registry openshift-origin


    【解决方案1】:

    根据文档:

     您可以将您的客户端证书和密钥放入 

    ~/.docker/certs.d/<MyRegistry>:<Port>/client.cert

    ~/.docker/certs.d/<MyRegistry>:<Port>/client.key

    https://docs.docker.com/docker-for-mac/faqs/#how-do-i-add-custom-ca-certificates

    或者,您可以配置凭证存储并在那里加载证书,然后在 ~/.docker/config json 中配置存储

    这里的文档:https://docs.docker.com/engine/reference/commandline/login/

    【讨论】:

      【解决方案2】:

      您提到的这两个环境变量是用于docker 命令行工具与 Docker 守护进程对话的。您通常不需要设置它们。 (另请注意,端口 2376 是 Docker API HTTP-over-TLS 的常规端口,尽管没有什么能阻止您将其用于注册表。)

      您正在尝试将 Docker 守护程序配置为与您信任的远程注册表通信。 The dockerd reference says about secure registries:

      安全注册表使用 TLS,其 CA 证书的副本放置在 Docker 主机上的/etc/docker/certs.d/myregistry:5000/ca.crt

      所以在你的设置中,你需要为你的 registry 找到 CA 证书,并将其放入 /etc/docker/certs.d/192.168.64.3:2376/ca.crt,然后重新启动 Docker 守护进程。

      这也在 OpenShift OKD 文档Securing and Exposing the Registry 下进行了描述(请参阅“手动保护注册表”,特别是其步骤 12 和 13)。

      【讨论】:

      【解决方案3】:

      Docker 客户端需要配置为 (i) 接受由 CA 证书签名的私有注册中心的证书,以及 (ii) 提供授权的客户端证书。

      Minishift 将其所有证书文件放在 ~/.minishift/certs 中。这包括 CA 证书 (ca.pem)、客户端证书 (cert.pem) 和客户端私钥 (key.pem)。

      这个示例查询证明了所有三个要素都能成功连接:

      curl \
          --cacert ~/.minishift/certs/ca.pem \
          --cert ~/.minishift/certs/cert.pem \
          --key ~/.minishift/certs/key.pem \
          https://$(minishift ip):2376/v2/info
      

      在macOS上,我们需要关注this part of Docker's documentation并将CA证书安装到钥匙串中:

      security add-trusted-cert -d -r trustRoot -k ~/Library/Keychains/login.keychain ~/.minishift/certs/ca.pem
      

      并且还链接到客户端证书和密钥:

      mkdir -p ~/.docker/certs.d/$(minishift ip):2376/
      ln -s ~/.minishift/certs/cert.pem ~/.docker/certs.d/$(minishift ip):2376/client.cert
      ln -s ~/.minishift/certs/key.pem ~/.docker/certs.d/$(minishift ip):2376/client.key
      

      最后重启 Docker for Mac 然后推送。

      【讨论】:

        猜你喜欢
        • 2016-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多