Docker架构里那些名字背后的秘密

Docker作为一个linux平台上一款轻量级虚拟化容器的管理引擎。在短短的两三年内火得不得了。人人都在说docker,大大小小的容器summit。

Docker的前景被普遍看好。最近恰好在研究Docker。看了孙宏亮大牛的《Docker源码解析》更是很有感触。于是我就在想,可不可以写一个学习体会来做一个阶段性总结。我的想法就是如何从起名字的角度来阐释Docker架构的一些内部原理。曾经有一位大牛导师给我说过这样几句话:

你给每个类起的名字代表了你对这个实现逻辑的最高理解”。

原话不记得了。但大体意思就是这样,这句话也成了我后来判断一个人代码质量的重要依据。

先上一张Docker的架构图(该图取自孙宏亮《Docker源码分析》)

Docker架构图 (以下图片单击可见高清)

是歪的,借此机会活动下脖子。

Docker的总架构图就是这样。架构中主要有DockerClient、DockerDaemon、Docker Registry、Graph 、 Driver、libcontainer 以及Docker Container

Docker Client

首先我们来看看DockerClient。这个名字很显然。是一个客户端。这时候你是不是联想到了命令、浏览器等等。不说了。client表示好伤人。。。

Docker Daemon

Docker Daemon。Daemon是守护的意思。读“滴萌”。前面说了client。那么就可能会联想到这应该是一个server。没错这个就是一个server。但docker的大牛们为什么不叫DockerServer呢?是有原因的。因为Daemon中不仅仅有server,还有其他的。还有Engine。这个Engine中有很多的job。DockerDaemon内部所有的任务都是由Engine中的一个个Job来完成。

事实上DockerDaemon就做两件事情:

  • 接受并处理Docker Client发送的请求
  • 管理所有的docker容器

容器是个什么鬼后面会讲。

Docker Daemon 的架构主要有三部分:Docker Server、Engine 和 Job 。

Docker Server

是走的http协议。你就姑且就把它理解为httpserver。ok?什么handler了。路由表啦都是标配。就是你常用的类似servlet那套。

Engine

一看名字就是很重要是不是。作为一个轻量级容器。自然要做很多的事情。这些事情由谁来做呢。就是由Engine来做。因为Engine手底下管理着众多的Job。那这么多的job是怎么进行管理的呢?在docker源码中,有个叫handlers的对象。你可以认为是一个map的数据结构。举例来说,有其中一项为{“create”,daemon.ContainerCreate},就说明执行一个“create”的job的时候,执行的就是daemon.ContainerCreate这个handler。这个设计思路是不是和前面说的server类似。其实就是一个路由或者叫映射。英文一般叫route或者map之类的。engine做的比较有名的一件事情就是管理我们的容器。

Job

job你可以认为是docker中做事情的最小单元。每个action都是一个job。比如:在docker容器内部运行一个进程要创建一个job;创建一个容器,要创建一个job;在网络上下载一个文档,是一个job;创建一个server服务,这也是一个job。

有关job的接口设计与unix进程非常的像。比如说,job有自己名称、有运行时参数、有环境变量、有个标准输出,有标准错误以及返回状态等。

Job就像java中的runnable一样。runnable有run()。 Job也有自己的运行函数也叫Run()。

Docker Registry

现在来看Docker Registry。

这个就是一个仓库。用来存储image的仓库。既然是仓库。你可能就会想到maven等等。自然有公用仓库,私有仓库。其中大家熟知的Docker Hub,就是是全球最大的共有仓库。用户也可以构建自己的私有仓库。在国内,也有很多的容器厂商为我们构建了公有仓库,比如daocloud、caicloud等等。真是为我们提供了极大的便利啊。

Graph

先上一段英文:

modern word-forming element meaning "instrument for recording; that which writes, marks, or describes; something written," from Greek -graphos "-writing, -writer" (as in autographos "written with one's own hand"), from graphe "writing, the art of writing, a writing," from graphein "to write, express by written characters," earlier "to draw, represent by lines drawn" (see -graphy). Adopted widely (Dutch -graaf, German -graph, French -graphe, Spanish -grafo). Related: -grapher; -graphic; -graphical.

