Docker容器技术基础入门
Docker容器技术基础入门
什么是容器?
容器是一种基础工具;泛指任何可以用于容纳其它物品的工具,可以部分或完全封闭,被用于
容纳、储存、运输物品;物体可以被放置在容器中,而容器则可以保护内容物;
人类使用容器的历史至少有十万年,甚至可能有数百万年的历史;
而在计算机领域:
容器(container)是指是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提
供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试
再到生产的整个过程中,它都具有可移植性和一致性。
容器与虚拟化的区别?
很多人分不清容器与虚拟化的区别。容器是虚拟化吗?是,但也不竟然,简单来说:
虚拟化使得多个操作系统可同时运行在单个系统上
容器则可共享同一个操作系统的内核,将应用程序与系统其它部分隔离开
这意味着什么?首先,让多个操作系统在单个虚拟机监控程序上运行以实现虚拟化,并不
能达成和使用容器同等的轻量级效果。事实上,在仅拥有容量有限的有限资源时,您需要能
够可以进行密集部署的轻量级应用。Linux 容器可从单个操作系统运行,在所有容器中共享该
操作系统,因此应用和服务能够保持轻量级,并行快速运行。
容器的发展史
1979年 — Chroot
容器技术的概念可以追溯到1979年的UNIX Chroot。这项功能将Root目录及其它子目录变更至文件系统内的新位置,且只接受特定进程的访问,其设计目的在于为每个进程提供一套隔离化磁盘空间。1982年其被添加至BSD。
Chroot只是提供了对进程文件目录虚拟化的功能,不能够防止进程恶意访问系统。这个问题在FreeBSDGails容器技术中得以解决。
2000年 — FreeBSD Jails
FreeBSD Jails与Chroot的定位类似,不过其中包含有进程沙箱机制以对文件系统、用户及网络等资源进行隔离。通过这种方式,它能够为每个Jail、定制化软件安装包乃至配置方案等提供一个对应的IP地址。Jails技术为FreeBSD系统提供了一种简单的安全隔离机制。它的不足在于这种简单性的隔离也同时会影响Jails中应用访问系统资源的灵活性。
2004年 — Solaris Zones
Solaris Zone技术为应用程序创建了虚拟的一层,让应用在隔离的Zone中运行,并实现有效的资源管理。每一个Zone 拥有自己的文件系统,进程空间,防火墙,网络配置等等。
Solaris Zone技术真正的引入了容器资源管理的概念。在应用部署的时候为Zone配置一定的资源,在运行中可以根据Zone的负载动态修改这个资源限制并且是实时生效的,在其他Zone不需要资源的时候,资源会自动切换给需要的资源的Zone,这种切换是即时的不需要人工干预的,最大化资源的利用率,在必要的情况下,也可以为单个Zone隔离一定的资源。
2008年 — LXC
LXC指代的是Linux Containers,其功能通过Cgroups以及Linux Namespaces实现。也是第一套完整的Linux容器管理实现方案。在LXC出现之前, Linux上已经有了类似 Linux-Vserver、OpenVZ 和 FreeVPS。虽然这些技术都已经成熟,但是这些解决方案还没有将它们的容器支持集成到主流 Linux 内核。相较于其它容器技术,LXC能够在无需任何额外补丁的前提下运行在原版Linux内核之上。目前LXC项目由Canonical有限公司负责赞助及托管。
LXC采用以下内核功能模块。
- Kernel namespaces (ipc, uts, mount, pid, network and user)
- Apparmor and SELinux profiles
- Seccomp policies
- Chroots (using pivot_root)
- Kernel capabilities
- CGroups (control groups)
2013年 — Docker
Docker项目最初是由一家名为DotCloud的平台即服务厂商所打造,其后该公司更名为Docker。Docker在起步阶段使用LXC,而后利用自己的Libcontainer库将其替换下来。与其它容器平台不同,Docker引入了一整套与容器管理相关的生态系统。其中包括一套高效的分层式容器镜像模型、一套全局及本地容器注册表、一个精简化REST API以及一套命令行界面等等。
与Docker具有同样目标功能的另外一种容器技术就是CoreOS公司开发的Rocket. Rocket基于App Container规范并使其成为一项更为开放的标准。
2016年 — Windows容器
微软公司也于2016年正式推出Windows容器。Windows 容器包括两个不同的容器类型。
Windows Server 容器
通过进程和命名空间隔离技术提供应用程序隔离。 Windows Server 容器与容器主机和该主机上运行的所有容器共享内核。
Hyper-V 容器
通过在高度优化的虚拟机中运行每个容器,在由 Windows Server 容器提供的隔离上扩展。 在此配置中,容器主机的内核不与 Hyper-V 容器共享。Hyper-V容器是一个新的容器技术,它通过Hyper-V虚拟化技术提供高级隔离特性。
CGroups
控制组(CGroups)是Linux内核的一个特性,用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,Docker才能避免多个容器同时运行时的系统资源竞争。
控制组可以提供对容器的内存、CPU、磁盘IO等资源进行限制。
CGroups能够限制的资源有:
- blkio:块设备IO
- cpu:CPU
- cpuacct:CPU资源使用报告
- cpuset:多处理器平台上的CPU集合
- devices:设备访问
- freezer:挂起或恢复任务
- memory:内存用量及报告
- perf_event:对cgroup中的任务进行统一性能测试
- net_cls:cgroup中的任务创建的数据报文的类别标识符
具体来看,控制组提供如下功能:
- 资源限制(Resource Limitting)组可以设置为不超过设定的内存限制。比如:内存子系统可以为进行组设定一个内存使用上限,一旦进程组使用的内存达到限额再申请内存,就会发出Out of Memory警告
- 优先级(Prioritization)通过优先级让一些组优先得到更多的CPU等资源
- 资源审计(Accounting)用来统计系统实际上把多少资源用到合适的目的上,可以使用cpuacct子系统记录某个进程组使用的CPU时间
- 隔离(Isolation)为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统
- 控制(Control)挂起、恢复和重启等操作
Docker的工作原理
1)可以建立一个容纳应用程序的容器。
2)可以从Docker镜像创建Docker容器来运行应用程序。
3)可以通过Docker Hub或者自己的Docker仓库分享Docker镜像。
Docker镜像是如何工作的?
Docker镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层(layers)组成;
Docker使用UnionFS(联合文件系统)来将这些层联合到一二镜像中,UnionFS文件系统允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。
正因为有了这些层(layers)的存在,Docker才会如此的轻量。当你改变了一个Docker镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。所以你不用重新发布整个镜像,只需要升级。层使得分发Docker镜像变得简单和快速。
每个镜像都是从一个基础的镜像开始的,比如ubuntu,一个基础的Ubuntu镜像,或者是Centos,一个基础的Centos镜像。你可以使用你自己的镜像作为新镜像的基础,例如你有一个基础的安装了Nginx的镜像,你可以使用该镜像来建立你的Web应用程序镜像。(Docker通常从Docker Hub获取基础镜像)
Docker镜像从这些基础的镜像创建,通过一种简单、具有描述性的步骤,我们称之为 指令(instructions)。
每一个指令会在镜像中创建一个新的层,指令可以包含这些动作:
1)运行一个命令。
2)增加文件或者文件夹。
3)创建一个环境变量。
5)当运行容器的时候哪些程序会运行。
这些指令存储在Dockerfile文件中。当你需要建立镜像的时候,Docker可以从Dockerfile中读取这些指令并且运
行,然后返回一个最终的镜像。
Docker仓库是如何工作的?
Docker仓库是Docker镜像的存储仓库。可以推送镜像到Docker仓库中,然后在Docker客户端,可以从Docker仓库中搜索镜像。
Docker容器是如何工作的?
一个Docker容器包含了一个操作系统、用户添加的文件和元数据(meta-data)。每个容器都是从镜像建立的,镜像告诉Docker容器内包含了什么,当容器启动时运行什么程序,还有许多配置数据。
Docker镜像是只读的,当Docker运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。
LXC
LXC(LinuX Containers)Linux容器,一种操作系统层虚拟化技术,为Linux内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享API来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得Linux用户可以容易的创建和管理系统或应用容器。 在Linux内核中,提供了cgroups功能,来达成资源的隔离。它同时也提供了名称空间隔离的功能,使应用程序看到的操作系统环境被区隔成独立区间,包括进程树,网络,用户id,以及挂载的文件系统。但是cgroups并不一定需要启动任何虚拟机。 LXC利用cgroups与名称空间的功能,提供应用软件一个独立的操作系统环境。LXC不需要Hypervisor这个软件层,软件容器(Container)本身极为轻量化,提升了创建虚拟机的速度。
而Docker本质来说不是容器,而是容器的管理工具,最初的Docker也是基于LXC实现的。
LXC关键技术点:
- chroot,根切换,从容器内的角度来看,仿佛真的有自己的根树
- namespaces:名称空间,负责将资源隔离,比如pid,网络,mnt,user,uts等
- CGroups:控制组,负责控制资源的分配
Docker容器编排
就像Apple推出iPhone让智能手机变成主流,Docker让容器变成了主流。自从项目发布以来,Docker着重于提升开发者的体验。基本理念是可以在整个行业中,在一个标准的框架上,构建、交付并且运行应用。理论上,一个机构能够从一个笔记本上构建出一个持续集成和持续开发的流程,然后将其应用到生产环境。
起初的一个挑战是数据中心编排。与VMware vSphere不同,当时少有能在生产环境中大规模管理负载的工具,而Docker用来在数据中心级别进行容器编排的主要方式是Docker Swarm。
容器编排的解决方案一直不缺。Apache Mesosphere是早期的领头羊,而现在的势头已经今非昔比。Docker Swarm虽然是单个厂商的编排视角,但是它与Docker EE深度整合。Docker正在用Docker EE构建一个能合与成熟的项目如Cloud Foundry匹敌的平台。然而,正如前面提到的,整个行业已经聚集到了Kubernetes的家门前。
按照Docker的说法,Google将它们的超大范围的经验带到了容器编排中。Kubernetes采取的开源策略赢得了生态中的大量用户。
常见的容器编排工具:
- machine+swarm(把N个docker主机当一个主机来管理)+compose(单机编排)
- mesos(实现统一资源调度和分配)+marathon
- kubernetes --> k8s