Docker基础

零、什么是容器?

在介绍容器的具体概念之前,先简单回顾一下操作系统是如何管理进程的。

首先,当我们登录到操作系统之后,可以通过 ps 等操作看到各式各样的进程,这些进程包括系统自带的服务和用户的应用进程。那么,这些进程都有什么样的特点?1)这些进程可以相互看到、相互通信;2)它们使用的是同一个文件系统,可以对同一个文件进行读写操作;3)这些进程会使用相同的系统资源。

这样的三个特点会带来什么问题呢?1)因为这些进程能够相互看到并且进行通信,高级权限的进程可以攻击其他进程;2)因为它们使用的是同一个文件系统,因此会带来两个问题:这些进程可以对于已有的数据进行增删改查,具有高级权限的进程可能会将其他进程的数据删除掉,破坏掉其他进程的正常运行;此外,进程与进程之间的依赖可能会存在冲突,如此一来就会给运维带来很大的压力;3)因为这些进程使用的是同一个宿主机的资源,应用之间可能会存在资源抢占的问题,当一个应用需要消耗大量 CPU 和内存资源的时候,就可能会破坏其他应用的运行,导致其他应用无法正常地提供服务。

针对上述的三个问题,如何为进程提供一个独立的运行环境呢?1)针对不同进程使用同一个文件系统所造成的问题而言,Linux 和 Unix 操作系统可以通过 chroot 系统调用将子目录变成根目录,达到视图级别的隔离;进程在 chroot 的帮助下可以具有独立的文件系统,对于这样的文件系统进行增删改查不会影响到其他进程;2)因为进程之间相互可见并且可以相互通信,使用 Namespace 技术来实现进程在资源的视图上进行隔离。在 chroot 和 Namespace 的帮助下,进程就能够运行在一个独立的环境下了;3)但在独立的环境下,进程所使用的还是同一个操作系统的资源,一些进程可能会侵蚀掉整个系统的资源。为了减少进程彼此之间的影响,可以通过 Cgroup 来限制其资源使用率,设置其能够使用的 CPU 以及内存量。

部署需要的原材料:

1)服务器;2)操作系统;3)JDK/JVM;4)代码Jar包、配置、依赖等。部署需要考虑的事情:1)部署后检查是否可用

Docker鲸鱼

理解Docker从看图开始,鲸鱼🐳是一台安装了操作系统的服务器,每个集装箱里装的是部署的应用程序。因此Docker的核心是容器(集装箱)、标准化(大小一样的集装箱)、隔离。

docker是一个开源的应用容器引擎,使用go语言编写;Docker以容器的形式把代码、依赖、配置文件、环境变量打包在一起,部署到不同环境时只需从Docker仓库下载镜像并运行,以确保应用在开发、测试、生产环境中无差别运行,提高上线的成功率。Docker有社区版和商业版。

一、为什么使用Docker?

Docker实现了隔离,相比虚拟机有什么好处?Docker容器运行在操作系统之上,而虚拟机是包含操作系统的,Docker更轻量。

docker本质就是宿主机的一个进程,容器之间共享内核;通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)。发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问其自己的命名空间中的资源。而Cgroups不允许容器消耗比分配给它们更多的资源。

Docker对操作系统的侵入性很低,使用LXC(linux container)虚拟化技术(Linux内核从2.6.24开始支持),无需安装额外的软件就可运行。也就是说setup一台机器只需要安装Linux操作系统和Docker。

二、核心概念

1)容器:指的是在一个服务器上运行多个应用,各个应用通过容器实现隔离。Docker容器包括应用程序及其依赖项,与其他容器共享内核,作为主机操作系统上用户空间中的独立进程运行。Docker容器可以有四种状态:运行、已暂停、重新启动、已退出。可以通过docker ps -a来识别Docker容器状态。

2)镜像:我们将这些容器运行时所需要的所有的文件集合称之为容器镜像。Docker镜像是Docker容器的源代码;容器是镜像的运行时。通常情况下,我们会采用 Dockerfile 来构建镜像,这是因为 Dockerfile 提供了非常便利的语法糖,能够帮助我们很好地描述构建的每个步骤。当然,每个构建步骤都会对已有的文件系统进行操作,这样就会带来文件系统内容的变化,我们将这些变化称之为 changeset。使用build命令创建映像,并且在使用run启动时它们将生成容器。镜像存储在Docker registry;可设计分层镜像,从而在通过网络传输镜像时发送最少量的数据。

