The goal is to be able take a Docker image on my laptop and push it to the OpenShift Origin image registry (started by oc cluster up
) to do local development. It's not clear if I'm doing something wrong or there's a bug in Docker or OpenShift Origin. For those unfamiliar with OpenShift Origin:
https://github.com/openshift/origin/blob/master/docs/cluster_up_down.md
Any illuminating information would be appreciated. Here's what I've tried so far:
# oc cluster up
Starting OpenShift using openshift/origin:v3.6.0 ...
OpenShift server started.
The server is accessible via web console at:
https://127.0.0.1:8443
You are logged in as:
User: developer
Password: <any value>
To login as administrator:
oc login -u system:admin
# docker container ls | fgrep origin-docker-registry
9de6bb0cdd28 openshift/origin-docker-registry "/bin/sh -c '/usr/..."
# docker inspect 9de6bb0cdd28 | fgrep DOCKER_REGISTRY_PORT
"DOCKER_REGISTRY_PORT_5000_TCP_PROTO=tcp",
"DOCKER_REGISTRY_PORT=tcp://172.30.1.1:5000",
"DOCKER_REGISTRY_PORT_5000_TCP_PORT=5000",
"DOCKER_REGISTRY_PORT_5000_TCP_ADDR=172.30.1.1",
"DOCKER_REGISTRY_PORT_5000_TCP=tcp://172.30.1.1:5000",
# oc whoami -t
qH2cTKtIpr1QB1dMw10ffiDGX1iH_uocrtXaFPyTei8
# docker login -u developer -p qH2cTKtIpr1QB1dMw10ffiDGX1iH_uocrtXaFPyTei8 172.30.1.1:5000
Login Succeeded
# docker tag alpine:latest 172.30.1.1:5000/alpine:latest
# docker push 172.30.1.1:5000/alpine:latest
The push refers to a repository [172.30.1.1:5000/alpine]
5bef08742407: Preparing
error parsing HTTP 400 response body: unexpected end of JSON input: ""
I know that running alpine won't yield anything interesting. The result is the same regardless of what image I try to push. The login seems to actually work. If I remove or alter any part of the token, the login fails. The version of Docker I'm running:
# docker version
Client:
Version: 17.06.0-ce
API version: 1.30
Go version: go1.8.3
Git commit: 02c1d87
Built: Fri Jun 23 21:31:53 2017
OS/Arch: darwin/amd64
Server:
Version: 17.06.0-ce
API version: 1.30 (minimum version 1.12)
Go version: go1.8.3
Git commit: 02c1d87
Built: Fri Jun 23 21:51:55 2017
OS/Arch: linux/amd64
Experimental: true
You can, like Graham pointed out above expose the registry, but it's not required.
In your case when using internal IP, the docker push command docker push 172.30.1.1:5000/alpine:latest
is not correct.
In either case (external route or internal IP) the internal registry, based on the image namespace and name, will create appropriate image stream for you. The name of the image stream and the namespace/project for it, is taken from the push. This means you need to make sure you tag the image with 3 elements:
- docker registry IP and port (external route or internal IP)
- namespace/project your user have access to (in case of
oc cluster up
myproject
is the default one your user have access to)
- finally the image stream name
In your case the docker push should look like this: docker push 172.30.1.1:5000/myproject/alpine:latest
.
There are potentially a couple of issues which can affect when trying to push docker images.
Before we get to that, usually the way to give access to the internal image registry would be to expose it using a route. Since using an IP as you were only applies to oc cluster up
, will show how to use a route instead, that way more generic.
For oc cluster up
, you would run:
oc expose svc/docker-registry -n default --as system:admin
This would create a URL for the internal image registry of:
http://docker-registry-default.127.0.0.1.nip.io/
Next login to the internal image registry using:
docker login -u developer -p `oc whoami -t` http://docker-registry-default.127.0.0.1.nip.io:80/
Make sure you use :80
in the URL when you login. If the internal image registry was exposed using a secure route, would instead use :443
instead of :80
.
Next you want to tag the image, but do be careful what you tag it with, as you want to include the project name in which the image stream should be added.
docker tag alpine:latest docker-registry-default.127.0.0.1.nip.io:80/myproject/alpine
See how I included myproject
in tag, as that is the project I wanted it to end up in.
Details in:
- https://docs.openshift.com/online/dev_guide/managing_images.html#creating-an-image-stream-by-manually-pushing-an-image
Again use :80
for the port in the name. That need the port in the URL when logging in, even though http
given, may be a bug in 3.6.0 or docker command line client. They mention this against OpenShift Online at the moment, which is using 3.6.0.
- https://docs.openshift.com/online/release_notes/online_known_issues.html
Now can push the image:
docker push docker-registry-default.127.0.0.1.nip.io:80/myproject/alpine
Full sequence of commands is:
$ oc expose svc/docker-registry -n default --as system:admin
route "docker-registry" exposed
$ docker login -u developer -p `oc whoami -t` http://docker-registry-default.127.0.0.1.nip.io:80/
Login Succeeded
$ docker tag alpine:latest docker-registry-default.127.0.0.1.nip.io:80/myproject/alpine
$ docker push docker-registry-default.127.0.0.1.nip.io:80/myproject/alpine
The push refers to a repository [docker-registry-default.127.0.0.1.nip.io:80/myproject/alpine]
5bef08742407: Layer already exists
latest: digest: sha256:471fd6e70d36b9c221f76464d0a9ff78392ccee359da351ebfec45138fb40f9b size: 528
$ oc get is
NAME DOCKER REPO TAGS UPDATED
alpine 172.30.1.1:5000/myproject/alpine latest 10 seconds ago