容器技术出现的背景

服务器时代

在服务器时代,应用直接跑在服务器上。业务部门想要增加一个新的应用服务,IT部门就需要采购新的服务器服务器来满足需求,而IT部门为了不让业务由于服务器瓶颈而出现问题,就会采购大幅由于业务需求的服务器。这种做法,导致了公司大量的服务器处于低负荷运行状态下,浪费了大量的资源和资产。

虚拟机时代

而虚拟机技术解决了如上的问题,通过虚拟机技术,实现了一个服务器安全稳定运行多个应用。虚拟机是一种有划时代意义的技术,每当业务部门需要增加应用的时候,IT部门直接在空闲的服务器上启动虚拟机就可以部署应用了,从而大大增加了服务器的利用率,为公司节省了大量资金。

虚拟机技术也有自己的缺点,最大缺点为每个虚拟机必须拥有自己独立的完整操作系统,而操作系统本身会占用额外的cpu,内存和存储资源。并且,每个操作系统本身需要许可证,打补丁,监控等,从而增加了运营成本。虚拟机技术也面临启动速度慢,跨平台移植性差的挑战。

容器时代

容器技术可以很好的解决虚拟机的缺点,可以把服务跑在容器中解决虚拟机模型的缺点。对比虚拟机主要区别在于容器运行不需要独占一个完整的操作系统。运行在同一主机的容器可以共享主机上的操作系统,这样就节省了大量的cpu,内存和存储资源。容器也不需要许可证和打补丁,降低了运营和资金成本。

现代的容器技术起源于Linux,是很多人长期努力持续贡献的产 物。对容器发展影响比较大的技术包括内核命名空间 (Kernel Namespace) 、控制组(Control Group) 、联合文件系统 (Union File System) ,当然更少不了Docker。由于容器技术的复杂性,阻碍了其大规模发展,而Docker技术的出现,使容器使用变的简单,促使了容器的普遍应用。

Docker简介

Docker是一种运行于Linux和Windows上的容器平台,用于创建、管理和编排容器。Docker是在GitHub上开发的Moby开源项目的一部分。 Docker公司,位于旧金山,是整个Moby开源项目的维护者。Docker公司还提供包含支持服务的商业版本的Docker。

Kubernetes作为容器编排领域的老大,已经采用Docker作为其默认容器运行时 (container runtime),包括Kubernetes启动和停止容器,以及镜像的拉取等。

Docker优势和劣势

优势

对于开发团队

1,部署简单易用,开发团队可以独立轻易的变更基础环境。 2,测试时的镜像环境就是最终产品运行的服务端环境,增加了测试可靠性。 3,一旦Docker镜像构建成功,我们就会在交付的各个阶段都是用这个镜像,这就提高了交付的可靠性。

对于运维团队

1,减少维护应用运行环境的工作量。环境是自动创建的,因此更少的人为操作是有必要的。 2,在多态服务器上手工搭建相同环境是很容易出错而且让人崩溃的。使用Docker的话就可以很轻松地创建一个环境的多个实例,因为我们最终只需要在服务端运行这个实例镜像。这种方式也可以很轻松将未来的多个节点添加到集群中进行水平扩展。 3,轻松更新现有的应用和环境。

对比puppet等自动化工具

1,当我们想要持续交付时,我们需要为交付的各个阶段创建大量的环境实例(提交阶段,验收阶段,容量测试,预生产和生产环境),使用物理机器来达到这个目的时不划算的。 2,安装应用和必要的基础设施变得相当简单,因为我们总是从一个空的image开始配置的,不容易出错。

对比虚拟机

1,启动一个Docker容器远比启动一个虚拟机快得多,因为不需要启动一个操作系统,较少了开销。 2,几个容器共享主机操作系统的内核,但是有自己的文件系统、用户、网络和进程。从主机操作系统角度来看,当我们运行Docker容器时,我们就是在运行另一个进程。这显著加速了容器的启动,同时仍然为各个容器提供了良好的隔离。 3,跨平台移植性好

劣势

1,容器技术本身比较复杂,比如容器管理、编排、应用打包、容器间的网络、数据快照等技术原理是复杂的。 2,同一个主机上跑的所有容器由于共用一个操作系统,例如kernel出现bug,则影响所有容器。 3,管理大量的容器比较麻烦,我们需要依赖kubernetes这种编排工具进行管理。

