Docker相关进程结构

只是一个简答的分析,有一个大概的认识,其实我还看了一会儿Docker的源码,然后看的自闭了

环境

  • Version: 19.03.2
  • OS/Arch: linux/amd64
  • (这里使用的是安装K8S时附带安装的Docker)

Docker相关进程名称

这里仅列出进程名称:

  • dockerd
  • containerd
  • containerd-shim
  • docker-proxy

实验环境准备

为了能更加明显地观察到这些进程的关系,本地启动两个 Nginx 容器

1
2
docker run -p 8081:80 -d nginx:alpine
docker run -p 8082:80 -d nginx:alpine

查看结果

执行命令查看相关的进程

1
pstree -apl | grep 'container\|docker' -A3 -B3

截取了主要的部分结果如下!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  |-containerd,926
| |-containerd-shim,3334 -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/f25d014e124b01669e0d5d518b7759efcf0a9be898774870a89af8a126ad9402 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
| | |-nginx,3358
| | | |-nginx,3430
| | | `-nginx,3431
| | |-{containerd-shim},3335
| | |-{containerd-shim},3336
| | |-{containerd-shim},3337
| | |-{containerd-shim},3338
| | |-{containerd-shim},3339
| | |-{containerd-shim},3340
| | |-{containerd-shim},3341
| | |-{containerd-shim},3390
| | `-{containerd-shim},4654
| |-containerd-shim,4393 -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/54a64603063ff0260b98bfe6196f9304455ef14dd762565f48dc708ea7314ac2 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
| | |-nginx,4422
| | | |-nginx,4477
| | | `-nginx,4478
| | |-{containerd-shim},4394
| | |-{containerd-shim},4395
| | |-{containerd-shim},4396
| | |-{containerd-shim},4397
| | |-{containerd-shim},4398
| | |-{containerd-shim},4399
| | |-{containerd-shim},4400
| | |-{containerd-shim},4401
| | `-{containerd-shim},5501
| |-{containerd},1035
| |-{containerd},1036
| |-{containerd},1037
| |-{containerd},1038
| |-{containerd},1112
| |-{containerd},1124
| |-{containerd},1169
| |-{containerd},1170
| |-{containerd},2118
| |-{containerd},2119
| |-{containerd},2120
| `-{containerd},4466
--
|-dockerd,1914 -H unix:// -H tcp://0.0.0.0:2375
| |-docker-proxy,3326 -proto tcp -host-ip 0.0.0.0 -host-port 8082 -container-ip 172.17.0.2 -container-port 80
| | |-{docker-proxy},3327
| | |-{docker-proxy},3328
| | |-{docker-proxy},3329
| | |-{docker-proxy},3330
| | |-{docker-proxy},3331
| | `-{docker-proxy},3332
| |-docker-proxy,4386 -proto tcp -host-ip 0.0.0.0 -host-port 8081 -container-ip 172.17.0.3 -container-port 80
| | |-{docker-proxy},4387
| | |-{docker-proxy},4388
| | |-{docker-proxy},4389
| | |-{docker-proxy},4390
| | |-{docker-proxy},4391
| | `-{docker-proxy},4392
| |-{dockerd},1975
| |-{dockerd},1976
| |-{dockerd},1977
| |-{dockerd},1980
| |-{dockerd},1991
| |-{dockerd},1992
| |-{dockerd},2091
| |-{dockerd},2115
| |-{dockerd},2172
| |-{dockerd},2173
| `-{dockerd},2174

{dockerd} 代表进程 dockerd 开出的子线程


分析结构图

看上面的这个图已经非常清晰了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  |-containerd,926
| |-containerd-shim,3334 -namespace moby -workdir...
| | |-nginx,3358
| | | |-nginx,3430
| | | `-nginx,3431
| | |-{containerd-shim},3335
// ...
| | `-{containerd-shim},4654
| |-containerd-shim,4393 -namespace moby -workdir...
| | |-nginx,4422
| | | |-nginx,4477
| | | `-nginx,4478
| | |-{containerd-shim},4394
// ...
| | `-{containerd-shim},5501
| |-{containerd},1035
// ....

从上述关系可以看出, containerd 启动了子进程 containerd-shim 以及一些线程, containerd-shim 启动了容器的进程以及一些线程。每启动一个容器就需要启动一个 containerd-shim ,可见 containerd-shim 与容器有着紧密的联系。


1
2
3
4
5
6
7
8
9
10
11
12
 |-dockerd,1914 -H unix:// -H tcp://0.0.0.0:2375
| |-docker-proxy,3326 -proto tcp -host-ip 0.0.0.0 -host-port 8082 -container-ip 172.17.0.2 -container-port 80
| | |-{docker-proxy},3327
// ...
| | `-{docker-proxy},3332
| |-docker-proxy,4386 -proto tcp -host-ip 0.0.0.0 -host-port 8081 -container-ip 172.17.0.3 -container-port 80
| | |-{docker-proxy},4387
// ...
| | `-{docker-proxy},4392
| |-{dockerd},1975
// ...
| `-{dockerd},2174

从上述关系可以看出, dockerd 启动了 docker-proxy 以及多个子线程,而 docker-proxy 负责传输相应的数据到指定的容器中,本次实验中使用的是 host 模式。

那么, 进程 dockerdcontainerd 的父进程是多少?可以使用 pstree -s -p {PID} 查看,但这里还有一种方法,查看文件 /proc/{PID}/stat 中的第四个参数,两者都为 1 ,也就是 systemd 启动的它们.