• docker 9 :镜像存储机制


    一、Linux 系统运行基础

    Linux 系统正常运行, 通常需要两个文件系统:

        1、boot file system (bootfs)
      1、 包含 Boot Loader与Kernel文件,用户不能修改这些文件。并且在系统启动过程完成之后, 整个系统的内核都会被加载进内存。此时bootfs会被卸载, 从而释放出所占用的系统内存。

      2、在容器中可以运行不同版本的Linux, 说明对于同样内核版本的不同的 Linux 发行版的 bootfs 都是一致的, 否则会无法启动。因此可以推断, Docker运行是需要内核支持 的。

      3、Linux系统中典型的bootfs目录: (核心) /boot/vmlinuz、(核心解压缩所需 RAM Disk) /boot/initramfs

        2、root file system (rootfs)
      1、不同的Linux发行版本, bootfs相同, rootfs不同(二进制文件)。

      2、每个容器有自己的 rootfs, 它来自不同的 Linux 发行版的基础镜像,包括 Ubuntu, Debian 和 SUSE 等。

      3、使用不同的rootfs 就决定了, 在构建镜像的过程中, 可以使用哪些系统的命令。 4) 典型的rootfs 目录: /dev、/proc、/bin、/etc、 /lib、/usr

    2、OverlayFS 存储原理

        OverlayFS 结构分为三个层: LowerDir、Upperdir、MergedDir

        1、LowerDir (只读)

      只读的 image layer,其实就是 rootfs, 在使用 Dockfile 构建镜像的时候, Image Layer

      可以分很多层,所以对应的 lowerdir 会很多(源镜像)。

        2、Upperdir (读写)

      upperdir 则是在 lowerdir 之上的一层, 为读写层。容器在启动的时候会创建, 所有对容 器的修改, 都是在这层。比如容器启动写入的日志文件,或者是应用程序写入的临时 文件。

        3、MergedDir (展示)
      merged 目录是容器的挂载点,在用户视角能够看到的所有文件,都是从这层展示的。

      LowerDir、Upperdir、MergedDir 关系图:

    3、分析镜像存储结构

        1、获取镜像存储路径

      通过镜像信息获取到物理存储位置

    [root@master jdk]# docker image inspect jre8:1.0        
    .......
    "GraphDriver": { "Data": { "LowerDir": "/data/docker/overlay2/0dabd34b699bd07a6fedc787305c029837a509ba325dc19c913a83c1cdb42a3b/diff:/data/docker/overlay2/f0d9e8983ce0eb5189d1343a750ead40fff0b8bf2e7366a288746addca5e64f3/diff:/data/docker/overlay2/203eca2fa309cfded560ddbacaea64e1fe5644a74f8c682cdb94961b7f93f99a/diff:/data/docker/overlay2/cd72a119f6ac0b9796511e54070635c2f6250987163e851005079c310e020b80/diff:/data/docker/overlay2/7468ae5cef2f56d4db4a92d71b979bc2af007af9b5e4f6b3a635db1702a9d429/diff", "MergedDir": "/data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/merged", "UpperDir": "/data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/diff", "WorkDir": "/data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/work" }, "Name": "overlay2" },......

        2、分析Lower

      LowerDir 层的存储是不允许创建文件, 此时的LowerDir实际上是其他的镜像的UpperDir层,也就是说在构建镜像的时候, 如果发现构建的内容相同, 那么不会重复的构建目录,而是使用其他镜像的Upper 层来作为本镜像的Lower

    [root@master jdk]# touch  /data/docker/overlay2/0dabd34b699bd07a6fedc787305c029837a509ba325dc19c913a83c1cdb42a3b/diff/lower.txt

        3、分析Upper

    [root@master jdk]# touch  /data/docker/overlay2/871f67b56f58f71f9774021c44b1ff35e7ef492dabb0dcf9a515353b085bf3f5/diff/upper.txt

        4、分析Merged层

      属于对外展示层,只能在运行中的容器查看,镜像是查看不了的

    4、运行中容器的存储结构

        1、前台启动,直接进入到容器

    [root@master lihanghang]# docker run -it jre8:1.0 bash  # 重新ssh 开个窗口
    bash-4.3#

        2、查看容器挂在信息

      容器启动以后,挂载merged、lowerdir、upperdir以及workdir目录

      lowerdir是只读的image layer,其实就是rootfs

    [root@master jdk]# docker ps
    CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                  NAMES
    6816ade398c3        repo.abc.com/nginx:v1.0   "/docker-entrypoint.…"   4 hours ago         Up 4 hours          0.0.0.0:9091->80/tcp   condescending_shaw
    

     3、查看容器存储目录信息

    #注意在所有的启动容器中会自动添加init目录, 此目录是存放系统的hostname与域名解析文件。

    [root@master jdk]# docker inspect 6816ade398c3 
    "Data": { "LowerDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929-init/diff:/data/docker/overlay2/696103a495dc761560c3ec0de8414619b559c483c5e6e66ec01fc2c5e6af12e1/diff:/data/docker/overlay2/b8e2bc89bb28f516fea555be11d33bf14334008be9c1e547e81088a54112510a/diff:/data/docker/overlay2/e2abf1e74fb5ee048de2066f1c2ee2e3750302cbbfbbd36bd9eff4d8872ec572/diff:/data/docker/overlay2/75c9819b8bf9e1de7b7471ee96632c3e20f82d1a88d5a58555a0b46f4ce952d8/diff:/data/docker/overlay2/0c809e2915134cf1ac493c5d5a814320923982d2384c1de0484d2c8bd5d9ad05/diff", "MergedDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929/merged", "UpperDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929/diff", "WorkDir": "/data/docker/overlay2/768c9e3cbf17b6dd61a47fa5ae935c5c7bc6adfc2a5c0ea79b38a9a3443ac929/work" },

    5、容器文件存储解析

        1、容器运行时的UpperDir目录结构

    # 本地窗口
    [root@master jdk]# touch /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a/diff/upper.txt [root@master jdk]# echo 11111 > /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a/diff/upper.txt
    # 容器里面
    bash-4.3# ls /
    bin        etc        lib        media      opt        root       sbin       sys        upper.txt  var
    dev        home       lib64      mnt        proc       run        srv        tmp        usr
    bash-4.3# cat /upper.txt
    11111

        2、Work 目录

    work目录用于联合挂载指定的工作目录,在overlay 把文件挂载到 upperdir后, work内容会

    被清空,且在使用过程中(为空)其内容用户不可见。

        3、用户视角层Merged

    #最后给用户展示的层,一般看到为一个完整的操作系统文件系统结构

    [root@master jdk]# ll /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a/merged
    bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  upper.txt  usr  var

    4、Lower 层

    #Lower 包括两个层:a. 系统的init。b.容器的镜像层

    Lower 记录父层的链接名称
    [root@node-2 ~]# cat /var/lib/docker/overlay2/d4dc057329ecbf5a2f97293b6d49078e9cce6869a9f049ba5bc365f6fba424d2/lower
    l/QCXVWDWYPFM5NRVMB2ZC2BE5WU:l/PUSOZBTJKJ2OBNKK2UQDNQLHCU
    init 层 / 容器镜像层

        1、查看init层地址指向

      容器在启动的过程中, Lower 会自动挂载init的一些文件

    [root@master jdk]# ls  /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a-init/diff/etc
    hostname  hosts  mtab  resolv.conf

     2、init层主要内容是什么?

      init层是以一个uuid+-init结尾表示,放在只读层(Lower)和读写层(upperdir)之间,

      作用只是存放/etc/hosts、/etc/resolv.conf 等文件。

        3、为什么需要init层?

      1、容器在启动以后, 默认情况下lower层是不能够修改内容的, 但是用户有需求需要修改主 机名与域名地址, 那么就需要添加init层中的文件(hostname, resolv.conf), 用于解决此类问 题.
      2、修改的内容只对当前的容器生效, 而在docker commit提交为镜像时候,并不会将init层提 交。

      3、init 文件存放的目录为/var/lib/docker/overlay2/<init_id>/diff

        4、查看init层文件

      hostname与resolv.conf 全部为空文件, 在系统启动以后由系统写入。注:不能在打镜像的时候copy进去,copy进去用这个镜像启动时,启动起来以后文件也是空的。

    [root@master jdk]# ll  /data/docker/overlay2/d6e4e36c309de456d6025d56144feaf4097c9d133b7cda4a20baa8526ebe671a-init/diff/etc
    总用量 0
    -rwxr-xr-x. 1 root root  0 8月  24 00:03 hostname
    -rwxr-xr-x. 1 root root  0 8月  24 00:03 hosts
    lrwxrwxrwx. 1 root root 12 8月  24 00:03 mtab -> /proc/mounts
    -rwxr-xr-x. 1 root root  0 8月  24 00:03 resolv.conf

    总结

    1. 1、镜像所挂载的目录层为 Lower 层,然后通过 Merged 展示所有的文件目录与文件。用户写入的所有文件都是在 UpperDir 目录,并且会在 UpperDir 建立于 Merged 层展示的文件 目录结构, 所以用户就可以看到写入的文件。并且底层的镜像是不能被修改(如果挂载目 录为 UpperDir,则可以修改源镜像)。

    2. 2、在下次重新启动已经停止的容器的时候, 如果容器的 ID 没有发生改变,那么所写入的文 件是存在物理系统中的; 反之就会是一个新的容器,之前手工创建的文件是不存在的。

           3、基于容器创建的镜像,就相当于容器的快照, 可以删除原来的容器, 但是不能删除原来 的镜像

           4、基于镜像创建的镜像,原来的镜像就是新镜像的 low 层 (build), tag 则是没有区别

           5、容器启动以后,镜像就存在于容器的low 层,所有的写入都是在upper

  • 相关阅读:
    TCP/UDP常见端口参考
    HTTP状态码对照表 HTTP response codes
    HTTP请求方法对照表
    服务器返回的各种HTTP状态码介绍
    HTTP响应头和请求头信息对照表
    简析TCP的三次握手与四次分手
    什么是JDK
    jmeter使用IP欺骗压力测试
    jmeter制造安全证书
    Python 变量作用域
  • 原文地址:https://www.cnblogs.com/tortoise512/p/14674540.html
Copyright © 2020-2023  润新知