Docker适用场景

1,快速部署或者扩容 2,多租户管理 3,整合服务器资源,提高利用率 4,提供开发效率,开发测试部署环境完全一样 5,简化了配置。同一个Docker的配置可以在不通环境中使用,降低了硬件和应用环境之间的耦合性 6,完美支持CI/CD 7,无缝支持微服务架构

Docker核心技术点

Namespace命名空间

内核命名空间属于容器技术中的核心,该技术能够将操作系统进行拆分,使一个操作系统看起来像多个互相独立的操作系统一样。比如可以实现在相同的操作系统上运行多个Web服务,同时还不存在端口冲突的问题。该技术还允许多个应用运行在相同操作系统上并且不存在竞争,同时还能共享配置文件以及类库。

Linux Docker现在利用了下列内核命名空间:

进程ID(PID)

Docker使用PID命名空间为每个容器提供互相独立的容器树。每个容器都拥有自己的进程树,意味着每个容器都有自己的PID为1的进程。PID命名空间也意味着容器不能看到其他容器的进程树,或者其所在主机的进程树。

网络(NET)

Docker使用NET命名空间为每个容器提供互相隔离的网络栈。网络栈中包括接口、IP地址、端口地址以及路由表。例如:每个容器都有自己的eth0网络接口,并且有自己独立的IP和端口地址。

文件系统/挂载(MNT)

每个容器都有互相隔离的根目录/。这意味着每个容器都有自己的/etc 、/var 、/dev 等目录。容器内的进程不能访问Linux主机上的目录,或者其他容器的目录,只能访问自己 容器的独立挂载命名空间。

进程内通信(IPC)

IPC全称 Inter-Process Communication,是Unix/Linux下进程间通信的一种方式,IPC有共享内存、信号量、消息队列等方法。所以,为了隔离,我们也需要把IPC给隔离开来,这样,只有在同一个Namespace下的进程才能相互通信。Docker使用IPC命名空间在容器内提供共享内存,IPC 提供的共享内存在不同容器间也是互相独立的。

用户(USER)

Docker允许用户使用USER命名空间将容器内用户映射到Linux主机不同的用户上。常见的例子就是将容器内的root用户映射到Linux主机的非root用户上。用户命名空间对于Docker来说还属于新生事物且非必选项。该部分内容在未来可能出现改变。

UTS

UTS全称UNIX Time-sharing System,Docker使用UTS命名空间为每个容器提供自己的主机名称。

CGroup

CGroup用于限额。由于再Docker环境中,容器之间是互相隔离的,单却共享操作系统资源,可以通过CGroup限制单个容器的cpu,内存,存储io等资源的使用量。

Capability

Capability机制是在Linux内核2.2之后引入,它将root用户的权限细分为多个,可以分别启用或者禁用,例如:

CAP_CHOWN :允许用户修改文件所有权。 
CAP_NET_BIND_SERVICE :允许用户将socket绑定到系统端口号。 
CAP_SETUID :允许用户提升进程优先级。
CAP_SYS_BOOT :允许用户重启系统。

Docker采用Capability机制来实现用户在以root身份运行容器的同 时,还能移除非必须的root能力。

Docker存储驱动

数据主要分为两类:持久化和非持久化数据。持久化数据是需要保 存的,而非持久化数据不需要。默认情况下,所有容器都有与自身声明周期相同的非持久化存储——本地存储,它非常适用于非持久化数据。 但是,如果容器需要创建长期保存的数据,最好将数据存储到Docker卷中。

非持久化存储

非持久化存储就是容器的本地存储,每个容器启动都会自动分配本地存储,默认情况这里存放了全部文件和文件系统。容器使用镜像来运行,镜像包含了要运行的服务和需要的基础组件,镜像中的东西也要运行在容器本地存储中,而Docker镜像由一些松耦合的只读镜像层组成,所以本地存储使用的存储引擎需要能管理使用这些镜像层。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层,并保证多镜像层对外展示为统一的文件系统。Linux上可用的存储引擎有AUFS 、Overlay2 、Device Mapper 、Btrfs以及ZFS。

持久化存储

