「Docker」- 使用 Docker API

  CREATED BY JENKINSBOT

Engine API version history

之前通过在命令行中调用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"」
# 样子的信息