Docker核心概念
Docker 的操作主要围绕镜像,容器,仓库三大核心概念
什么是镜像?
一句话说即镜像是 Docker 容器启动的先决条件,因为镜像会提供容器运行的一些基础文件和配置文件,是容器启动的基础。说白了,要启动容器,需要镜像来提供一些基础环境。
使用的镜像的方式有哪些?
- 自定义创建镜像。首先找一个基础镜像,比如此镜像是Centos,然后在此镜像基础上自定义需要的内容。举个例子,基础镜像为Centos,先安装Nginx服务,然后部署咱们的应用程序,最后做一些自定义的配置,这样一个镜像就完成了,此镜像的操作系统是Centos,其中包含了Nginx服务
- 从仓库寻找别人已经做好的镜像。直接去Docker hub或者其他公开仓库 下载即可
什么是容器?
容器是镜像的运行实体。镜像是静态的只读文件,可是容器是要运行的,需要可写文件层。所以容器运行着真正的应用进程,所以自然会有创建,运行,停止,暂停和删除五种状态
既然容器是直接运行的运行程序,那它是有自己的命名空间嘛?
容器有自己独立的命名空间和资源限制,意味着在容器内部,你无法看到主机上面的进程,环境变量等信息,这就是容器和物理机上的进程本质区别
什么是仓库?
镜像仓库类似于代码仓库,用来分发和存储镜像,分为公共镜像和私有镜像。Docker hub 是 Docker 的官方公开镜像仓库,很多的官方镜像都可以在上面找到,但是访问很慢,所以可以找国内的镜像源,当然后面我们也会自己搭建一个私有镜像仓库
三者的关系是怎么样的?
上图清晰的展现了镜像是容器的基石,容器是在镜像的基础上创建的。一个镜像可以创建多个容器,仓库用来存放和分发镜像
***
Docker架构
容器技术的发展可说突飞猛进了,市面上除了 Docker 容器还有 coreos 的 rkt,lxc 等,这么多种容器,是不是需要一个标准呢,不然就太容易乱套了
你可能会说直接把 Docker 作为标准不就好了,但是有这么多相关的容器技术,谁不想吃个好瓜,除此之外,当时的编排的技术也竞争火爆,当时的三主力分别是 Docker Swarm,kubernetes 以及 mesos。作为原生的 Docker Swarm 自然优势明显,但是 kubernetes 不同意啊,它们觉得调度形式太单一了
因此爆发了容器大战,OCI 也就在此出现。
OCI 是开放的容器标准,轻量级开放的治理结构,目前主要有两个标准,分别是容器运行时标准和容器镜像标准
在如此竞争激烈下面,Docker 的架构成为了下面这个样子
Docker 的整体架构为 CS 架构,客户端和服务端两部分组成,客户端发送命令,服务端接受处理指令,其通信的方式有多种,即可以通过 Unix 套接字通信,也可以网络链接远程通信
Docker客户端
我们平时通常使用 Docker 命令行的方式和服务端打交道,其实还可以通过 REST API 的方式和 Docker 服务端交互,甚至使用各种预言的 sdk 和 Docker 的服务端交互,美滋滋
Docker服务端Docker 服务端是 Docker 后台服务的总称。其中 Dockerd 是一个非常重要的后台进程,它负责响应并处理Docker 客户端的请求,然后转化为 Docker 的具体操作
Docker 重要的组件
我们去 Docker 默认安装路径先看看有哪些组件
这里主要说明下 runc 和 contained 组件
- runc:是一个用来运行容器的轻量级工具
- contained:是容器标准化后的产物,从Dockerd剥离出来,contained通过contained-shim启动并管理runc,可以说contained是真正管理容器的生命周期
通过上图,可以看到,dockerd 通过 gRPC 与 containerd 通信,由于 dockerd 与真正的容器运行时,runC 中间有了 containerd 这一 OCI 标准层,使得 dockerd 可以确保接口向下兼容。
gRPC 是一种远程服务调用。containerd-shim 的意思是垫片,类似于拧螺丝时夹在螺丝和螺母之间的垫片。containerd-shim 的主要作用是将 containerd 和真正的容器进程解耦,使用 containerd-shim 作为容器进程的父进程,从而实现重启 dockerd 不影响已经启动的容器进程。
docker 各个组件之间的关系
- 启动一个容器
- 启动完成,通过下面命令查看 docker 的 pid
此时发现其 pid 为 4428,随后我们查看进程之间的关系
- 通过 pstree 查看进程之间的关系
注意,docker19 就看不到两者是父子关系了
可以先使用 ps aux | grep contained ,然后使用 pstree 查看 contained 的 pid ,实际上,Docker 启动的时候,contained 就启动了,dockerd 和 contained 一直就存在。当执行了docker run以后,contained 就会创建 contained-shim 充当垫片进程,然后启动容器的真正进程 sleep 3600,这和架构图一致
***
\