使用socat来监视Docker API

目录

作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/http://andyyoung01.16mb.com/

在某些情况下,也许您想查看docker daemon和docker client之间的通信的数据流;也许您遇到docker命令不像您预期的那样工作;或者您想编写一个自己的docker客户端来使用API与docker daemon交互。在这些情况下,使用socat来查看docker client与docker daemon的交互就非常有用了。

socat是一个十分强大的命令行工具,它允许你在几乎任何类型的两个数据通道之间中继数据,从而可以嗅探到两个数据通道的通信,进行分析。可以把它看成是一个增强版本的netcat。
我们知道docker是典型的client/server架构的程序,通常默认的情况下,docker配置为通过本地的Unix domain socker来通信,如下图:
“Docker的客户-服务器架构”
通过在客户端的请求和服务器的socker之间插入一个proxy Unix domain socker,使用socat,就可以嗅探到客户端和服务器端的通信。注意需要有root或者sudo的权限来使这种方法工作。如下图:
“在Docker client和server之间插入proxy用socat监听”
使用如下的命令来建立proxy socket同时用socat进行监听:

$ sudo socat -v UNIX-LISTEN:/tmp/dockerapi.sock UNIX-CONNECT:/var/run/docker.sock &

上面的命令中-v使输出可读,并且在输出中通过“>”和“<”标明了数据的流向。UNIX-LISTEN部分告诉socat在一个Unix socket上进行监听,UNIX-CONNECT告诉socat连接到Docker的Unix socket上。
下面使用docker client发送一个命令到上面的proxy socket(即/tmp/dockerapi.sock),该socket会由socat将命令中继到docker server的socket上,并且命令的具体内容会由socat监听到,命令如下:

$ sudo docker -H unix:///tmp/dockerapi.sock ps -a

socat监听到的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
> 2016/08/15 12:51:29.727277 length=95 from=0 to=94
GET /v1.23/containers/json?all=1 HTTP/1.1\r
Host: \r
User-Agent: Docker-Client/1.11.2 (linux)\r
\r
< 2016/08/15 12:51:29.729244 length=759 from=0 to=758
HTTP/1.1 200 OK\r
Content-Type: application/json\r
Server: Docker/1.11.2 (linux)\r
Date: Mon, 15 Aug 2016 04:51:29 GMT\r
Content-Length: 619\r
\r
[{"Id":"08b49553a278203ed321b7d10955323783760b1c1ff52c551221d7b592bc6e4b","Names":["/sleepy_visvesvaraya"],"Image":"busybox","ImageID":"sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749","Command":"sh","Created":1471236261,"Ports":[],"Labels":{},"State":"exited","Status":"Exited (0) 3 minutes ago","HostConfig":{"NetworkMode":"default"},"NetworkSettings":{"Networks":{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"","EndpointID":"","Gateway":"","IPAddress":"","IPPrefixLen":0,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":""}}},"Mounts":[]}]

可见,docker ps -a命令就是通过对docker server发送一个特定格式的HTTP的GET请求,第2行显示出了这个请求的格式。从第6行开始是docker server的HTTP响应。这样,我们便监听到了docker client和docker server间的实际通信内容。
socat不但可以用来debug Docker,而且还可以用于其它任何的网络服务,它是一个非常强大的工具。