问题导读
1、通常在哪里使用 HTTPS?Why呢?
2、如何远程管理 Docker 主机?
3、在配置过程中出错,可以使用哪些方法解决?
在哪里使用 HTTPS?Why?
Docker 启动监听端口后,使用的是 http,可以远程来管理 Docker 主机。
这样的场景存在弊端,API 层面是没有提供用户验证、Token 之类身份验证功能,任何人都可以通过地址加端口来控制 Docker 主机,为了避免这样的情况发生,Docker 官方也支持 https 方式,不过需要我们自己来生成证书。
通过 OpenSSL 命令来生成 CA 证书、服务器私钥、客户端证书、签名,openssl 命令比较复杂,我用脚本直接生成:
- # cat certgen.sh
- set -ex
-
- [ -e certs ] || mkdir certs
- cd certs
- echo "Creating ca keys..."
- echo 01 > ca.srl
- openssl genrsa -des3 -out ca-key.pem
- openssl rsa -in ca-key.pem -out ca-key.pem
- openssl req -subj "/CN=$(hostname -f)/" -new -x509 -days 365 -key ca-key.pem -out ca.pem
-
- echo "Creating server keys..."
- openssl genrsa -des3 -out server-key.pem
- openssl rsa -in server-key.pem -out server-key.pem
- openssl req -subj "/CN=$(hostname -f)/" -new -key server-key.pem -out server.csr
- openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -out server-cert.pem
-
- echo "Creating client keys..."
- openssl genrsa -des3 -out key.pem
- openssl rsa -in key.pem -out key.pem
- openssl req -subj '/CN=*/' -new -key key.pem -out client.csr
- echo extendedKeyUsage = clientAuth > extfile.cnf
- openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem -out cert.pem -extfile extfile.cnf
复制代码
需要注意,在执行脚本之前,确保你的主机名符合 FQDN 并能正常解析,不推荐修改脚本内容 $(hostname -f) 为 IP 地址,无需修改脚本,在脚本执行过程中会反复需要输入密码,统一输入一个密码就 ok:
复制代码
执行完后,会在当前目录下生成一个 certs 目录,里面有生成的所有的证书文件。
为了避免混淆,现在拷贝 CA 和服务器私钥到其它目录:
- mkdir -p /etc/docker/certs
- cd certs/
- cp ca.pem server-cert.pem server-key.pem /etc/docker/certs/
复制代码
服务器私钥有了,我们也知道在哪里,现在只需要让 Docker 知道:
- vim /etc/default/docker
- DOCKER_OPTS='-H unix:///var/run/docker.sock -H docker01.thstack.com:6732 --tlsverify --tlscacert=/etc/docker/certs/ca.pem --tlscert=/etc/docker/certs/server-cert.pem --tlskey=/etc/docker/certs/server-key.pem'
复制代码
重启 docker 服务:
复制代码
添加 DOCKER_HOST 环境变量,地址为 Docker 主机的主机名,同样如果设置 IP 地址会有问题:
- # vim /etc/profile
- export DOCKER_HOST=tcp://docker01.thstack.com:6732
-
- # source /etc/profile
复制代码
现在 Docker 已经开启了 https 认证,在命令行里敲 docker 命令会报错,需要在每个 docker 命令加 –tlsverify 参数,docker 命令作为一个客户端工具来操作 Docker 主机同样依赖客户端证书:
- root@docker01:~/certs# docker info
- 2014/09/14 16:19:26 Get http://docker01.thstack.com:6732/v1.14/info: malformed HTTP response "\x15\x03\x01\x00\x02\x02"
-
- root@docker01:~# docker --tlsverify images
- 2014/09/14 16:25:53 Couldn't read ca cert /root/.docker/ca.pem: open /root/.docker/ca.pem: no such file or directory
复制代码
从 docker –tlsverify images 结果输出中了解到,加了 –tlsverify 参数后,就会默认去 ~/.docker 文件中找客户端证书,现在为 docker 客户端命令添加证书:
- mkdir ~/.docker
- cd certs/
- cp ca.pem cert.pem key.pem ~/.docker
复制代码
再次尝试执行命令:
- root@docker01:~# docker ps
- 2014/09/14 16:28:42 Get http://docker01.thstack.com:6732/v1.14/containers/json: malformed HTTP response "\x15\x03\x01\x00\x02\x02"
-
- root@docker01:~# docker --tlsverify images
- REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
- ubuntu 14.04.1 826544226fdc 9 days ago 194.2 MB
- ubuntu 14.04 826544226fdc 9 days ago 194.2 MB
- ubuntu trusty 826544226fdc 9 days ago 194.2 MB
- ubuntu latest 826544226fdc 9 days ago 194.2 MB
- ubuntu 14.10 245ce11c1f25 9 days ago 202.5 MB
- ubuntu utopic 245ce11c1f25 9 days ago 202.5 MB
- ubuntu precise c17f3f519388 9 days ago 106.7 MB
- ubuntu 12.04.5 c17f3f519388 9 days ago 106.7 MB
- ubuntu 12.04 c17f3f519388 9 days ago 106.7 MB
- ubuntu 12.10 c5881f11ded9 12 weeks ago 172.2 MB
- ubuntu quantal c5881f11ded9 12 weeks ago 172.2 MB
- ubuntu 13.04 463ff6be4238 12 weeks ago 169.4 MB
- ubuntu raring 463ff6be4238 12 weeks ago 169.4 MB
- ubuntu 13.10 195eb90b5349 12 weeks ago 184.7 MB
- ubuntu saucy 195eb90b5349 12 weeks ago 184.7 MB
- ubuntu lucid 3db9c44f4520 4 months ago 183 MB
- ubuntu 10.04 3db9c44f4520 4 months ago 183 MB
复制代码
只要开启 https 认证后,docker 命令就必须加 –tlsverify 参数。
上面所有的操作都是在 Docker 主机上操作,找另外一台机器来验证 https 是否生效:
- root@ubuntu:~# curl -v -s https://docker01.thstack.com:6732/info
- * About to connect() to docker01.thstack.com port 6732 (#0)
- * Trying 192.168.3.23... connected
- * successfully set certificate verify locations:
- * CAfile: none
- CApath: /etc/ssl/certs
- * SSLv3, TLS handshake, Client hello (1):
- * SSLv3, TLS handshake, Server hello (2):
- * SSLv3, TLS handshake, CERT (11):
- * SSLv3, TLS alert, Server hello (2):
- * SSL certificate problem, verify that the CA cert is OK. Details:
- error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
- * Closing connection #0
复制代码
上面提示,证书验证失败,在 Docker 主机上 scp 客户端证书到这台机器上:
- root@docker01:~# cd certs/
- root@docker01:~/certs# scp ca.pem cert.pem key.pem root@ubuntu:/tmp
复制代码
指明证书位置来验证,可以看到验证过程和结果:
- root@ubuntu:~# curl -v -s -k --key /tmp/key.pem --cert /tmp/cert.pem https://docker01.thstack.com:6732/info
-
- * About to connect() to docker01.thstack.com port 6732 (#0)
- * Trying 192.168.3.23... connected
- * successfully set certificate verify locations:
- * CAfile: none
- CApath: /etc/ssl/certs
- * SSLv3, TLS handshake, Client hello (1):
- * SSLv3, TLS handshake, Server hello (2):
- * SSLv3, TLS handshake, CERT (11):
- * SSLv3, TLS handshake, Server key exchange (12):
- * SSLv3, TLS handshake, Request CERT (13):
- * SSLv3, TLS handshake, Server finished (14):
- * SSLv3, TLS handshake, CERT (11):
- * SSLv3, TLS handshake, Client key exchange (16):
- * SSLv3, TLS handshake, CERT verify (15):
- * SSLv3, TLS change cipher, Client hello (1):
- * SSLv3, TLS handshake, Finished (20):
- * SSLv3, TLS change cipher, Client hello (1):
- * SSLv3, TLS handshake, Finished (20):
- * SSL connection using ECDHE-RSA-AES256-SHA
- * Server certificate:
- * subject: CN=docker01.thstack.com
- * start date: 2014-09-14 03:27:16 GMT
- * expire date: 2015-09-14 03:27:16 GMT
- * common name: docker01.thstack.com (matched)
- * issuer: CN=docker01.thstack.com
- * SSL certificate verify result: self signed certificate (18), continuing anyway.
- > GET /info HTTP/1.1
- > User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
- > Host: docker01.thstack.com:6732
- > Accept: */*
- >
- < HTTP/1.1 200 OK
- < Content-Type: application/json
- < Job-Name: info
- < Date: Sun, 14 Sep 2014 08:43:26 GMT
- < Content-Length: 417
- <
- {"Containers":1,"Debug":0,"Driver":"aufs","DriverStatus":[["Root Dir","/var/lib/docker/aufs"],["Dirs","36"]],"ExecutionDriver":"native-0.2","IPv4Forwarding":1,"Images":34,"IndexServerAddress":"https://index.docker.io/v1/","InitPath":"/usr/bin/docker","InitSha1":"","KernelVersion":"3.13.0-24-generic","MemoryLimit":1,"NEventsListener":0,"NFd":11,"NGoroutines":11,"OperatingSystem":"Ubuntu 14.04.1 LTS","SwapLimit":0}
- * Connection #0 to host docker01.thstack.com left intact
- * Closing connection #0
- * SSLv3, TLS alert, Client hello (1):
复制代码
也可以在其它机器上安装 lxc-docker,来用 docker 命令远程管理 Docker 主机,同样设置环境变量,添加证书。
如果在配置过程中出错,查看 /var/log/upstart/docker.log 日志,或重新生成证书。
参考资料:
https://docs.docker.com/articles/https/
http://sheerun.net/2014/05/17/remote-access-to-docker-with-tls/
http://blog.jameskyle.org/2014/04/coreos-docker-remote-api-tls/
|