Docker的主要组件
Docker 的主要组件
安装 docker ,其实是安装了 docker 客户端、dockerd 等一系列的组件,其中比较重要的有下面几个。
Docker CLI(docker)
docker 程序是一个客户端工具,用来把用户的请求发送给 docker daemon(dockerd)。该程序的安装路径为:
/usr/bin/docker
Dockerd
docker daemon(dockerd),一般也会被称为 docker engine。该程序的安装路径为:
/usr/bin/dockerd
Containerd
详情请参考《Containerd 简介》。该程序的安装路径为:
/usr/bin/docker-containerd
Containerd-shim
它是 containerd 的组件,是容器的运行时载体,我们在 docker 宿主机上看到的 shim 也正是代表着一个个通过调用 containerd 启动的 docker 容器。该程序的安装路径为:
/usr/bin/docker-containerd-shim
RunC
详情请参考《RunC 简介》。该程序的安装路径为:
/usr/bin/docker-runc
从 hello world 开始
Docker 很贴心的为我们提供了 hello-world 镜像来验证安装是否成功,但是透过这个镜像我们还能看到更多的信息:
$ docker run hello-world
上面的输出信息指出,hello-world 容器的运行经历了如下四步:
- Docker 客户端向 docker daemon 发送请求
- Docker daemon 从 Docker Hub 上拉取镜像
- Docker daemon 使用镜像运行了一个容器并产生了输出
- Docker daemon 把输出的内容发送给了 docker 客户端
这是一个很抽象也很容器理解的过程,但是我们还想知道更多:docker daemon 是如何创建并运行容器的?
其实容器部分的操作和管理都被 dockerd 外包给 containerd 了,下图描述了运行一个容器时各个组件之间的关系:
Docker Engine API
从本质上说,docker 是一个客户端/服务器架构的应用。Dockerd 以 Engine API (REST)的方式对外提供服务,Engine API 里描述了 dockerd 支持的所有请求。Docker 客户端与 dockerd 之间就是通过 REST 的方式通信的。在 ubuntu 16.04 中,dockerd 默认是不监听 tcp 端口的,为了方便演示,我们让 dockerd 监听 tcp 端口。这样就可以使用 curl 代替 docker 客户端向 dockerd 发送请求了。具体的操作为,先修改 /lib/systemd/system/docker.service 文件,注释掉默认的 ExecStart 并添加新的 ExecStart 配置:
# ExecStart=/usr/bin/dockerd -H fd://
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
然后重启 docker.service:
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker.service
这样 dockerd 就开始监听 tcp 端口 2375 了:
Docker 与 Dockerd 的交互
Docker 客户端与 dockerd 之间就是通过 REST 的方式通信的。前面我们已经让 dockerd 监听 tcp 端口了,所以我们可以使用 curl 来代替 docker 客户端。这里我们简单的演示如何请求 dockerd 从 docker hub 上下载 hello-world 镜像:
$ curl '127.0.0.1:2375/v1.37/images/create?fromImage=hello-world&tag=latest' -X POST
如果去看看 Engine API,你会发现其它的请求也都是用类似方式发送的,是不是很简单啊!
创建容器
容器镜像的下载是由 dockerd 完成的,但容器的创建和运行就需要 containerd(docker-containerd) 来完成了。Dockerd 与 docker-containerd 之间是通过 grpc 协议通信的。当 docker-containerd 收到 dockerd 启动容器的请求之后,会做一些初始化工作,然后启动 docker-containerd-shim 进程,并将相关配置作为参数传给它。docker-containerd 负责管理所有本机正在运行的容器,而一个 docker-containerd-shim 进程只负责管理一个运行的容器,它相当于 docker-runc 的一个封装,充当 docker-containerd 和 docker-runc 之间的桥梁,docker-runc 能干的就交给 docker-runc 来做,docker-runc 做不了的就放到这里来做。下面我们用 ubuntu 镜像运行一个容器:
$ docker run -id ubuntu bash
上图中黄线框起来的是几个主要的进程,它们之间是有父子关系的(systemd 没有出现在上图):
systemd---dockerd---docker-containerd---docker-containerd-shim---bash
细心的朋友一定发现了,上图中没有出现 docker-runc 进程,这是为什么呢?
实际上,在容器启动的过程中,docker-runc 进程是作为 docker-containerd-shim 的子进程存在的。docker-runc 进程根据配置找到容器的 rootfs 并创建子进程 bash 作为容器中的第一个进程。当这一切都完成后 docker-runc 进程退出,然后容器进程 bash 由 docker-runc 的父进程 docker-containerd-shim 接管。
为什么需要 docker-containerd-shim?
也许大家会问,为什么在容器的启动或运行过程中需要一个 docker-containerd-shim 进程呢?把它移除掉整个架构会更简洁也更优美一些!事实上 docker-containerd-shim 的存在是非常有必要的,其目的有如下几点:
- 它允许容器运行时(即 runC)在启动容器之后退出,简单说就是不必为每个容器一直运行一个容器运行时(runC)
- 即使在 containerd 和 dockerd 都挂掉的情况下,容器的标准 IO 和其它的文件描述符也都是可用的
- 向 containerd 报告容器的退出状态
前两点尤其重要,有了它们就可以在不中断容器运行的情况下升级或重启 dockerd(这对于生产环境来说意义重大)。 从这里可以看到对 containerd-shim 的一些解释。
Docker的主要组件的更多相关文章
- Docker系列(二)组件介绍
镜像 镜像是一个只读的模版,可以用来创建Docker容器. 容器 Docker利用容器来运行应用,容器是从镜像创建的运行实例.它可以被启动.开始.停止.删除.每个容器都是互相隔离的,保证安全的平台.可 ...
- Docker构建其它组件
构建mysql 运行centos7容器 docker run --privileged -dti --name=centos-container centos:7 /usr/sbin/init 查询c ...
- Docker 的技术组件
Docker可以运行于任何安装了现代Linux内核的x64主机上.推荐的内核版本是3.8或者更高.Docker的开销比较低,可用于服务器.台式机或者笔记本.它包括以下几个部分. 一个原生的Linux容 ...
- 在Windows环境中开始Docker的学习和体验
研究docker有一段时间了,当然我主要的使用环境还是在Linux中,确实很方便. 但也有不少朋友希望使用Windows来工作学习,这里介绍一下在Windows中如何快速开始Docker的学习和体验吧 ...
- 进击的docker 二 : docker 快速入门
1.安装docker 1.1.安装环境 [root@docker ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@docke ...
- 《第一本docker书》- 第一章笔记
环境: Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-30-generic i686) 第一章: 1 Docker客户端和服务器 2 Docker镜像 添加一个文件,执行一 ...
- 在Mac OS上安装Vagrant和Docker的教程
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/128.html?1455808640 当听到很多人在说Docker是多么多 ...
- 搭建docker私有仓库,建立k8s集群
服务器IP角色分布 192.168.5.2 etcd server 192.168.5.2 kubernetes master 192.168.5.3 kubernetes node 192.168. ...
- Docker大行其道—初识
导读 随着分布式.云计算.大数据的火热爆发,大量的云计算集群出现,光凭计算机硬件配置的已经无法再次一较高下,虚拟化成为其中最核心的技术.虚拟化既可以通过硬件模拟,也可以通过操作系统层面去实现,近年来热 ...
随机推荐
- linux下查看进程路径
在linux下查看进程大家都会想到用 ps -ef|grep XXX可是看到的不是全路径,怎么看全路径呢?每个进程启动之后在 /proc下面有一个于pid对应的路径例如:ps -ef|grep pyt ...
- Git 常用命令和 Git Flow 梳理
git 用 git 有一段时间了,之前没有详细地了解 git flow,导致协作过程中或多或少出现了一些头疼问题.最近静下心来理了下 git flow 的整个流程,再回头看开朗了不少,总结到这里.介绍 ...
- UVA-11478 Halum (差分约束系统)
题目大意:一张n个节点的有向带边权图,每次操作能任选一个节点v个一个整数d,使以v为终点的边权值都减少d,以v为起点的边权值都增加d,求若干次操作后的最小边权值的非负最大值. 题目分析:用sum[i] ...
- UVALive-3211 Now or later (2-SAT+二分)
题目大意:有n架飞机,每架飞机有两个可选择的着陆时间,并且每架飞机都必须要选一个时间着陆.为了安全考虑,要求两架飞机的最小着陆时间差最大,找出这个最大值. 题目分析:有“最小值的最大值”这样的字眼,用 ...
- iOS自动化探索(八)Mac上的Jenkins安装
安装Jenkins 首先检查是否有Jenkins依赖的java环境 java -version 出现java version "1.8.xx"说明已经安装了java Jackeys ...
- Partition 1 does not start on physical sector boundary.分区信息不正常
[root@v1 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda2 20G 3.3G 16G ...
- 前端中CSS属性大全
css属性 布局常用样式属性: width 设置元素(标签)的宽度,如:width:100px; height 设置元素(标签)的高度,如:height:200px; background 设置元素背 ...
- restify构建REST服务(转)
restify构建REST服务 从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的Java ...
- Quartz创建多个不同名字的scheduler实例
_http://my.oschina.net/laiweiwei/blog/122280 需求创建多个不同的Scheduler实例,每个实例自主启动.关闭 问题 如果直接用 SchedulerFact ...
- [GitHub] git push的时候报错 fatal: unable to access 'http://github.com/xxx/xxx.git/': Recv failure: Connection reset by peer
参考了两种方法: 1. 解决fatal: unable to connect to github.com问题 http://blog.csdn.net/greenqingqingws/article/ ...