3)Dockerfile:为了降低升级和维护的成本,可将构建Jenkins容器的所有操作写入Dockerfile并用版本工具管理。Dockerfile中的一些常用指令:(1)FROM:为后续指令设置基本镜像。在每个有效的Dockerfile中,FROM是第一条指令。(2)LABEL:按照项目、模块、许可等组织我们的镜像。我们也可以使用LABEL来帮助实现自动化。在LABEL中,我们指定一个键值对,以后可用于以编程方式处理Dockerfile。(3)RUN:我们使用RUN命令在当前镜像之上的新图层中执行任何指令。使用每个RUN命令,我们在镜像顶部添加一些内容,并在Dockerfile的后续步骤中使用它。(4)CMD:提供执行容器的默认值。在Dockerfile中,如果我们包含多个CMD命令,则只使用最后一条指令。

4)层:Docker镜像是由一系列只读层构建的;每个层代表镜像Dockerfile中的一条指令。

5)Docker Registry和Docker Hub:docker registry的常用操作是push、pull、search;可以构建企业私有的registry;最大的公有registry是docker hub。

三、Docker使用流程

1)一切都从Dockerfile开始。Dockerfile是镜像的源代码。2)创建Dockerfile后,可以构建它以创建容器的镜像。3)获得容器的镜像后,上传到注册表。注册表就像一个git存储库 - 你可以推送和拉取镜像。4)使用该镜像来运行容器。

四、Docker命令

1)docker run -d -p 9090:8080 ——name jenkins jenkins:1.576

2)docker build -t jenkins:1.578 —rm .

3)Docker volume功能进行外部目录挂载,达到不在容器中放置任何项目数据的目的。

4)docker pull<imageName>

5)docker images:查看已下载镜像

6)docker  save nginx >/tmp/nginx.tar.gz:导出镜像;docker load导入镜像

7)配置文件:docker.service

8)docker ps:查看容器id(container id)、image(镜像名称)、cmd、created

五、镜像分层

Docker本身提供了多种途径分享容器,例如:通过export/import或者save/load命令以文件的形式分享,也可以通过将容器提交至私有Registry进行分享。

当镜像用作另一个镜像构建的基础时,ONBUILD指令向镜像添加将在稍后执行的触发指令。如果要构建将用作构建其他镜像的基础的镜像(例如,可以使用特定于用户的配置自定义的应用程序构建环境或守护程序),这将非常有用。

很多企业内部都存在一套叫做标准化的规范,定义开发语言、工具版本等信息;从而达到统一开发环境并降低运维团队负担的目的。依据标准化规范,可以创建一系列容器并按照职能进行分组。

分层后, 由于上层镜像已经提供了应用所需要的全部软件和服务,因此可以显著加快应用层镜像构建的速度。

在Dockerfile中使用FROM命令可以帮助构建分层镜像。

定义base镜像
基于base镜像定义java服务镜像,类SaaS
基于java镜像定义jboss镜像

六、Docker架构

6.1 总体过程

用户是使用Docker Client与Docker Daemon建立通信,并发送请求给后者。Docker Daemon作为Docker架构中的主体部分,首先提供Server的功能使其可以接受Docker Client的请求;而后Engine执行Docker内部的一系列工作,每一项工作都是以一个Job的形式的存在。Job的运行过程中,当需要容器镜像时,则从Docker Registry中下载,并通过镜像管理驱动graphdriver将下载镜像以Graph的形式存储;当需要为Docker创建网络环境时,通过网络管理驱动networkdriver创建并配置Docker容器网络环境;当需要限制Docker容器运行资源或执行用户指令等操作时,则通过execdriver来完成。而libcontainer是一项独立的容器管理包,networkdriver以及execdriver都是通过libcontainer来实现具体对容器进行的操作。当执行完运行容器的命令后,一个实际的Docker容器就处于运行状态,该容器拥有独立的文件系统,独立并且安全的运行环境等。

6.2 docker client

docker client 是docker架构中用户用来和docker daemon建立通信的客户端,用户使用的可执行文件为docker,通过docker命令行工具可以发起容器管理请求。

docker client可以通过以下三种方式和docker daemon建立通信tcp://、host:port、unix:path_to_socket、fd://socketfd。docker client可以通过设置命令行flag参数的形式设置安全传输层协议(TLS)的有关参数,保证传输的安全性。

