一、docker架构
Docker 采用了 C/S架构,包括客户端和服务端。 Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。 客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。
docker基本架构
docker daemon 一般在宿主机后台运行,等待接收来自客户端的消息。 Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon 交互。
Docker提供了工具和平台来管理容器,而Docker Engine则是一个提供了大部分功能组件的CS架构的应用,如架构图所示,Docker Engine负责管理镜像,容器,网络以及数据卷等。
二、Docker容器的底层实现
Docker提供了一个打包和运行应用的隔离环境,称之为容器,docker容器本质上是把系统中为同一个业务目标服务的相关进程合成一组,放在一个叫做namespace的空间中,同一个namespace中的进程能够互相通信,但看不见其他namespace中的进程。每个namespace可以拥有自己独立的主机名、进程ID系统、IPC、网络、文件系统、用户等等资源。Docker的隔离和安全特性允许你在一个主机同时运行多个容器,而且它并不像虚拟机那样重量级,容器都是基于宿主机的内核运行的,它是轻量的,不管你运行的是ubuntu, debian还是其他Linux系统,用的内核都是宿主机内核。
容器 = cgroup + namespace + 联合文件系统 + 容器引擎
- Cgroup: 资源控制
- namespace: 访问隔离
- 联合文件系统:文件系统隔离
- 容器引擎:生命周期控
namespace
Linux Namespaces机制提供一种资源隔离
方案。PID,IPC,Network等系统资源不再是全局性的,而是属于某个特定的Namespace。这是一种轻量级的虚拟化形式,用来隔离各个容器
Namespace 的工作方式通过为一组资源和进程设置相同的 Namespace 而起作用,但是这些 Namespace 引用了不同的资源。资源可能存在于多个 Namespace 中。这些资源可以是进程 ID、主机名、用户 ID、文件名、与网络访问相关的名称和进程间通信。
简而言之,Namespace 是 Linux 内核的一个特性,该特性可以实现在同一主机系统中,对进程 ID、主机名、用户 ID、文件名、网络和进程间通信等资源的隔离。Docker 利用 Linux 内核的 Namespace 特性,实现了每个容器的资源相互隔离,从而保证容器内部只能访问到自己 Namespace 的资源。
正是由于 Docker 使用了 Linux 的这些 Namespace 技术,才实现了 Docker 容器的隔离,可以说没有 Namespace,就没有 Docker 容器。
最新的 Linux 5.6 内核中提供了 8 种类型的 Namespace,而最新版本的 Docker 只使用了其中的前6 种,分别为Mount Namespace、PID Namespace、Net Namespace、IPC Namespace、UTS Namespace、User Namespace。
IPC: 用于隔离进程间通信。
MNT: 用于隔离文件系统和提供硬盘挂载点。
NET: 用于隔离网络。
PID: 用于隔离进程ID。
User: 用于隔离用户和用户组。
UTS: 用于隔离HostName和DomianName。
Cgroup
Docker通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面, 基本覆盖了常见的资源配额和使用量控制。
Cgroup的内核通过hook钩子来实现管理进程资源,提供了一个统一的接口,从单个进程的资源控制到操作系统层面的虚拟卡的过渡!