之前通过在命令行中调用Docker命令,但是这不是理想的方案。Docker提供了API,可以通过API来操作Docker进行服务集成。
首先将Docker服务绑定到网络端口,然后通过HTTP API来控制Docker服务。
最后使用TLS进行认证。
三种 API 接口
在 Docker Ecosystem 中,有三种 API 接口:
1)Registry API:用于与 Registry 服务集成。
2)Docker Hub API:用于与 Docker Hub 集成。
3)Docker Remote API:用于与 Docker 守护进程进行集成。
这三种 API 都是 RESTful 风格,该笔记将记录:与 Docker Remote API 相关内容。
# 初识「Remote API」
Remote API由Docker守护进程提供。
守护进程默认会绑定到一个本地的套接字上,`unix:///var/run/docker.sock’。守护进程是以root运行,因为要去管理资源。如果系统存在一个Dokcer组,Docker会将套接字的所有者设置为该组,任何属于该组的用户都可以控制Docker,而无需root权限。(这里存在一些安全问题,要做好权限控制。)
但本地的套接字只能用于本地访问,如果要远程访问,则需要使用-H选项绑定到网络接口上。本地可以使用 nc 命令进行测试:
echo -e "GET /info HTTP/1.0/r/n" | nc -U /var/run/docker.sock
绑定到网络接口指定-H选项(docker -d -H tcp://0.0.0.0:2375)既可,但是不同的发行版有不同的配置方式,这里不介绍…………当然,防火墙要允许访问。
使用-H选项来测试(docker -H docker.example.com:2375 info),此时的Docker是作为客户端运行的。或者使用DOKCER_HOST环境变量(DOCKER_HOST="tcp://docker.example.com:2375“)
# 测试「Remote API」
#!/bin/sh # 服务状态查看 curl http://docker.example.com:2375/info # JSON ################################################################################ # 镜像相关 ################################################################################ # 查看所有镜像 curl http://docker.example.com:2375/images/json | python -m json.tool # 查看某一个镜像 curl http://docker.example.com:2375/images/15xxxxxxxxx/json | python -m json.tool # 通过API进行搜索 curl http://docker.example.com:2375/images/search?term=jamturo1 | python -m json.tool ################################################################################ # 容器相关 ################################################################################ # 查看所有容器 curl http://docker.example.com:2375/containers/json | python -m json.tool curl http://docker.example.com:2375/containers/json?all=1 | python -m json.tool # 创建容器 curl -X POST -H "Content-Type: application/json" \ http://docker.example.com:2375/containers/create \ -d '{ "Image" : "jscaasd/jek" }' # 返回新容器的ID # 启动容器 curl -X POST -H "Content-Type: application/json" \ http://docker.example.com:2375/containers/baxxxxxxxx/start \ -d '{ "PublicshAllPort" : true }' # 查看容器信息 curl http://docker.example.com:2375/containers/15xxxxxxxxx/json | python -m json.tool
# 改进TProv应用
官方提供了很多的SDK用于操作Docker服务,建议在应用程序中使用RESTful API操作Docker服务,而不是使用Docker命令。
「Develop with Docker Engine SDKs and API」
# 对「Remote API」进行认证
从Docker 0.9开始支持TLS/SSL认证。
下面的示例中我们建立自己的「证书授权中心(CA)」
#1 CA
#!/bin/sh mkdir ssl && cd ssl # http://users.skynet.be/pascalbotte/art/server-cert.htm # The first time you use your CA to sign a certificate you can use the # -CAcreateserial option. This option will create a file (ca.srl) containing a # serial number. You are probably going to create more certificate, and the next # time you will have to do that use the -CAserial option (and no more # -CAcreateserial) followed with the name of the file containing your serial # number. This file will be incremented each time you sign a new certificate. # This serial number will be readable using a browser (once the certificate is # imported to a pkcs12 format). And we can have an idea of the number of # certificate created by a CA echo 01 | tee ca.srl # CA密钥:ca-key.pem openssl genrsa -des3 -out "ca-key.pem" # 最好设置密码 # CA证书:ca.pem(CA的一些信息) openssl req -new -x509 -days 365 -key "ca-key.pem" -out "ca.pem"
#2 Server
#!/bin/sh ################################################################################ # 生成服务器证书 ################################################################################ # Server密钥:server-key.pem openssl genrsa -des3 -out "server-key.pem" # 最好设置密码 # Server CSR:server.csr(服务器的信息) openssl req -new -key "server-key.pem" -out "server.csr" # Server CERT:server-cert.pem(服务器证书,并包含附加信息) echo "subjectAltName = IP:x.x.x.x,IP:127.0.0.1" > extfile.cnf openssl x509 -req -days 365 -in "server.csr" -CA "ca.pem" \ -CAkey "ca-key.pem" -out "server-cert.pem" -extfile "extfile.cnf" # 清除server-key.pem的密码 openssl rsa -in server-key.pem -out server-key.pem ################################################################################ # 配置Docker守护进程 ################################################################################ # 启动Docker守护进程时,指定如下选项: /usr/bin/docker -d -H tcp://0.0.0.0:2376 \ --tlsverify \ --tlscacert=/etc/docker/ca.pem \ --tlscert=/etc/docker/server-cert.pem \ --tlskey=/etc/docker/server-key.pem # 端口2376是默认的TLS/SSL端口 # 非认证则使用2375端口 # --tls 使用该选项后,只使用tls,而不启用客户端认证。
#3 Client
#!/bin/sh ################################################################################ # 生成客户端证书 ################################################################################ # Client密钥:client-key.pem openssl genrsa -des3 -out "client-key.pem" # 最好设置密码,只用于创建期间 # Client CSR:client.csr(客户端的信息) openssl req -new -key "client-key.pem" -out "client.csr" # Client CERT:client-cert.pem(客户端证书,并包含附加信息) echo "extendedKeyUsage = clientAuth" > extfile.cnf openssl x509 -req -days 365 -in "client.csr" -CA "ca.pem" \ -CAkey "ca-key.pem" -out "client-cert.pem" -extfile "extfile.cnf" # 清除client-key.pem的密码 openssl rsa -in client-key.pem -out client-key.pem ################################################################################ # 配置Docker客户端 ################################################################################ mkdir -p ~/.docker/ cp ca.pem ~/.docker/ca.pem cp client-key.pem ~/.docker/key.pem cp client-cert.pem ~/.docker/cert.pem chmod 0600 ~/.docker/key.pem ~/.docker/cert.pem docker -H=docker.example.com:2376 --tlsverify info # 或者使用--tlscacert , --tlscert , --tlskey来指定证书信息 # 如果没有指定TLS则会返回类似于「malformed HTTP response "\x15\x03\x01\x00\x02\x02"」 # 样子的信息