docker client发送容器管理请求后,由docker daemon接受并处理请求,当docker client接收到返回的应答后,docker client 一次完整的生命周期就结束了,当需要继续发送容器管理请求时,用户必须再次通过docker可以执行文件创建docker client。

6.3 docker daemon

docker daemon 是docker架构中一个常驻在后台的系统进程,功能是:接收处理docker client发送的请求。该守护进程在后台启动一个server,server负载接受docker client发送的请求;接受请求后,server通过路由与分发调度,找到相应的handler来执行请求。

docker daemon的架构可以分为:1)docker server:接受来自docker client的请求,路由到对应的handler。2)Engine:Docker架构中的运行引擎,也是Docker运行的核心模块。通过执行job的方式来操纵管理这些容器。handler对象存储job和对应的handler。例如Engine的handler对象中的{“create”: daemon.ContainerCreate},代表当名为”create”的job在运行时,执行的是daemon.ContainerCreate的handler。3)Job:Job是Engine内部最基本的工作单元。Docker可以做的每一项工作,都可以抽象为一个job。例如:在容器内部运行一个进程,这是一个job;创建一个新的容器,这是一个job,从Internet上下载一个文档,这是一个job;包括之前在Docker Server部分说过的,创建Server服务于HTTP的API,这也是一个job。Job的设计者把Job设计得与Unix进程相仿,有名称、参数、有环境变量、标准输入输出、错误处理、返回状态等。

6.4 Graph

Graph在Docker架构中扮演已下载容器镜像的保管者,以及已下载容器镜像之间关系的记录者。一方面,Graph存储着本地具有版本信息的文件系统镜像,另一方面也通过GraphDB记录着所有文件系统镜像彼此之间的关系。

其中,GraphDB是一个构建在SQLite之上的小型图数据库,实现了节点的命名以及节点之间关联关系的记录。同时在Graph的本地目录中,关于每一个的容器镜像,具体存储的信息有:该容器镜像的元数据,容器镜像的大小信息,以及该容器镜像所代表的具体rootfs。

6.5 Driver

Driver是Docker架构中的驱动模块。通过Driver驱动,Docker可以对容器执行环境的定制。由于Docker的生命周期中,用户操作分为容器管理和其他操作,如获取Docker运行信息、Graph的存储与记录等。因此,为了将容器管理从Docker Daemon内部业务逻辑中区分开来,设计了Driver层驱动来接管这部分请求。

Driver分为三类:

1)graphdriver:用于容器镜像的管理,包括存储与获取。当用户需要下载指定的容器镜像时,graphdriver将镜像存储在本地;当用户需要使用指定的镜像来创建容器的rootfs时,graphdriver从本地目录中获取镜像。graphdriver在初始化之前,支持4种文件系统:aufs、btrfs、vfs、devmapper;初始化时,通过环境变量”DOCKER_DRIVER”指定类型。

2)networkdriver:负责Docker容器网络环境的配置,包括Docker启动时为创建网桥、容器创建时创建专属虚拟网卡设备、以及为容器分配IP、端口并与宿主机做端口映射、设置容器防火墙策略等。

3)execdriver:作为Docker容器的执行驱动,负责创建容器运行命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。旧版Docker使用LXC驱动调用LXC接口来操纵容器的配置及生命周期,而现在execdriver默认使用native驱动。具体体现在Daemon启动过程中加载的ExecDriverflag参数,该参数在配置文件已经被设为”native”。

6.6 LibContainer

libcontainer是一个Go这种跨平台的语言实现的库,提供了一整套标准的接口来满足上层对容器管理的需求;屏蔽了Docker上层对容器的直接管理,实现解耦合。设计初衷是希望该库不依靠任何依赖,直接访问内核中与容器相关的API。Docker可以直接调用libcontainer来操纵容器的namespace、cgroups、apparmor、网络设备以及防火墙规则等。这一系列操作的完成都不需要依赖LXC或者其他包。

6.7 docker container

Docker容器是Docker架构中服务交付的最终体现形式。Docker按照用户的需求与指令,定制相应的Docker容器:1)用户通过指定容器镜像,使得Docker容器可以自定义rootfs等文件系统;2)用户通过指定计算资源的配额,使得Docker容器使用指定的计算资源;3)用户通过配置网络及其安全策略,使得Docker容器拥有独立且安全的网络环境;4)用户通过指定运行的命令,使得Docker容器执行指定的工作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容