- 为什么使用Docker?
- 与传统虚拟化技术的不同
- 传统虚拟机对比
- 主要特性
- 底层实现
- 基础架构
- 名称空间
- 控制组cgroups
- cgroup可实现的功能
- cgroup 的子系统
- Cgroup中的术语
- 联合文件系统AUFS
- 基本组件
简介
Docker是一个能把开发的应用程序自动部署到容器的开源引擎。简单说就是一个应用程序的执行容器,类似于虚拟的概念,但是与虚级化技术有所不同。
Docker 是一个开源项目,诞生于2013年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。
在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
为什么使用Docker?
Docker具有速度快、隔离框架、cpu/内存消耗低、快速开关机、跨云计算基础架构等特性,所以docker具有以下几个方面的优势
缩短开发周期,实现快速的交付和部署
高效的资源利用
轻松的迁移和扩展
简单的更新管理
与传统虚拟化技术的不同
1、 虚拟化技术需要依赖物理CPU和内存,是硬件级别;而docker构建在操作系统上,利用操作系统的containerization技术,所以docker甚至可以在虚拟上运行。
2、 虚拟化系统一般都是指操作系统镜像,比较复杂,称为“系统”;而docker开源而且轻量,成为容器,单个容器适合部署少量应用,比如不是一个redis,memcached。
3、 传统的虚拟化技术使用快照来保存状态;而docker在保存状态上不仅更为轻便和地成本,而且引入类似源代码的管理机制,将容器的快照历史版本--记录,切换成本降低。
4、 传统的虚拟化技术在构建系统的时候较为复杂,需要大量的人力;而docker可以通过Dockerfile来构建整个容器,重启和构建速度很快。更重要的是Dockfile可以手动编写,这样应用程序开发人员可以通过发布Dockerfile来知道系统环境和依赖,这样对于持续交付十分有利。
5、 Dockfile可以基于已经构建好的容器镜像,创建新容器。Dockfile可以通过社区分享和下载,有利于该技术的推广;
传统虚拟机对比
特性 |
容器 |
虚拟机 |
启动 |
秒级 |
分钟级 |
硬盘使用 |
一般为 MB |
一般为 GB |
性能 |
接近原生 |
弱于 |
系统支持量 |
单机支持上千个容器 |
一般几十个 |
主要特性:
1、 文件系统隔离:每个进程容器运行在完全独立的根文件系统里;
2、 资源隔离:可以使用cgroup为每个进程容器分配不同的系统资源,例如CPU和内存;
3、 网络隔离:每个进程容器运行在自己的网络命名空间里,拥有自己的虚拟接口和ip地址;
4、 写时复制:采用写时复制方式创建根文件系统,这让部署变得极其快捷,并且节省内存和硬盘空间。
5、 日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。
6、 变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。
7、 交互式shell:Docker可以分配一个虚拟终端并管理到任何容器的标准输入上,例如运行一个一次×××互shell。
底层实现
Docker底层的核心技术包括linux的名称空间(Namespaces)、控制组cgroups(Control group)、AUFS高级Union文件系统(Adanced Union file systems)和容器格式(Container format)
传动的虚拟主机通过在宿主主机上运行Hypervisor来模拟一整套完整的硬件环境提供给虚拟机的操作系统。虚拟系统看到的环境是可限制的,也是彼此隔离的。这种直接的做大实现了对资源最完整的封装,但很多时候往往意味着系统资源的浪费。例如,以宿主机和虚拟机系统都为linux系统为例,虚拟机中运行的应用其实可以利用宿主机系统中的运行环境。
在操作系统中,包括内核、文件系统、网络、PID、UID、IPC、内存、硬盘、CPU等等,所有的资源都是应用进程直接共享的。要想实现虚拟化,除了要实现对内存、CPU、网络IO、磁盘IO、存储空间等限制外,还要实现文件西戎、网络、PID、UID、IPC等等的相互隔离。前者相对容易实现一些,后者则需要宿主机系统的深入支持。
而让进程中个进程彼此隔离,互相之间公用一个内核,且彼此看不到对方,都只以为只有自己存在,这种机制就是容器(container)。利用名称空间来做权限隔离控制,利用cgroups来做资源分配;
基础架构
Docker采用了C/S架构,包括客户端和服务端。Dockerer daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。客户端和服务端可以运行在一个容器上,也可以通过socket或者RESTful API来进行通信;
Docker daemon 一般在宿主机主机后台运行,等待接收来自客户端的消息。Docker客户端则为用户提供一系列可执行命令,用户用这些命令实现Docker daemon交互;
名称空间
名称空间是linux内核一个强大的功能特性,每个容器都有自己独立的名称空间,运行在其中的应用都想在独立的操作系统中运行一样。名称空间保证容器之间彼此互相不影响;
使用户创建的进程与系统分离得3更加彻底,从而不需要使用更多的底层虚拟化技术;
PID Namespace(linux 2.6.24):PID名称空间 进程PID隔离;
Network Namespace(linux 2.6.29):网络名称空间 网络设备、网络栈、端口等网络资源隔离
User Namespace (linux 3.8):用户名称空间 用户和用户组资源隔离
IPC Namespace(linux2.6.19): 进程间通信名称空间 进程间通信 信号量、消息队列和共享内存的隔离;
UTS Namespace(linux 2.6.19):主机名和域名的隔离
mount Namespace(linux 2.4.19):挂载点(文件系统)隔离;
控制组cgroups
Cgroups是实现IaaS虚拟化(kvm、lxc等),PaaS容器沙箱(Docker等)的资源管理控制部分的底层基础
cgroup :linux contor group 控制组 liunx2.6.24 收录至内核
内核级别: 限制、控制与一个进程组群的资源。 限制每一个用户空间进行最大使用cpu的几个核心, 内存级也可以限制;
需要限制的资源:CPU、内存、IO
cgroup可实现的功能:
resource limitation :资源限制;
prioritization :优先级控制;
Accounting:审计和统计, 主要为计费;
control:挂起进程,恢复进程;
lssubsys -m /sys/fs/cgroup 单根树状结构
cgroup 的子系统 (linux 2.6.24收录至内核)
blkio:设定块设备的IO限制;
cpu:使用调度程序为cgroup任务提供cpu的访问,设定cpu限制;
cpuacct:报告cgroup中所使用的cpu资源;
cpuset:为cgroup中任务分配cpu和内存资源;
memory:设置每个cgroup的内存限制以及产生内存资源报告;
devices:控制cgroup中任务对设备的访问;
freezer:用于挂起或恢复cgroup中的任务;
net_cls:(classld),使用等级级别标识来标记网络数据包,以实现基于tc(traffic control)完成对不同cgroup中的产生流量控制
perf_event: 增加了对每group的监测跟踪的能力,即可以监测属于某个特定的group的所有线程以及运行在特定CPU上的线程,此功能对于监测整个group非常有用
hugetlb: 对hugeTLB系统进行限制; 转换后缓冲
Cgroup中的术语
task(任务):进程或线程
cgroup:一个独立的资源控制单位,可以包含一个或多个子系统;
subsystem:子系统, cgroups中的subsystem就是一个资源调度控制器(Resource Controller)。比如CPU子系统可以控制CPU时间分配,内存子系统可以限制cgroup内存使用量。
hierarchy:层级树 hierarchy由一系列cgroup以一个树状结构排列而成,每个hierarchy通过绑定对应的subsystem进行资源调度。hierarchy中的cgroup节点可以包含零或多个子节点,子节点继承父节点的属性。整个系统可以有多个hierarchy。
联合文件系统AUFS
联合文件系统(Union FS),一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下;
联合文件系统是docker镜像的基础。镜像可以通过分层来进程继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像;
另外,不同的docker容器可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率;
AUFS (Adanced UFS);支持位每一个成员目录(类似Git的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限,。同时AUFS里有一个类似分层的概念,对只读权限的分支可以逻辑上进行增量的修改(不影响支部部分的)。
Docker目前支持的联合文件系统种类包括AUFS、btrfs、vfs和deviceMapper;
API:clone(),setns().unshare(); 系统调用接口
clone():实现线程的系统调用,用来创建新线程。
setns(): 使进程脱离某个Namespace关联到一个新的Namespace
unshare() 将某个进程加入到某个Namespace中;
基本组件
镜像:docker image
仓库 repository
公共仓库:docker hub/registry
私有仓库:docker registry
容器 docker container:
连接 docker link(net)
数据卷docker volune
镜像
镜像:docker image:镜像文件,只读的;用来创建container;一个镜像可以运行多个container;镜像文件可以通过dockerfile文件创建,也可以从docker hub/registry 下载;
docker images:查看镜像列表
docker search:在docker hub中搜索镜像
镜像命令: images、search、pull 、push 、login、 logout、commit、build、rmi
创建镜像:commit,build
cimmit:根据已有的镜像新的变化创建新的镜像
build:根据dockerfile创建;
删除本地镜像:rmi
示例:
docker images
docker search centos
docker pull centos
上传镜像到docker hub
docker login 登录至docker hub
docker tag busybox:new yasinl/busybox:new
docker push yasinl/busybox
上传成功
根据已有镜像创建新的镜像
[root@node ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED TATUS PORTS NAMES
035229e8d264 busybox:new "/bin/sh" 3 seconds ago Up 2 seconds busybox
[root@node ~]# docker commit busybox busybox1:new1
sha256:058635d9491c913ae1572aa07f9211b7ae2cd91670514219c55e62a669190c2f
容器:
独立运行的一个或一组应用,以及它们运行的环境;
命令:
run、kill、stop、start、restart、logs、xmport、import;
logs命令:获取一个容器的日志,获取其输出的信息;
acttah命令:附加至一个运行中的容器;
run 命令
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
--name: Assign a name to the container 给容器分配一个名称
-i, --interactive=false Keep STDIN open even if not attached 开启交互式模式
-t, --tty=false Allocate a pseudo-TTY #是否打开并关联到一个为终端
--net=default Set the Network for the container 设置网络的容器默认关联到docker0网桥
示例:
运行一个容器:
[root@node ~]# docker run -it --name busybox busybox:new /bin/sh
docker kill busbox #杀次一个运行中的容器
docker stop busybox #停止一个运行中的容器
docker rm busybox #删除一个已停止容器;
启动方法:
两种方法:通过镜像创建一个新的容器;
启动一个处于停止状态的容器;
启动步骤:
检查本地是否存在指定的镜像,不存在则从registry下载;
利用镜像启动容器;
分配一个文件系统,并且在只读的镜像层之外挂载一个可读可写层;
从宿主机配置的网桥接口中桥接一个虚拟接口给此容器;
从地址池分配一个地址给容器;
执行用户指定的应用程序;
程序执行完成后,容器即终止;
仓库
仓库 repository :具有某种功能的镜像的所有相关版本构成的集合;
公共仓库:docker hub/registry
私有仓库:docker registry
registry:保存docker镜像及镜像的所有相关版本构成的集合;
随后的博客中会有关于详细仓库搭建的文章;
docker volume 数据卷
数据卷是供一个或多个容器使用的文件或目录,有多种特性:
可以共享于多个容器之间;
对数据卷的修改会立即生效;
对数据卷的更新与镜像无关;
数据卷会一直存在;