从上面对graph的解释以及词源挖掘。我们发现,graph类似一个画板。你可以在上面写写画画。在graph上有很多个元素。比如有很多点等等。

所以你就能理解docker作者的苦心了。在docker中,graph负责管理所有的image,也就是镜像。这些image,你可以任性的组装叠加来构建出新的镜像。就好像你在画板上画了一层又一层。画了一个鸟,又画了一个鸭。这些鸟和鸭就是一个个image。既然是image,就得存储啊。在docker中,支持多种image的存储方式。比如:aufs、devicemapper、Btrfs等等。

Driver

现在来看看driver。这个太明显了。既然是一个容器。自然会有驱动了。你是不是已经在想什么网络、存储等等了。没错,这个感觉就对了。

docker现在为我们提供了Execution Drivers、graphdriver、networkdriver。

这些驱动都是为容器的运行环境提供服务的。

Execution Drivers

先来看看这个Execution Drivers。在0.9发布以后,Solomon Hykes 兴致勃勃的在docker官网写了一文,在那里介绍了Execution Drivers:

以下是那天他说的一些话:

Fellow Dockers, Today we are happy to introduce Docker 0.9. ............blabla.................... First, we are introducing an execution driver API which can be used to customize the execution environment surrounding each container. This allows Docker to take advantage of the numerous isolation tools available, each with their particular tradeoffs and install base: OpenVZ, systemd-nspawn, libvirt-lxc, libvirt-sandbox, qemu/kvm, BSD Jails, Solaris Zones, and even good old chroot. This is in addition to LXC, which will continue to be available as a driver of its own. There are already several projects underway to develop more drivers. Want to join the fun? Come say hi on #docker-dev on Freenode, and we’ll help you get started.

大体就说自己很开心。说这个driver可以让docker利用多种隔离的工具。这个driver在当时是一个独立的子项目。在0.9之前是通过linux的lxc工具来管理容器的创建。现在我们可以使用这个driver来做这些事情。lxc我们还会继续支持。

与此同时我们还将会开发更多的driver。

你发现没?很多开发都是这样。一开始就用一些现成的。后来就自己开发一套,另起炉灶。好吧,继续。。。

networkdriver

比如接下来要介绍的networkdriver。

这个主要做的事情就是完成容器的网络环境的配置。比如docker daemon启动的时候创建网桥;以及容器创建的时候为容器分配网络接口资源;以及为容器分配ip、端口并和宿主机做nat端口影射;设置容器的防火墙等等。

graphdriver

对了,还有一个graphdriver。前面我们说了graph。说graph是容器镜像的管理者。那是不是需要开发个driver来把这些image存储起来呢?于是docker作者们就开发graphdriver来负责image的存储事宜。你现在不看源码都能想象到这个driver会干些什么事情。比如从本地存储目录get一个image,把一个image存到本地目录等等和image存储以及获取有关的事情。

在graphdriver初始化之前,已经有多种fs或者类fs的driver在docker daemon中严阵以待了。它们分别是aufs、btrfs、vfs、overlayFS和devmapper。其中前面四种都是可以用于image的管理的(后面那种是管理volume用的)。docker在初始化的时候,就会从系统环境变量“DOCKER_DRIVER”中获取指定的driver,之后就一直用这个driver来管理image了。比如配置的是overlayFS。

libcontainer

先来一张图:

上面介绍的那个execution driver把过去用的LXC driver扔到了边上。这个driver就是基于libcontainer之上的。libcontainer是一个纯粹的go语言包。我们的开发可以直接通过libcontainer来访问kernel的容器api,而不用其他任何依赖。

很感谢libcontianer。让我们可以开箱即用。不需要任何依赖。不用依赖什么LXC或者其他的底层的一些包,我们就可以使用namespaces,control groups,capabilities,apparmor profiles, network interfaces 以及 firewalling rules。而且libcontainer夹在中间还起到了解耦的作用。现在libcontainer已经是docker默认选择了。在0.9之后,LXC变为optional。只是一种可选。如果你想回到LXC driver,你只需要restart一下daemon就回到了熟悉而陈旧的过去,通过命令:docker -d -e lxc。虽然libcontainer已经被我们选为皇后。但LXC driver也没有被打入冷宫,在未来的版本中大牛们依然会翻她的牌子。

