I’ve been working with Docker lately (for WebSphere Liberty).
More I probably will write about that later, but this brief post is about pushing a Docker image to a private local registry that I can only reach through a 2-hop SSH tunnel.
It turns out unlike “native” Docker on Linux, the Docker for Windows daemon that push/pull uses isn’t using the same networking that the containers are. Looks like I have to get to the underlying VM, but can’t do this directly:
On Windows, Docker runs in a VM called MobyLinuxVM, but you cannot login to that VM via Hyper-V Manager. We aren’t technically going to SSH into the VM, we’ll create a container that has full root access and then access the file system from there.
I eventually was able to successfully follow the steps detailed in that post above, except as I need to then to ssh from the resulting container, I need Alpine + SSH. I also wanted to make my own image for the container+Docker client. Both so I knew exactly what was in it, and to see if I could get an even smaller image than that author’s Ubuntu one.
So here are the two images I created for the purpose, with their source Dockerfiles on GitHub:
Commands to perform the process:
From Windows CMD.EXE (Might have to be as Administrator):
C:\>docker run --privileged -it -v /var/run/docker.sock:/var/run/docker.sock dbreaux/alpine-with-docker-client
From that container:
root@931e191d5755:/# docker run --net=host --ipc=host --uts=host --pid=host -it --security-opt=seccomp=unconfined --privileged --rm -v /:/host dbreaux/alpine-with-ssh /bin/sh
Then run whatever SSH commands you need. I also created a private Docker image of the above alpine-with-ssh where I copied my private key file, known_hosts file for the two systems I’m going to tunnel through, and a shell script to establish my two-hop tunnel.
For quick reference, my ssh command (which is in my custom shell script) looks like:
# ssh -o GatewayPorts=yes -o ServerAliveInterval=60 -o ProxyCommand="ssh -W %h:%p myuser@my-proxy-server" -L80:my-registry-server:80 -L443:my-registry-server:443 myuser@server-on-same-network-as-my-registry-server
Then I can, back on my Windows workstation/host:
docker push my-registry-server/image-name:image-tag
Contents of a Docker Image
Bonus tip: useful site to inspect the contents of a Docker Hub image: https://microbadger.com/
e.g. for my Alpine-with-Docker-client: https://microbadger.com/images/dbreaux/alpine-with-docker-client