17.1 基本架构

Docker目前采用了标准的C/S架构,如图17-1所示。客户端和服务端既可以运行在一个机器上,也可运行在不同机器上通过socket或者RESTful API来进行通信。

17.1 基本架构 - 图1

图17-1 Docker采用了C/S架构

1.服务端

Docker Daemon一般在宿主主机后台运行,作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。

在设计上,Docker Daemon是一个模块化的架构,通过专门的Engine模块来分发管理各个来自客户端的任务。

Docker服务端默认监听本地的unix:///var/run/docker.sock套接字,只允许本地的root用户或docker用户组成员访问。可以通过-H选项来修改监听的方式。

例如,让服务端监听本地的TCP连接1234端口,如下所示:


  1. $ docker daemon -H 0.0.0.0:1234
  2. WARN[0000] /!\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU
  3. DON'T KNOW WHAT YOU'RE DOING /!\
  4. INFO[0000] New containerd process, pid: 22385
  5. INFO[0001] [graphdriver] using prior storage driver "aufs"
  6. INFO[0001] Graph migration to content-addressability took 0.00 seconds
  7. INFO[0001] Firewalld running: false
  8. INFO[0001] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16.
  9. Daemon option --bip can be used to set a preferred IP address
  10. WARN[0002] Your kernel does not support swap memory limit.
  11. WARN[0002] mountpoint for pids not found
  12. INFO[0002] Loading containers: start.
  13. ...

此外,Docker还支持通过HTTPS认证方式来验证访问。

17.1 基本架构 - 图2注意

Debian/Ubuntu 14.04等使用upstart管理启动服务的系统中,Docker服务端的默认启动配置文件在/etc/default/docker。对于使用systemd管理启动服务的系统,配置文件在/etc/systemd/system/docker.service.d/docker.conf。

2.客户端

Docker客户端为用户提供一系列可执行命令,用户用这些命令与Docker Daemon交互。

用户使用的Docker可执行命令即为客户端程序。与Docker Daemon不同的是,客户端发送命令后,等待服务端返回,一旦收到返回后,客户端立刻执行结束并退出。用户执行新的命令,需要再次调用客户端命令。

同样,客户端默认通过本地的unix:///var/run/docker.sock套接字向服务端发送命令。如果服务端没有监听在默认的地址,则需要客户端在执行命令的时候显式指定服务端地址。

例如,假定服务端监听在本地的TCP连接1234端口tcp://127.0.0.1:1234,只有通过-H参数指定了正确的地址信息才能连接到服务端,如下所示:


  1. $ docker version
  2. Client:
  3. Version: 1.12.0
  4. API version: 1.24
  5. Go version: go1.6.3
  6. Git commit: 8eab29e
  7. Built: Thu Sep 28 22:00:36 2016
  8. OS/Arch: linux/amd64
  9. Cannot connect to the Docker daemon. Is the docker daemon running on this host?
  10. $ docker -H tcp://127.0.0.1:1234 version
  11. Client:
  12. Version: 1.12.0
  13. API version: 1.24
  14. Go version: go1.6.3
  15. Git commit: 8eab29e
  16. Built: Thu Sep 28 22:00:36 2016
  17. OS/Arch: linux/amd64
  18. Server:
  19. Version: 1.12.0
  20. API version: 1.24
  21. Go version: go1.6.3
  22. Git commit: 8eab29e
  23. Built: Thu Sep 28 22:00:36 2016
  24. OS/Arch: linux/amd64

3.新的架构设计

应该说,C/S架构给Docker基本功能的实现带来了许多便利,但同时也引入了一些限制。

读者朋友们可能发现,使用Docker时,必须要启动并保持Docker Daemon的正常运行,它既要管理容器的运行时,又要负责提供对外部API的响应。而一旦Docker Daemon服务不正常,则已经运行在Docker主机上的容器也往往无法继续使用。

Docker团队已经意识到了这个问题,在较新的版本(1.11.0+)中,开始将维护容器运行的任务放到一个单独的组件containerd中来管理,并且支持OCI的runc规范。原先的对客户端API的支持则仍然放在Docker Daemon,通过解耦,大大减少了对Docker Daemon的依赖。

同时,新的架构提高了启动容器的速度,一项测试表明,可以达到每秒启动超过100个容器。