前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >docker核心原理

docker核心原理

作者头像
一夕如环
发布2019-02-13 09:51:30
8560
发布2019-02-13 09:51:30
举报
  • 容器概念。

docker是一种容器,应用沙箱机制实现虚拟化。能在一台宿主机里面独立多个虚拟环境,互不影响。在这个容器里面可以运行着我饿们的业务,输入输出。可以和宿主机交互。

  • 使用方法。
  1. 拉取镜像 默认是从官网的docker仓库上面获取,其中pull的命令是拉取,与之对应的是push命令,日后有能力自己创建镜像并且上传到docker仓库的时候用到。registry是镜像名,docker官方维护有很多基础镜像,可以直接下载来用。同时在公共仓库也有很多共享的镜像,自己可以视情况来下载使用。
代码语言:javascript
复制
docker pull registry
  1. 启动容器 docker run -d -p 5000:5000 --name registry registry 第一步把镜像下载到本地,现在可以在镜像的基础上启动容器。run命令就是启动的意思,后面可以加一下附属参数。命令中-d就是daemon的意思,以守护进程方式运行。--name就是制定容器的名字,方便日后管理,不然每次都要使用容器的ID,12位16进制数。后面就是我们的镜像名。容器启动后就会返回一串数字,作为sha256,这一串是我们的长ID。长ID和短ID的区别如下:

一般操作使用短ID,下面说到的文件目录用长ID标记。

  1. 这是最基本的用法。
  • 核心原理。
  1. 这是用方式不是一个镜像一台提供不同服务的虚拟机吗?
    1. 应用不同,这是两个完全不一样的产品。docker可以快速部署相同的和不同的环境,虚拟机只是节省资源,在同一台宿主机安装多个系统。
    2. 容器是共用镜像,独立的服务,属于云计算中的paas服务,在统一的基础环境延伸。虚拟机提供的是iaas,从底层开始。
    3. docker的实现方法是共享和隔离。虚拟机的只是虚拟硬件,虚拟机间没有共享成分。
  2. 容器的实现原理很炫吗?
    1. 它是通过利用内核自带的namespace和cgroup功能隔离系统必须的六个模块,以完成一个独立的系统环境。用namespace隔离一个小空间,UTS、IPC、PID、Network、mount、User六个环境的新隔离,用cgroup作为系统资源的控制。
    2. UTC实现主机名和域名的隔离,使容器有独立的主机名;IPC隔离信号量和消息队列,使之有独立的工作通讯;Network隔离网络,使之有独立的网络设备;mount隔离文件系统,使之有独立的存储;PID隔离进程号,使之有独立的进程编排。运行起来就像一个独立的计算机环境。
  3. 除了文件,其他一些隔离都可以调用接口实现。每个容器里面有整个系统的文件,而且都是一秒钟生成。就很难理解了。
代码语言:javascript
复制
docker exec -it smokeping bash

    上面说了,容器操作的时候,用名字就不用每次都找ID。exec命令是发送命令给容器执行,-i是使用交互模式保持输入流的开放,-t是创建虚拟终端,smokeping是指定的容器名,bash是容器要执行的命令。我们看看容器的这些文件存放在宿主机的什么地方  。

  • 运行目录。
  1. 容器是虚拟的,文件总不能也是虚拟的。查找了相关资料发现全部都是保存在docker容器的运行目录。/var/lib/docker
  2. 看了一下,还真有。
  1. 为了能看到文件的变化,我们把docker的运行目录都删掉了。 重启docker daemon,一切都是新的。
