一、Docker引擎
最核心的是 Docker Daemon我们称之为Docker守护进程,也就是Server端,Server端可以部署在远程,也可以部署在本地,因为Server端与客户端(Docker Client)是通过Rest API进行通信。
docker CLI 实现容器和镜像的管理,为用户提供统一的操作界面,这个 客户端提供一个只读的镜像,然后通过镜像可以创建一个或者多个容器(container),这些容器可以只是一个RFS(Root File System),也可以是一个包含了用户应用的RFS。容器在docker Client中只是一个进程,两个进程是互不可见的。
二、Docker架构
Docker使用C/S架构,Client 通过接口与Server进程通信实现容器的构建,运行和发布。client和server可以运行在同一台集群,也可以通过跨主机实现远程通信。
Docker三大核心概念
Docker 镜像(Image)就是一个只读的模板。例如:一个镜像可以包含一个完整的操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
Docker 利用容器(Container)来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
仓库是集中存放镜像文件的场所,仓库注册服务器(Registry)上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。目前,最大的公开仓库是DockerHub,存放了数量庞大的镜像供用户下载。
Docker仓库用来保存我们的images,当我们创建了自己的image之后我们就可以使用push命令将它上传到公有或者私有仓库,这样下次要在另外一台机器上使用这个image时候,只需要从仓库上pull下来就可以了。
Docker的运行离不开这几位的支持,Docker的成功也是拜几位所赐。也有人会误以为,Docker就是容器。但Docker只会傲娇地说:我不是容器,我是管理容器的引擎。
三、Docker组成
Docker是由Cgroup、NameSpace、rootfs和容器引擎(用户态工具)组成。
3.1、Cgroup
Cgroup是Control group的简写,属于Linux内核的一个特性,用于限制和隔离一组进程对系统资源的使用,也就是做资源QOS,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免多个容器同时运行时对宿主机系统的资源竞争。控制组可以提供对容器的内存、CPU、磁盘IO等资源进行限制和计费管理。控制组的设计目标是为不同的应用情况提供统一的接口,从控制单一进程(比如nice工具)到系统级虚拟化(包括OpenVZ、Linux-VServer、LXC等)。从实现的角度来看,Cgroup中实现的子系统其作用如下:
- devices:设备权限控制
- cpuset:分配指定的cpu和内存节点
- cpu:控制cpu的占用率
- cpuacct:统计cpu的使用情况
- memory:限制内存的使用上限
- freezer:冻结(暂停)Cgroup中的进程
- net_cls:配合tc(traffic controller)限制网络带宽
- net_prio:设置进程的网络流量优先级
- huge_tlb:限制HugeTLB的使用
- perf_event:允许Perf工具基于Cgroup分组做性能测试
从而可见Cgroup主要的作用是以下几点。
- 资源限制(Resource limiting):可以将组设置为不超过设定的内存限制。比如:内存子系统可以为进程组设定一个内存使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发Out of Memory警告。
- 优先级(Prioritization):通过优先级让一些组优先得到更多的CPU等资源。
- 资源审计(Accounting):用来统计系统实际上把多少资源用到适合的目的上,可以使用cpuacct子系统记录某个进程组使用的CPU时间。
- 隔离(isolation):为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统。
- 控制(Control):挂起、恢复和重启动等操作。
3.2、NameSpace
NameSpace是将内核的全局资源做封装,使得每个NameSpace都有一份独立的资源,因此不同的进程在各自的NameSpace内对同一种资源的使用不会互相干扰。目前Linux内核公共实现了6种NameSpace:
- IPC:隔离进程间通信(System V IPC和POSIX消息队列):
- Network:隔离网络资源
- Mount:隔离文件系统挂载点
- PID:隔离进程ID
- UTS:隔离主机名和域名
- User:隔离用户ID和组ID
Linux 的命名空间机制提供了七种不同的命名空间,包括 CLONE_NEWCGROUP、CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWPID、CLONE_NEWUSER 和 CLONE_NEWUTS,通过这七个选项我们能在创建新的进程时设置新进程应该在哪些资源上与宿主机器进行隔离。
3.3、rootfs
挂载在容器根目录上、用来为容器进程提供隔离后执行环境的文件系统,就是所谓的“容器镜像”;一个最常见的rootfs,或者说容器镜像,会包括如下所示的一些目录和文件,比如/bin /etc/ proc等等。对Docker项目来讲,最核心的管理是为等待创建的用户进程:
- 启用Linux NameSpace隔离配置;
- 设置指定的Cgroup限制参数;
- 切换进程的根目录(Change Root)
这样一个完整的容器就诞生了。需要明确的是rootfs只是一个操作系统所包含的文件、配置和目录,并不包括操作系统的内核(bootfs包含了BootLoader和Kernel), 在Linux操作系统中,这两部分是分开存放的,操作系统只有在开机启动
时才会加载指定版本的内核。
所以说,rootfs 只包括了操作系统的“躯壳”,并没有包括操作系统的“灵魂”。
四、Docker容器的能力
- 文件系统隔离:每个容器都有自己的root文件系统;
- 进程隔离:每个容器都运行在自己的进程环境中;
- 网络隔离:容器间的虚拟网络接口和IP地址都是分开的;
- 资源隔离和分组:使用cgroups将CPU和内存之类的资源独立分配给每个Docker容器;