上面说到了libcontainer的解耦。这也是意味着底层可以不仅仅是linux,也可以是其他的平台。

Docker Container

最后来说说压轴的 Docker Container。container既然是一个包含某些东西的器皿,肯定会承载一些内容,比如image,你可以这样理解。docker最终是以容器的方式呈现给大家的。就像你运行一个tomcat,当然tomcat是另外一个层面的的cotainer。但container们都是大同小异的。这时候你也许会想到vm(虚拟机)。docker 的container长得和虚拟机很像。而且操作起来也和vm一样一样的,包括资源、环境都是和外界隔离的。

container运行了指定的image之后,就具备服务大家的能力了。比如运行个nginx,tomcat、redis等等。什么都可以。

至于container和image的关系。这二者之间的关系很紧密。image是静态的,

contianer是动态的。不多说了。你就记住只要是container都是要start的,要处于运行态的。容器中运行什么,就是image这个模板里的东西了。

总之

总之,

技术变化太快,也许在撸此文的时候,人家又升级了,比如又开发了一个新的 *driver或者 *graph或者lib*。

end了,有不对的地方指出来。

声明:文中涉嫌打广告的内容只是想向每一位努力的人致敬,别无他意。

原文发布于微信公众号 - ImportSource(importsource)

原文发表时间:2016-09-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏zhangdd.com

Docker简介

Docker是开源项目。Docker是基于Go语言实现的云开源项目,诞生于2013年初,最初发起者是dotCloud公司。Docker自开源后受到广泛的关注和讨...

1942
来自专栏美团技术团队

美团点评Docker容器管理平台

本文介绍美团点评的Docker容器集群管理平台(以下简称“容器平台”)。该平台始于2015年,是基于美团云的基础架构和组件而开发的Docker容器集群管理平台。...

4747
来自专栏云计算

随时随地部署Kubernetes

Kubernetes 可以部署和管理您的容器化应用程序,其中包括 NGINX,MySQL,Apache 等等。

4578
来自专栏北京马哥教育

如何理解LXC与Docker之间的主要区别

这篇文章从两个部分来探讨LXC,LXC和Docker的容器托管,以及轻便的容器技术将取代虚拟技术的可能性。 LXC有可能会改变我们如何运行和缩放应用程序。Dr...

8066
来自专栏达摩兵的技术空间

docker入门学习(1)

1、简化程序: Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,便可以实现虚拟化。Docke...

1072
来自专栏算法修养

Docker 学习应用篇之一: 初识Docker

    Docker 自从2013年以来就非常的火热,无论是从github上的代码活跃度,还是Redhat在RHE6.5中集成对Docker的支持,等等。第一次...

43610
来自专栏技术翻译

Kubernetes vs. Docker Swarm:完整的比较指南

有无数的辩论和讨论谈论Kubernetes和Docker。如果你没有深入研究,你会认为这两种开源技术都在争夺集装箱至上。让我们明确指出,Kubernetes和D...

5.9K4
来自专栏大魏分享(微信公众号:david-share)

容器生产落地需要考虑的几点因素

前言: 本文是笔者与同事陈耿共同完成,不代表任何官方观点。 随着容器技术的持续发酵,以及互联网+应用的持续扩张,目前金融行业使用容器云上生产的案例越来越多。在本...

3594
来自专栏PaddlePaddle

PaddlePaddle发布基于Docker的AI系统开发流程

继两周前(2017年3月11日)PaddlePaddle社区发布新的PythonAPI之后,最近又发布了对应的新版Docker镜像,并优化了镜像的体积和组织方式...

38311
来自专栏人称T客

Docker容器服务需要牢记的五个问题|资讯

关键词:Docker,容器服务 ? 进入2015年,容器技术突然开始变得炙手可热,特别是随着Docker的出现,更是将容器技术推向了顶峰,甚至让人有一种错觉—...

2905

扫码关注云+社区

领取腾讯云代金券