您好,欢迎访问三七文档
容器化技术与Docker杜浩宇2020.6从操作系统说起关键词:内核Shell内核空间用户空间ABIAPI系统调用接口为什么要有容器?•麻烦的环境配置•开发和运行环境存在差异•以前的应用程序:•几乎都是单块应用:大系统,多模块•紧耦合:内部调用•不常变更:需求稳定(改动成本高)•如今的应用程序:•解耦:微服务/异步•经常变更:快速迭代•动态创建和部署:服务化•新架构的挑战•多样化的技术栈•需要动态创建机器•很多活动组件•运维人员需要管理复杂的架构为什么要有容器?容器是什么?密封的便携的可移植的持续运行“容器”是一个黑盒,对于它的使用者来说:•无需关心里面有什么:只关注“容器”能做什么•有一套工具来管理黑盒:打包、运输、运行•减少了部署单元的数量,从而减少了花销:多个工具聚集在一个“容器”内•更容易管理多个环境:以“容器”为单位进行部署和管理容器的核心技术容器核心技术——NamespaceNamespace命名空间Linux的命名空间机制提供了以下6种不同的命名空间,包括CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWPID、CLONE_NEWUSER、CLONE_NEWUTS,通过这6个选项我们能在创建新的进程时设置新进程应该在哪些资源上与宿主机器进行隔离。因此容器只能感知内部的进程,而对宿主机和其他容器一无所知。这6项资源隔离分别对应6种系统调用,通过传入上表中的参数,调用clone()函数来完成。容器核心技术——ControlGroups每一个CGroup都是一组被相同的标准和参数限制的进程,不同的CGroup之间是有层级关系的,也就是说它们之间可以从父类继承一些用于限制资源使用的标准和参数。可限制进程组使用的资源(Resourcelimiting):比如memory子系统可以为进程组设定一个memory使用上限,进程组使用的内存达到限额再申请内存,就会触发OOM(outofmemory)(outofmemory)进程组的优先级控制(Prioritization):比如可以使用cpu子系统为某个进程组分配cpushare记录进程组使用的资源量(Accounting):比如使用cpuacct子系统记录某个进程组使用的cpu时间进程组隔离(Isolation):比如使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间进程组控制(Control):比如使用freezer子系统可以将进程组挂起和恢复容器核心技术——UnionFSUnionFS是一种为Linux操作系统设计的用于把多个文件系统『联合』到同一个挂载点的文件系统服务。AUFS作为联合文件系统,它能够将不同文件夹中的层联合(Union)到了同一个文件夹中,这些文件夹在AUFS中称作分支,整个『联合』的过程被称为联合挂载(UnionMount)每一个镜像层或者容器层都是/var/lib/docker/目录下的一个子文件夹;在Docker中,所有镜像层和容器层的内容都存储在/var/lib/docker/aufs/diff/目录中而/var/lib/docker/aufs/layers/中存储着镜像层的元数据,每一个文件都保存着镜像层的元数据,最后的/var/lib/docker/aufs/mnt/包含镜像或者容器层的挂载点,最终会被Docker通过联合的方式进行组装。虚拟化技术与容器技术Whatisdocker?Whyisdocker?Docker架构DockerClient:接收命令和DockerHost进行交互的客户端DockerHost:运行Docker服务的主机DockerDaemon:守护进程,用于管理所有镜像和容器DockerImages/Containers:镜像和容器实例Registry(Hub):镜像仓库用户是使用DockerClient与DockerDaemon建立通信,并发送请求给后者。DockerDaemon作为Docker架构中的主体部分,首先提供DockerServer的功能使其可以接受DockerClient的请求。DockerEngine执行Docker内部的一系列工作,每一项工作都是以一个Job的形式的存在。Job的运行过程中,当需要容器镜像时,则从DockerRegistry中下载镜像,并通过镜像管理驱动Graphdriver将下载镜像以Graph的形式存储。当需要为Docker创建网络环境时,通过网络管理驱动Networkdriver创建并配置Docker容器网络环境。当需要限制Docker容器运行资源或执行用户指令等操作时,则通过Execdriver来完成。Libcontainer是一项独立的容器管理包,Networkdriver以及Execdriver都是通过Libcontainer来实现具体对容器进行的操作。Docker模块组件——DockerDaemonDockerClient是和DockerDaemon建立通信的客户端。用户使用的可执行文件为docker,docker命令使用后接参数的形式来实现一个完整的请求命令(例如:dockerimages,docker为命令不可变,images为参数可变)。DockerClient可以通过以下三种方式和DockerDaemon建立通信:tcp://host:port、unix://pathtosocket和fd://socketfdDockerClient发送容器管理请求后,由DockerDaemon接受并处理请求,当DockerClient接收到返回的请求相应并简单处理后,DockerClient一次完整的生命周期就结束了。(一次完整的请求:发送请求→处理请求→返回结果),与传统的C/S架构请求流程并无不同。Docker模块组件——DockerEngine&JobDockerEngine是Docker架构中的运行引擎,同时也是Docker运行的核心模块。它扮演DockerContainer存储仓库的角色,并且通过执行Job的方式来操纵管理这些容器。在DockerEngine数据结构的设计与实现过程中,有一个Handler对象。该Handler对象存储的都是关于众多特定Job的Handler处理访问。比如说:DockerEngine的Handler对象中有一项为:{“create”:daemon.ContainerCreate,},则说明当名为“create”的Job在运行时,执行的是daemon.ContainerCreate的Handler。一个Job可以认为是Docker架构中DockerEngine内部最基本的工作执行单元。Docker可以做的每一项工作,都可以抽象为一个Job。例如:在容器内部运行一个进程,这是一个Job;创建一个新的容器,这是一个Job。DockerServer的运行过程也是一个Job,名为ServeApi。Job的设计者,把Job设计得与Unix进程相仿。比如说:Job有一个名称、有参数、有环境变量、有标准的输入输出、有错误处理,有返回状态等。Docker模块组件——GraphRepository已下载镜像的保管者(包括下载的镜像和通过Dockerfile构建的镜像)。一个Repository表示某类镜像的仓库(例如:Ubuntu),同一个Repository内的镜像用Tag来区分(表示同一类镜像的不同标签或版本)。一个Registry包含多个Repository,一个Repository包含同类型的多个Image。镜像的存储类型有Aufs、Devicemapper、Btrfs、Vfs等。其中CentOS系统7.x以下版本使用Devicemapper的存储类型。同时在Graph的本地目录中存储有关于每一个的容器镜像具体信息,包含有:该容器镜像的元数据、容器镜像的大小信息、以及该容器镜像所代表的具体rootfs。GraphDB已下载容器镜像之间关系的记录者。GraphDB是一个构建在SQLite之上的小型数据库,实现了节点的命名以及节点之间关联关系的记录。Docker模块组件——GraphdriverDriver是Docker架构中的驱动模块。通过Driver驱动,Docker可以实现对Docker容器执行环境的定制。即Graph负责镜像的存储,Driver负责容器的执行。Graphdriver主要用于完成容器镜像的管理,包括存储与获取。存储:dockerpull下载的镜像由Graphdriver存储到本地的指定目录(Graph中)。获取:dockerrun(create)用镜像来创建容器的时候由Graphdriver到本地Graph中获取镜像。Docker模块组件——NetworkdriverNetworkdriver的用途是完成Docker容器网络环境的配置,其中包括:Docker启动时为Docker环境创建网桥。Docker容器创建时为其创建专属虚拟网卡设备。Docker容器分配IP、端口并与宿主机做端口映射,设置容器防火墙策略等。Docker网络模型——Bridge网桥模式Docker提供四种网络模式,Host、Container、None和Bridge模式,默认模式为Bridge。在Bridge模式下,除了分配隔离的网络命名空间之外,Docker还会为所有的容器设置IP地址。当Docker服务器在主机上启动之后会创建新的虚拟网桥docker0,随后在该主机上启动的全部服务在默认情况下都与该网桥相连。每一个容器在创建时都会创建一对虚拟网卡,两个虚拟网卡组成了数据的通道,其中一个会放在创建的容器中,另一个会加入到名为docker0网桥中。docker0会为每一个容器分配一个新的IP地址并将docker0的IP地址设置为默认的网关。网桥docker0通过iptables中的配置与宿主机器上的网卡相连,所有符合条件的请求都会通过iptables转发到docker0并由网桥分发给对应的机器。当有Docker的容器需要将服务暴露给宿主机器,就会为容器分配一个IP地址,同时向iptables中追加一条新的规则。容器使用IP(宿主机)+端口映射的方式完成对外服务暴露。Docker模块组件——ExecdriverExecdriver作为Docker容器的执行驱动,负责创建容器运行命名空间、容器资源使用的统计与限制、容器内部进程的真正运行等。(其实就是runtime所在)现在Execdriver默认使用Native驱动,不依赖于LXC。Docker模块组件——LibcontainerLibcontainer是Docker架构中一个使用Go语言设计实现的库,设计初衷是希望该库可以不依靠任何依赖,直接访问内核中与容器相关的API。Docker可以直接调用Libcontainer来操纵容器的Namespace、Cgroups、Apparmor、网络设备以及防火墙规则等。Libcontainer提供了一整套标准的接口来满足上层对容器管理的需求。或者说Libcontainer屏蔽了Docker上层对容器的直接管理。Docker模块组件——DockerContainerDockerContainer(Docker容器)是Docker架构中服务交付的最终体现形式。Docker按照用户的需求与指令,订制相应的Docker容器:用户通过指定容器镜像,使得Docker容器可以自定义rootfs等文件系统。用户通过指定计算资源的配额,使得Docker容器使用指定的计算资源。用户通过配置网络及其安全策略,使得Docker容器拥有独立且安全的网络环境。用户通过指定运行的命令,使得Docker容器执行指定的工作。Docker的使用Docker的全生命周期管理
本文标题:容器技术详解
链接地址:https://www.777doc.com/doc-6962255 .html