持久化存储的方式一般使用存储卷,用户创建卷,然后创建容器,接着将卷挂载到容器上。卷会挂载到容器文件系统的某个目录之下,任何写到该目录下的内容都会写到卷中。即使容器被删除,卷与其上面的数据仍然存在。

目前,Docker支持几十种卷插件,涵盖了块存储,文件存储,对象存储等。

Docker网络驱动

Docker网络架构源自一种叫作容器网络模型(CNM)的方案,该 方案是开源的并且支持插接式连接。Libnetwork是Docker对CNM的一种实现,提供了Docker核心网络架构的全部功能。不同的驱动可以通过插拔的方式接入Libnetwork来提供定制化的网络拓扑。

为了实现开箱即用的效果,Docker封装了一系列本地驱动,覆盖了 大部分常见的网络需求。其中包括单机桥接网络(Single-Host Bridge Network)、多机覆盖网络(Multi-Host Overlay),并且支持接入现有VLAN。Docker生态系统中的合作伙伴通过提供驱动的方式,进一步拓展了Docker的网络功能。

OCI

Open Container initiative(开放容器倡议)是一个旨在对容器基础架构中的基础组件进行标准化的管理委员会。

这个标准是怎么来的呢?由于CoreOS的公司不喜欢Docker的某些行事方式。因此它就创建了一个新的开源标准,称作“appc”,该标准涉及诸如镜像格式和容器运行时等方面。此外它还开发了一个名为rkt的实现,这让容器生态处于分裂的危险中。故在相关方沟通下,共同成立了OCI——一个旨在管理容器标准的轻量级的、敏捷型的委员会。OCI已经发布了两份规范,而Docker的运行时组件runc就是OCI容器运行时标准的参考实现。标准如下: 1,镜像规范:定义镜像的组织结构 the Runtime Specification (runtime-spec)[http://www.github.com/opencontainers/runtime-spec] 2,运行时规范:定义容器能接收的命令和对应的行为,例如容器的create,start,stop,delete等命令规范。 the Image Specification (image-spec)[http://www.github.com/opencontainers/image-spec]

OCI在Linux基金会的支持下运作,对容器生态规范化产生了极大作用,Docker公司和CoreOS公司都是主要贡献者。

其它容器技术

Rocket(rkt)

CoreOS的开源的容器运行平台,推出的目的主要是和Dockr做竞争,目前kubernetes内置了Docker和rtk两种容器运行时环境。Docker和Rocket目前都遵循OCI标准,Rocket在兼容性(例如rkt还支持AppC标准)和容器安全方面做的更好,其它安全使用便利行和社区活跃度方面Docker遥遥领先。

LXC

LXC (Linux Containters)是一种基于内核容器的用户空间接口,提供了一系列创建、配置、管理的接口,通过这些接口来简单管理容器。LXC出现远早于Docker,一般用于一些容器管理工具的底层实现,社区活跃度比较高。

Kubernetes

Kubernetes是Google的一个开源项目,并且开源之后迅速成为容器编 排领域的领头羊,使用Docker作为默认容器运行时。Kubernetes运行在数据中心硬件基础设施之上,对外暴露的是一个资源池,它让我们部署和运行组件应用的时候不用关注底层,实现了容器或者应用的自动调度,配置,管理和故障处理。

Mesos

Mesos是一个遵循Apache协议的开源项目,是一个集群管理工具,可以将整个数据中心的资源(包括CPU、内存、存储、网络等)进行抽象和调度,使得多个应用同时运行在集群中分享资源,并无需关心资源的物理分布情况。

Mesos是以与Linux内核同样的原则而创建的,不同点仅仅是在于抽象的层面。Mesos内核运行在每一个机器上,同时通过 API 为各种应用提供跨数据中心和云的资源管理调度能力。这些应用包括Hadoop、Spark、Kafka、Elastic Search,Cassandra等。还可配合框架Marathon来管理大规模的Docker等容器化应用。

主要有如下特性:

  • 支持数万个节点的大规模场景(Apple、Twitter、eBay 等公司实践);
  • 支持多种应用框架,包括 Marathon、Singularity、Aurora 等;
  • 支持 HA(基于 ZooKeeper 实现);
  • 支持 Docker、LXC 等容器;
  • 提供了多个流行语言的 API,包括 Python、Java、C++ 等;
  • 自带了简洁易用的 WebUI,方便用户直接进行操作。