I'm trying to push an image, say foo/bar, from my local Docker registry to a registry running on OpenShift 3.11 (actually Minishift v1.33.0+ba29431).

The registry is at 192.168.64.3:2376 and it expects HTTPS connections. It uses a self-signed certificate.

First I copy the tag for the new image:

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

This succeeds. Then I try pushing:

$ 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

or, when Docker is configured to allow use of unsafe registries in 192.168.64.0/24, it talks HTTP to the server instead of disabling certificate verification:

$ 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

The documentation says that for an unsafe registry, it should "First, try using HTTPS. If HTTPS is available but the certificate is invalid, ignore the error about the certificate. If HTTPS is not available, fall back to HTTP." So I would not expect to see an EOF error.

I also cannot try to tell Docker to use the Minishift certs, because it suddenly loses the ability to talk to the local Docker daemon (it should use a Unix domain socket, not 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?

This is the version of Docker I'm using:

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

3 Answers

1
David Maze On

Those two environment variables you mention are for the docker command-line tool to talk to the Docker daemon. You don't normally need to set them. (Also note that port 2376 is the conventional port for the Docker API HTTP-over-TLS, though nothing stops you from using it for a registry instead.)

You're trying to configure the Docker daemon to talk to a remote registry that you trust. The dockerd reference says about secure registries:

A secure registry uses TLS and a copy of its CA certificate is placed on the Docker host at /etc/docker/certs.d/myregistry:5000/ca.crt.

So in your setup, you need to find the CA certificate for your registry, and put it in /etc/docker/certs.d/192.168.64.3:2376/ca.crt, and then restart the Docker daemon.

This is also described in the OpenShift OKD documentation under Securing and Exposing the Registry (see "Manually Securing the Registry", and in particular its steps 12 and 13).

1
Shirine On

As per documentation:

 You can put your client certificates and key in 

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

and

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

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

Alternatively you configure a credential store and load the certs there and then configure the store in ~/.docker/config json

Documentation here : https://docs.docker.com/engine/reference/commandline/login/

0
helpmeh On

The Docker client needs to be configured to (i) accept the private registry's certificate, which is signed by the CA certificate, and (ii) present an authorized client certificate.

Minishift places all of its certificate files in ~/.minishift/certs. This includes a CA certificate (ca.pem), a client certificate (cert.pem), and a client private key (key.pem).

This example query proves that all three ingredients lead to a successful connection:

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

On macOS, we need to follow this part of Docker's documentation and install the CA certificate to the keychain:

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

And also make links to the client certificate and key:

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

Finally, restart Docker for Mac and then push.