Docker on Windows Hyper-V
Provision of docker host
I'm gonna use Ubuntu 15.04, at moment there is troubles with DOCKER_OPTS
hope will be fixed later on.
On a fresh install all you need to do:
###Install docker itself
wget -qO- https://get.docker.com/ | sh
sudo usermod -aG docker $USER # relogin required
docker run hello-world
###Certificates
https://docs.docker.com/articles/https/
How it works: Both client and server have its own cert and key files, they all are signed with same CA. While connecting both client and server verify each other certificates agains CA file they have. If all OK communication begins.
First of all we need our CA
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem
Server certificates
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
echo subjectAltName = IP:192.168.5.123,IP:127.0.0.1 > extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
rm server.csr extfile.cnf ca.srl
Here is tricky part, you need to provide your server IP here to be able to connect to it by IP address rather than by DNS.
But in my case its my local lab so I prefer doing it without IP addresses like so:
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
rm server.csr ca.srl
Not that in this variant I am no longer defining IP addresses so connections will be available only by host names which in our case everywhere set to start - so connection will be available from everywhere, but from now on you must deal with hosts file on your client system or configure DNS.
Client certificates
openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
rm client.csr extfile.cnf ca.srl
Privileges
chmod -v 0400 ca-key.pem key.pem server-key.pem
chmod -v 0444 ca.pem server-cert.pem cert.pem
What do we have now is:
server-key.pem
,server-cert.pem
andca.pem
- will be used by docker serverkey.pem
,cert.pem
andca.pem
- will be used by client
Notice that both client and server do need to have same ca.pem
to be able to verify certificates.
###DOCKER_OPTS
By default docker listens to socket, what wee need is to modify docker startup parameters so it will start listening network.
sudo sed -i "s|#DOCKER_OPTS=\"--dns 8.8.8.8 --dns 8.8.4.4\"|DOCKER_OPTS=\"--tlsverify --tlscacert=$PWD/ca.pem --tlscert=$PWD/server-cert.pem --tlskey=$PWD/server-key.pem -H=0.0.0.0:2376\"|" /etc/default/docker
Be sure to set appropriate file names and paths, do not forget to remove -i
parameter to check what will happen.
Unfortunatelly at this moment things will not happen, because of moving to systemd file we were edit is not used at all, hope it will be fixed soon, but for now we need do few more things.
sudo mkdir -p /etc/systemd/system/docker.service.d
cat << EOF | sudo tee -a /etc/systemd/system/docker.service.d/ubuntu.conf
[Service]
EnvironmentFile=/etc/default/docker
ExecStart=
ExecStart=/usr/bin/docker -d -H fd:// \$DOCKER_OPTS
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl status docker
netstat -ntulp | grep 2376
Windows client
Windows client may be downloaded here: https://get.docker.com/builds/Windows/x86_64/docker-latest.exe
To copy certificate files use something like this:
scp [email protected]:"/home/alexandr/ca.pem /home/alexandr/cert.pem /home/alexandr/key.pem" .
To verify things are working:
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=hvd:2376 version
Note that we are connection to hvd
machine rather that its IP.
To make things easier you may set environment variables:
set DOCKER_TLS_VERIFY=1
set DOCKER_HOST=tcp://hvd:2376
set DOCKER_CERT_PATH=C:\Users\Alexandr\Desktop
And now you should be able to run docker commands from your windows client against ubuntu vm in your hyper-v like so:
docker info | findstr "Operating System"
Operating System: Ubuntu 15.04
Docker Machine
Please take a note that there is docker-machine available for Windows which supports hyper-v out of the box. All what have beed done here may be done in few commands like:
docker-machine create -d hyper-v dev
docker-machine env dev
set DOCKER_TLS_VERIFY=1
set DOCKER_HOST=tcp://192.168.5.156:2376
set DOCKER_CERT_PATH=C:\Users\Alexandr\.docker\machine\machines\dev
set DOCKER_MACHINE_NAME=dev
docker run busybox echo hello world
Docker machine will create docker host vm in hyper-v, will deal with certificates and so on. Even more, when you will be ready you can use docker machine to provision docker host in cloud providers without doing anything by hand.