linux中让 Docker 使用 HTTPS的教程
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化,下文来看一个 Docker 使用 HTTPS的教程.
Docker 启动监听端口后,使用的是 http,可以远程来管理 Docker 主机.
这样的场景存在弊端,API 层面是没有提供用户验证、Token 之类身份验证功能,任何人都可以通过地址加端口来控制 Docker 主机,为了避免这样的情况发生,Docker 官方也支持 https 方式,不过需要我们自己来生成证书.
通过 OpenSSL 命令来生成 CA 证书、服务器私钥、客户端证书、签名,openssl 命令比较复杂,我用脚本直接生成:
- #catcertgen.sh
- set-ex
- [-ecerts]||mkdircerts
- cdcerts
- echo"Creatingcakeys..."
- echo01>ca.srl
- opensslgenrsa-des3-outca-key.pem
- opensslrsa-inca-key.pem-outca-key.pem
- opensslreq-subj"/CN=$(hostname-f)/"-new-x509-days365-keyca-key.pem-outca.pem
- echo"Creatingserverkeys..."
- opensslgenrsa-des3-outserver-key.pem
- opensslrsa-inserver-key.pem-outserver-key.pem
- opensslreq-subj"/CN=$(hostname-f)/"-new-keyserver-key.pem-outserver.csr
- opensslx509-req-days365-inserver.csr-CAca.pem-CAkeyca-key.pem-outserver-cert.pem
- echo"Creatingclientkeys..."
- opensslgenrsa-des3-outkey.pem
- opensslrsa-inkey.pem-outkey.pem
- opensslreq-subj'/CN=*/'-new-keykey.pem-outclient.csr
- echoextendedKeyUsage=clientAuth>extfile.cnf
- opensslx509-req-days365-inclient.csr-CAca.pem-CAkeyca-key.pem-outcert.pem-extfileextfile.cnf//phpfensi.com
需要注意,在执行脚本之前,确保你的主机名符合 FQDN 并能正常解析,不推荐修改脚本内容 $(hostname -f) 为 IP 地址,无需修改脚本,在脚本执行过程中会反复需要输入密码,统一输入一个密码就 ok:
sh certgen.sh
执行完后,会在当前目录下生成一个 certs 目录,里面有生成的所有的证书文件,为了避免混淆,现在拷贝 CA 和服务器私钥到其它目录:
- mkdir-p/etc/docker/certs
- cdcerts/
- cpca.pemserver-cert.pemserver-key.pem/etc/docker/certs/
服务器私钥有了,我们也知道在哪里,现在只需要让 Docker 知道:
- vim/etc/default/docker
- DOCKER_OPTS='-Hunix:///var/run/docker.sock-Hdocker01.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 服务:service docker restart,添加 DOCKER_HOST 环境变量,地址为 Docker 主机的主机名,同样如果设置 IP 地址会有问题:
- #vim/etc/profile
- exportDOCKER_HOST=tcp://docker01.thstack.com:6732
- #source/etc/profile
现在 Docker 已经开启了 https 认证,在命令行里敲 docker 命令会报错,需要在每个 docker 命令加 –tlsverify 参数,docker 命令作为一个客户端工具来操作 Docker 主机同样依赖客户端证书:
- root@docker01:~/certs#dockerinfo
- 2014/09/1416:19:26Gethttp://docker01.thstack.com:6732/v1.14/info:malformedHTTPresponse"x15x03x01x00x02x02"
- root@docker01:~#docker--tlsverifyimages
- 2014/09/1416:25:53Couldn'treadcacert/root/.docker/ca.pem:open/root/.docker/ca.pem:nosuchfileordirectory//phpfensi.com
从 docker –tlsverify images 结果输出中了解到,加了 –tlsverify 参数后,就会默认去 ~/.docker 文件中找客户端证书,现在为 docker 客户端命令添加证书:
- mkdir~/.docker
- cdcerts/
- cpca.pemcert.pemkey.pem~/.docker
再次尝试执行命令:
- root@docker01:~#dockerps
- 2014/09/1416:28:42Gethttp://docker01.thstack.com:6732/v1.14/containers/json:malformedHTTPresponse"x15x03x01x00x02x02"
- root@docker01:~#docker--tlsverifyimages
- REPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZE
- ubuntu14.04.1826544226fdc9daysago194.2MB
- ubuntu14.04826544226fdc9daysago194.2MB
- ubuntutrusty826544226fdc9daysago194.2MB
- ubuntulatest826544226fdc9daysago194.2MB
- ubuntu14.10245ce11c1f259daysago202.5MB
- ubuntuutopic245ce11c1f259daysago202.5MB
- ubuntuprecisec17f3f5193889daysago106.7MB
- ubuntu12.04.5c17f3f5193889daysago106.7MB
- ubuntu12.04c17f3f5193889daysago106.7MB
- ubuntu12.10c5881f11ded912weeksago172.2MB
- ubuntuquantalc5881f11ded912weeksago172.2MB
- ubuntu13.04463ff6be423812weeksago169.4MB
- ubunturaring463ff6be423812weeksago169.4MB
- ubuntu13.10195eb90b534912weeksago184.7MB
- ubuntusaucy195eb90b534912weeksago184.7MB
- ubuntulucid3db9c44f45204monthsago183MB
- ubuntu10.043db9c44f45204monthsago183MB
只要开启 https 认证后,docker 命令就必须加 –tlsverify 参数,上面所有的操作都是在 Docker 主机上操作,找另外一台机器来验证 https 是否生效:
- root@ubuntu:~#curl-v-shttps://docker01.thstack.com:6732/info
- *Abouttoconnect()todocker01.thstack.comport6732(#0)
- *Trying192.168.3.23...connected
- *successfullysetcertificateverifylocations:
- *CAfile:none
- CApath:/etc/ssl/certs
- *SSLv3,TLShandshake,Clienthello(1):
- *SSLv3,TLShandshake,Serverhello(2):
- *SSLv3,TLShandshake,CERT(11):
- *SSLv3,TLSalert,Serverhello(2):
- *SSLcertificateproblem,verifythattheCAcertisOK.Details:
- error:14090086:SSLroutines:SSL3_GET_SERVER_CERTIFICATE:certificateverifyfailed
- *Closingconnection#0
上面提示,证书验证失败,在 Docker 主机上 scp 客户端证书到这台机器上:
- root@docker01:~#cdcerts/
- root@docker01:~/certs#scpca.pemcert.pemkey.pemroot@ubuntu:/tmp
指明证书位置来验证,可以看到验证过程和结果:
- root@ubuntu:~#curl-v-s-k--key/tmp/key.pem--cert/tmp/cert.pemhttps://docker01.thstack.com:6732/info
- *Abouttoconnect()todocker01.thstack.comport6732(#0)
- *Trying192.168.3.23...connected
- *successfullysetcertificateverifylocations:
- *CAfile:none
- CApath:/etc/ssl/certs
- *SSLv3,TLShandshake,Clienthello(1):
- *SSLv3,TLShandshake,Serverhello(2):
- *SSLv3,TLShandshake,CERT(11):
- *SSLv3,TLShandshake,Serverkeyexchange(12):
- *SSLv3,TLShandshake,RequestCERT(13):
- *SSLv3,TLShandshake,Serverfinished(14):
- *SSLv3,TLShandshake,CERT(11):
- *SSLv3,TLShandshake,Clientkeyexchange(16):
- *SSLv3,TLShandshake,CERTverify(15):
- *SSLv3,TLSchangecipher,Clienthello(1):
- *SSLv3,TLShandshake,Finished(20):
- *SSLv3,TLSchangecipher,Clienthello(1):
- *SSLv3,TLShandshake,Finished(20):
- *SSLconnectionusingECDHE-RSA-AES256-SHA
- *Servercertificate:
- *subject:CN=docker01.thstack.com
- *startdate:2014-09-1403:27:16GMT
- *expiredate:2015-09-1403:27:16GMT
- *commonname:docker01.thstack.com(matched)
- *issuer:CN=docker01.thstack.com
- *SSLcertificateverifyresult:selfsignedcertificate(18),continuinganyway.
- >GET/infoHTTP/1.1
- >User-Agent:curl/7.22.0(x86_64-pc-linux-gnu)libcurl/7.22.0OpenSSL/1.0.1zlib/1.2.3.4libidn/1.23librtmp/2.3
- >Host:docker01.thstack.com:6732
- >Accept:*/*
- >
- <HTTP/1.1200OK
- <Content-Type:application/json
- <Job-Name:info
- <Date:Sun,14Sep201408:43:26GMT
- <Content-Length:417
- <
- {"Containers":1,"Debug":0,"Driver":"aufs","DriverStatus":[["RootDir","/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":"Ubuntu14.04.1LTS","SwapLimit":0}
- *Connection#0tohostdocker01.thstack.comleftintact
- *Closingconnection#0
- *SSLv3,TLSalert,Clienthello(1):
也可以在其它机器上安装 lxc-docker,来用 docker命令远程管理 Docker 主机,同样设置环境变量,添加证书,如果在配置过程中出错,查看 /var/log/upstart/docker.log 日志,或重新生成证书.
热门评论