代码语言:javascript
复制
rm -rf /var/lib/docker
  1. Docker运行目录的变化
    1. 拉取第一个镜像开始,/var/lib/docker开始建立,包含了下下目录。
      1. 删除镜像。
      1. 展开目录。
        1. 全部目录为空,打开image/aufs/repositories.json的记录文件也为空。
    2. 重新拉取镜像,再展开对比
      1. Aufs目录下的三个文件夹的首层子目录或者文件名都是各层ID。
        1. diff目录保存着只读层和可读写层的数据。每层只保存历史当次读写。
        1. Layer目录下的文件名和diff子目录名一一对应,里面的内容是层依赖。
        1. Mnt目录下的子目录名和iff子目录名一一对应,里面的内容暂时为空。
      2. Container的目录为空。
      3. Image目录下的distribution、imagedb、layerdb。
        1. Distribution下的diffid-by-digest和v2metadata-by-diffid都有sha256。
        1. Imagedb就只有一个sha256。这个正是image的ID。
        1. Layerdb的sha256下面也有同数量子目录。每个目录里面有相同名字的配置文件。
        1. repositories.json记录的也是镜像的sha256。
      4. Network文件夹为空,本来是用来存放容器内网络相关文件。
      5. Volumes文件夹为空,是存放容器里面挂载的目录,有真实可读写的文件。
      6. 小结:在上面“使用方法”演示的“docker pull”过程中,docker下载的镜像文件全部分层保存在aufs目录下的diff目录,目录名是sha256,和层ID无关。
    3. 启动容器时的目录变化。
      1. 生成容器的ID:
        1.   bc893c0031db98114a48ebb924cf5d0b9b2c77968839696e735528648a1a531b
      2. aufs的三个目录。
        1. Diff没有变化,但是多了一层把diff的内容都挂载上去。
        1. Layer增加了一个目录,目录文件是个别层实现可读写。
        1. Mnt中前面的目录没变,但是多了一层把diff的内容都挂载上去。
      3. Container的目录不再为空,首先是以容器ID为目录名新建了个目录。然后在目录下存放hostname、hosts等配置文件。
      1. Image目录完全没有改动。
      2. Network文件夹为空,本来是用来存放容器内网络相关文件。
      3. Volumes下面出现了容器定义挂载的数据文件。此数据文件在mnt目录没有挂载。
      4. 小结:在上面“使用方法”演示的“docker run”过程中,aufs下的diff和mnt目录,自动生成两个目录,名为sha256的一串数字ID,另一个是ID-init。diff下也是这两个目录,此ID是在diff是最新一层,在mnt中是当前容器所有文件;aufs/mnt/ID的文件由diff下的镜像目录通过aufs系统整合挂载而来,aufs系统是实现多目录挂载在同一个目录的工具。aufs/mnt/ID-init目录为空;aufs/diff/ID下保存的是最新一层也就是当前可读写文件,aufs/diff/ID-init是最新一层也就是当前的只读文件hostname、host等。一句话,数据都是储存在diff,mnt是打酱油的。过程就是aufs整合镜像存放在diff下的内容,一起挂载在aufs/mnt/ID下,连最新一层aufs/diff/ID(有几个可读写文件)和aufs/diff/ID-init(只有只读文件)都挂载上去。
    4. 运行目录生成文件时的变化。
      1. 在root目录touch ken.txt
        1. 其他目录都没有变化。
        2. aufs下的diff和mnt的那个容器新生成的ID目录下随地生成了ken.txt文件,应该是数据库文件记录了此文件在容器中的位置。
        1. Mnt目录和diff的关系。
        1. Mnt目录是被挂载。
      2. 在root目录mv rc.local rc.loca
        1. 其他目录没有变化。
        2. aufs下的diff的那个容器新生成的ID目录下etc中生成rc.loca文件。
        1. diff下镜像层的文件没改。
        1. 修改的文件存在于diff和mnt中。
      3. 新增的文件直接放在aufs/diff/e36b1bd8e430d4731211af3984aed0fd3fa6fa62c57f5c877a013856ba32abc4目录这里,修改的文件连带目录生成到这里。
      1. 小结:容器启动之后,新建目录ID,和ID-init目录;容器需要更改的文件从镜像文件复制到diff下的ID目录,经过容器的操作,ID目录就拥有了最新的变更,ID-init是亘古不变的只读文件;新增文件出现在新建层级diff的ID的储存方式是直接随地放在根目录下,修改文件出现在新建层级diff的ID的储存方式是连带目录首先复制到diff的新建层级,然后修改。最终挂载到aufs/mnt/ID展示在容器内的正确位置。
    5. 运行目录在停止容器后的变化。
      1. Aufs目录下的三个文件夹。
        1. Diff完全没有变化,说明一旦容器停止的时候,容器必须的配置文件时复制的。
        2. Layer文件完全没有变化。
        3. Mnt那个新建作为挂载diff各层文件的目录为空,说明已经卸载。
      2. Images目录不变。
      3. Container目录不变,保留着diff时刻准备着的文件。
      4. 小结:容器停止后,在mnt上面的挂载马上卸掉,但是目录不变。而在diff上面的文件状态保持不变,期待下次容器启动的时候一次挂载到mnt下面。
    6. 运行目录在删除容器的变化。
      1. Aufs目录下的三个子目录。
        1. Diff在容器启动时所生成的那个ID的文件夹消失。
        2. Layer在容器启动时所生成的那个带ID的文件夹消失。
        1. Mnt在容器启动时所生成的那个ID的文件夹消失.
      2. Container目录下容器启动时所生成的那个ID的文件夹消失。
      3. Volumes目录下的文件存活下来。
    7. 小结:当容器删除,镜像文件不变,其他全部删除。如果有定义volume的,会有所保留。
  2. 总结:容器在宿主机上运行,无非是围绕只读层和可读写,利用复制和挂载,灵活操作;来得快的文件时通过挂载,如果在只读层无法修改文件就可以先复制出来再说;整个过程就是,容器一启动,diff就新建可读写的新ID目录和ID-init目录,ID-init目录一开始就加载了只读文件。然后和其他各层数据挂在mnt的分别挂在ID一一对应的mnt下,aufs系统把全部数据整合嫁接到mnt的新ID下。此时mnt中其他的目录为空,新ID拥有容器的全部数据。当容器产生动态数据,就作用于那个可读写并且挂在mnt新ID下的diff新ID文件夹。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-11-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档