1. docker的整体工作流程
docker本身其实是一个server的形式存在着的,叫做docker daemon
,也叫做dockerd
,那么怎么与这个server进行通信呢?当然想到要用一个client客户端,client客户端有很多种形式,比如我们经常在命令行敲的docker
工具,它就是一个client,另外比如windows或mac系统装的桌面版docker,那也是客户端(这个也可以操控dockerd),总之有很多形式的客户端。所以docker工作本身是一个client/server
架构,客户端通过unix socket
进程间通信的方式与服务端做信息交互(默认如果是与本地的dockerd交互的话是这么交互,如果是与远端的dockerd交互需要重新指定host及协议)。
2. dockerd如何启动
这里先不聊dockerd启动以后做了什么,先来聊聊dockerd是如何启动的。
以centos7为例,之前我的机器已经通过yum安装了docker,这里通过下面的命令来看下到底安装了什么。
[root@wxtest062vm6 system]# rpm -qa | grep docker
docker-ce-19.03.1-3.el7.x86_64
docker-ce-cli-19.03.1-3.el7.x86_64
安装了一个docker和docker-cli
通过执行rpm -ql 软件名称
就可以看到软件的安装路径
[root@wxtest062vm6 system]# rpm -ql docker-ce-19.03.1-3.el7.x86_64
/usr/bin/docker-init
/usr/bin/docker-proxy
/usr/bin/dockerd
/usr/lib/systemd/system/docker.service
/usr/lib/systemd/system/docker.socket
/var/lib/docker-engine/distribution_based_engine-ce.json
可以看到docker是通过服务systemd起的,/usr/lib/systemd/system/docker.service
这个文件,看看这个文件里都有什么。
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
BindsTo=containerd.service
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3
# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
[Install]
WantedBy=multi-user.target
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
这一行表示服务启动的命令,跟我们用ps看到的是一样的
[root@wxtest062vm6 ~]# ps -ef |grep docker | grep -v grep
root 26288 1 0 4月09 ? 00:00:23 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
看完了这个文件再来看看/usr/lib/systemd/system/docker.socket
[root@wxtest062vm6 ~]# cat /usr/lib/systemd/system/docker.socket
[Unit]
Description=Docker Socket for the API
PartOf=docker.service
[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
这里指明了docker的本地的socket文件/var/run/docker.sock
,可以这么理解,docker客户端发往docker daemon的请求其实都是发给了这个socket文件,我们通过netstat命令来看一下
[root@wxtest062vm6 ~]# ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 4月 9 14:41 /var/run/docker.sock
[root@wxtest062vm6 ~]# netstat -anp | grep docker
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 2 [ ACC ] STREAM LISTENING 17552729 26288/dockerd /var/run/docker/libnetwork/922b58f9f1ffa643ecb3b95f6a66c61ffed763bab57aa0861f55d0c03f3225db.sock
unix 2 [ ACC ] STREAM LISTENING 17549222 1/systemd /var/run/docker.sock
unix 2 [ ACC ] STREAM LISTENING 17551074 26288/dockerd /var/run/docker/metrics.sock
unix 3 [ ] STREAM CONNECTED 17551072 26288/dockerd
unix 3 [ ] STREAM CONNECTED 17551076 26288/dockerd
unix 3 [ ] STREAM CONNECTED 17552634 26288/dockerd
unix 2 [ ] DGRAM 17554460 26288/dockerd
Proto显示连接使用的协议,RefCnt表示连接到本套接口上的进程号,Types显示套接口的类型,State显示套接口当前的状态,Path表示连接到套接口的其它进程使用的路径名。
其中,unix表示连接使用的协议,是unix域协议。在创建socket的时候,可以指定协议族,有AF_UNIX,AF_INET,AF_INET6三种协议族,docker在这里使用的就是UNIX域协议族AF_UNIX,能够在本地进程间通信,而AF_INET,AF_INET6这两种协议族就是用在网络之间传输,UNIX本地协议族要比网络协议族的速度快很多。
前面说过docker是systemd下的一个服务,那么就可以用systemd启停服务的命令来启停docker服务。
systemctl start docker.serovce
也可以使用service start docker
来用,这个是Centos6与Centos7的区别。
这样一来,dockerd就启动了。