远程调用 Docker API

默认情况下 Docker 的守护进程启动会生成一个 socket (/var/run/docker.sock)进程通信文件,而并没有监听端口,只能在本机操作 Docker。如果想在其它地方操作 Docker 主机,就需要让 Docker 主机监听一个端口号,这样可以通过端口号就能实现远程操作。

直接和 Docker 守护进程通信

用 Python 来调用 API,Docker 提供了 Python API Client:

项目地址:https://github.com/docker/docker-py

在 Docker 主机上安装 docker-py:

pip install docker-py

先用命令行看看操作输出:

没有正在运行中的容器
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

有一个已经关闭的容器
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED                 STATUS                    PORTS               NAMES
050f47812f2c        ubuntu:14.04        "/bin/bash"         23 hours ago            Exited (0) 22 hours ago                       hopeful_shockley

用 API 方式重复上面命令行的操作,在 Python 交互里尝试调用:

# ipython

导入模块
In [1]: import docker

与 Docker 守护进程建立连接、通信
In [2]: c = docker.Client(base_url='unix:///var/run/docker.sock')                                                      

    In [3]: c.containers()
Out[3]: []

加了一个参数:all=True,代表列出所有运行、关闭的容器
In [4]: c.containers(all=True)
Out[4]: 
[{u'Command': u'/bin/bash',
  u'Created': 1410588586,
  u'Id': u'050f47812f2c1925439bbdefb479efb80bc1df007fc45ced1d74a9d483036e9b',
  u'Image': u'ubuntu:14.04',
  u'Names': [u'/hopeful_shockley'],
  u'Ports': [],
  u'Status': u'Exited (0) 22 hours ago'}]

docker 模块可以实现命令行的所有操作,具体使用方法参考 help、dir 的输出,或者查阅 docker-py 项目的文档

让 Docker 监听端口

修改 Docker 服务启动参数,添加一个没有被占用的端口号:

# vim /etc/default/docker
DOCKER_OPTS='-H docker01.thstack.com:6732'

重启 Docker 服务生效:

service docker restart

设置一个 DOCKER_HOST 环境变量,可以用主机名或 IP 地址,用主机名时候注意域名的解析,有防火墙的添加下面端口:

# vim /etc/profile
export DOCKER_HOST=tcp://docker01.thstack.com:6732

# source /etc/profile

验证

可以在本机或其它主机用 Curl 来验证,也可以使用 chrome 浏览器插件 postman 来验证:

返回空
# curl -k -X 'GET' http://docker01.thstack.com:6732/containers/json -H 'Content-type: application/json' | python -mjson.tool    

在 url 上加一个参数:all=1,获取所有的 container
# curl -k -X 'GET' http://docker01.thstack.com:6732/containers/json?all=1 -H 'Content-type: application/json' | python -mjson.tool

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   218  100   218    0     0  14273      0 --:--:-- --:--:-- --:--:-- 14533
[
    {
        "Command": "/bin/bash",
        "Created": 1410588586,
        "Id": "050f47812f2c1925439bbdefb479efb80bc1df007fc45ced1d74a9d483036e9b",
        "Image": "ubuntu:14.04",
        "Names": [
            "/hopeful_shockley"
        ],
        "Ports": [],
        "Status": "Exited (0) 23 hours ago"
    }
]

具体 Docker Remote API 参数可以参考官方 API 文档:
https://docs.docker.com/reference/api/dockerremoteapi_v1.14/

用 docker-py 来验证:

# ipython

In [1]: import docker

In [2]: c = docker.Client(base_url='http://docker01.thstack.com:6732')                                                 

In [3]: c.containers(all=True)
Out[3]: 
[{u'Command': u'/bin/bash',
  u'Created': 1410588586,
  u'Id': u'050f47812f2c1925439bbdefb479efb80bc1df007fc45ced1d74a9d483036e9b',
  u'Image': u'ubuntu:14.04',
  u'Names': [u'/hopeful_shockley'],
  u'Ports': [],
  u'Status': u'Exited (0) 23 hours ago'}]

In [4]: 

现在的 Docker 守护进程默认只监听了端口,并没有开放 socket 入口,可以让两者同时工作:

# vim /etc/default/docker
DOCKER_OPTS='-H unix:///var/run/docker.sock -H docker01.thstack.com:6732'

# service docker restart

现在我们在任何地方来连接、操作自己的 Docker 主机了。

Longgeek

Read more posts by this author.

Subscribe to Longgeek Fuvism | Python Linux 云计算 | OpenStack 虚拟技术HPC | 性能调优自动化服务器架构

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!