详解docker容器的层的概念

今天我们看看容器的层的概念。

上一节中,我们知道了,容器是一个进程,在这个进程的基础上,添加了下面3个部分:

1、启动Linux Namespace的配置实现与物理机的隔离。

2、设置Cgroups参数限制容器的资源。

3、生成系统文件目录,也就是rootfs文件,也叫镜像文件

这里需要备注的是:rootfs只是容器需要使用的基本文件的组合,并不包括操作系统内核,容器的操作系统内核依旧是使用宿主机的内核。当然,rootfs的存在,并不是没有意义,它的存在,使得容器拥有了一个最主要的性能:一致性。

01 容器的一致性

容器的rootfs打包了操作系统的所有文件和目录,包含了所有的依赖,有了这个特性,就使得容器无论在本地、云端,用户只需要解压打包好的容器镜像,那么应用运行的环境就被搭建好了。

这就是容器的一致性。

02 层的概念

"我之所以看的远,是因为我站在巨人的肩膀上",牛顿曾经这句话在今天也依旧适用。"不要做重复造轮子的人",在我们开发应用的时候,我们只需要借助Linux操作系统去开发即可,我们不需要为了跑我们的应用,重新开发一个Linux系统。

在容器的使用过程中,如果我们已经存在一个已有的MySQL容器镜像,里面有数据A;此时,其他人也想要一个MySQL容器镜像,导入他们的数据B,这个时候,我们只需要在我们自己的MySQL容器删除数据A,再重新导入数据B即可。

在上面描述的场景中,一旦删除数据A,导入数据B,那么这个容器我们自己就不能用了,因为数据A已经删除了。这显然不是我们想要的结果。很明显,数据集A和数据集B都需要的是一个安装了MySQL,但是没有数据的容器镜像(也就是rootfs)。

Docker软件在设计的时候,引入了"层"的概念,很巧妙的解决了这个问题。

"层"的概念是通过联合文件系统AuFS来实现的,全称是Advance UnionFS。它的概念不难理解,举例如下:

目录1包含文件a,文件c

目录2包含文件b,文件c

通过联合文件方式,将目录1和目录2挂在在目录3上,此时,目录3拥有文件a、b、c三个文件。

此时,如果在目录3中对文件a、b、c进行修改,对应的目录1和目录2也会生效。

如何通过"联合文件系统"实现层,这个问题其实比较复杂,留给有兴趣读者自己思考吧,这里,我们只需要了解层的概念是通过联合文件系统实现的就行。

下面是一个mysql基础镜像的"层"的例子:

[root@VM-0-14-centos ~]# docker image inspect docker.io/mysql 
[
    {
        "Id": "sha256:db2b37ec6181ee1f367363432f841bf3819d4a9f61d26e42ac16e5bd7ff2ec18",
        "RepoTags": [
            "docker.io/mysql:latest"
        ],
......
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:d0fe97fa8b8cefdffcef1d62b65aba51a6c87b6679628a2b50fc6a7a579f764c",
                "sha256:329fe06a30f03f9131ce8d9db2e8a9f725b18efe3457d6f015e1c4d8a3f41a0a",
                "sha256:ec8c80284c72bcf47ffedc0dde4d5792de761d52f974c30d37d52b9ac00e8a2a",
                "sha256:9dae2565e824235798981525d6ff9114817b7139c073e0d216b00ae9e58f74d0",
                "sha256:36b89ee4c647b9c21de8b5476b4922efc873aba69705c169e1a3edcf9128679b",
                "sha256:c21e35e55228365b268f57fac382a6e991db216cb03d9b7079496f5498956ab0",
                "sha256:15b463db445cb750fa6bc908a41fd18e38c4d2a02a978b66beb598c4f3f57b95",
                "sha256:7832ac00d41eda3a773a18408dea0b8e05ddbdd3a1e94afef3b6e3dc6444b7bb",
                "sha256:7f893b7c04ac2f939737d2da4e15af796c7acc0fd10c2951d9ae5bf33ceec2dc",
                "sha256:060fef62a228fff7e9dc3b7008bc9089e642ef29dc699f7e90c36ced5b2e75c6",
                "sha256:af6e790b82373cc65ca73efe5cc8945731525a9dcae6deeea2a5a5802561a72a",
                "sha256:9b0377a95c0e0bd5aa5b220449d17333faaa0e2bd7e8b93565beeadbf3906646"
            ]
        }
    }
]

可以看到,RootFS字样的就是容器的文件系统,Layers就是“层”。

那么一个docker容器镜像,分为哪些层呢???

按照功能的不同,主要分为只读层、init层和读写层。

只读层:

只读层的挂载方式都是只读的,这些层都是以增量的方式挂载了操作系统的一部分。

可读写层:

它是这个镜像的最顶层,它的挂载方式为读写,没有写入文件之前,这个目录是空的,而一旦在容器里面执行了写操作,你修改的内容就会通过增量的方式出现在这个层中。

init层:

init层是docker专门生成的一个内部层,主要是存放/etc/hosts、/etc/resolv.conf等文件的。

之所以存放这些特定文件,是因为这些文件本来是操作系统的一部分,但是用户的应用程序往往会修改这些文件,这些修改只对当前容器有效,我们不希望docker commit的时候,将这些改变同读写层一起提交掉。

几点注意:

1、用户执行docker commit的时候,只会提交读写层的内容。

2、如果我们要删除一个只读层文件a.txt,那么我们只需要在读写层写一个同名的文件.wh.a.txt,这样,a.txt这个文件就会被.wh.a.txt这个文件给遮挡起来,实现了删除的目的。

03 分层设计的优点

通过分层设计,增量式数据操作,每次拉取、修改的内容,比完整的操作系统小;

底层只读层的共享,让多个容器镜像使用的总空间,也比每个容器镜像的总和要小;

同时,基于容器镜像的团队协作,可以将各个公司,不同领域的人联系起来,更加快速的迭代出新的功能。

以上就是详解docker容器的层的概念的详细内容,更多关于docker容器的层的资料请关注我们其它相关文章!

(0)

相关推荐

  • 浅析Docker镜像分层的注意事项

    前言 我们平常在对程序进行Docker镜像打包的时候总会有些困惑,到底是将最终的镜像分层打包最后汇总成程序的镜像(也就是一层一层的 From )合适,还是说直接将程序从Source code就打包出最终的镜像更合适呢?其实这里面没有说那个是对或错的,要看程序包自身的情况做选择. Docker build的注意点 如果接触过Docker,Docker build大家都清楚怎么用了,但是有几个容易忽略的注意点: 1.Dockerfile开头的 From 和 MAINTAINER 其实都是一层镜像 2

  • Docker底层技术Namespace Cgroup应用详解

    Docker底层技术: docker底层的2个核心技术分别是Namespaces和Control groups Namespace:是容器虚拟化的核心技术,用来隔离各个容器,可解决容器之间的冲突. 主要通过以下六项隔离技术来实现: 有两个伪文件系统:/proc和/sys/ UTS:允许每个container拥有独立的hostname(主机名)和domainname(域名),使其在网络上可以被视作一个独立的节点而非Host上的一个进程. IPC:contaner中进程交互还是采用linux常见的进

  • Docker镜像分层的原理详解

    base镜像 base镜像有两层含义: 不依赖其他镜像,从scratch构建 其他镜像可以之为基础进行扩展 所以,base镜像一般都是各种Linux发行版本的Docker镜像,比如:Ubuntu,Debian或者CentOS等. base镜像提供的都是最小安装的Linux发行版本. 我们大部分镜像都将是基于base镜像构建的.所以,通常使用的是官方发布的base镜像.可以在docker hub里找到.比如centos:https://hub.docker.com/_/centos 我们可以自己构

  • 详解docker容器的层的概念

    今天我们看看容器的层的概念. 上一节中,我们知道了,容器是一个进程,在这个进程的基础上,添加了下面3个部分: 1.启动Linux Namespace的配置实现与物理机的隔离. 2.设置Cgroups参数限制容器的资源. 3.生成系统文件目录,也就是rootfs文件,也叫镜像文件 这里需要备注的是:rootfs只是容器需要使用的基本文件的组合,并不包括操作系统内核,容器的操作系统内核依旧是使用宿主机的内核.当然,rootfs的存在,并不是没有意义,它的存在,使得容器拥有了一个最主要的性能:一致性.

  • 详解Docker容器可视化监控中心搭建

    概述 一个宿主机上可以运行多个容器化应用,容器化应用运行于宿主机上,我们需要知道该容器的运行情况,包括 CPU使用率.内存占用.网络状况以及磁盘空间等等一系列信息,而且这些信息随时间变化,我们称其为时序数据,本文将实操 如何搭建一个可视化的监控中心 来收集这些承载着具体应用的容器的时序信息并可视化分析与展示! 动手了,动手了... 准备镜像 adviser:负责收集容器的随时间变化的数据 influxdb:负责存储时序数据 grafana:负责分析和展示时序数据 部署Influxdb服务 可以将

  • 详解Docker 容器使用 cgroups 限制资源使用

    上一篇文章将到 Docker 容器使用 linux namespace 来隔离其运行环境,使得容器中的进程看起来就像爱一个独立环境中运行一样.但是,光有运行环境隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络.磁盘.CPU以及内存 等.为了让容器中的进程更加可控,Docker 使用 Linux cgroups 来限制容器中的进程允许使用的系统资源. 1. 基础知识:Linux control groups 1.1 概念 Linux Cgroup 可​​​让​​​您​​​为​​​系

  • 详解docker容器分配静态IP

    最近因为工作要求需要用学习使用docker,最后卡在了网络配置这一块.默认情况下启动容器的时候,docker容器使用的是bridge策略比如: docker run -ti ubuntu:latest /bin/bash 等效于 docker run -ti --net=bridge ubuntu:latest /bin/bash bridge策略下,docker容器自动为我们分配了一个IP地址,并连接到docker0的网桥上.但这里有一个问题,这个IP地址并不是静态分配的,这对我们的对容器的实

  • 详解Docker 容器互联方法

    Docker容器都是独立的,互相隔离的环境.然而,它们通常只有互相通信时才能发挥作用. 虽然有许多方法可以连接容器们,可是我将并不会试着去将其全部讨论在内.但是在这一系列的方法中,我们将看看那些常用的做法. 虽然看起来是很浅显,但是这对于与Docker成天打交道的朋友来说,理解这些技术及底层的设计理念就显得非常地重要了. 理解这些主题将会: 帮助开发和运维人员探索广泛的容器部署的选择. 让开发和运维人员更自信的着手于微服务microservice架构设计. 让开发和运维人员可以较好的编排更复杂的

  • 详解Docker容器跨主机通信的方法

    默认情况下Docker容器需要跨主机通信两个主机节点都需要在同一个网段下,这时只要两个Docker容器的宿主机能相互通信并且该容器使用net网络模式,改实现方式为网桥模式通信: 除此之外我们还可以通过使用第三方工具为不同主机间创建一个覆盖网络,使之能够 跨节点通信 ,这里将使用Flanneld实现: 安装etcd 创建 cat /etc/etcd/etcd.conf文件 # [member] ETCD_NAME=infra1 ETCD_DATA_DIR="/var/lib/etcd"

  • 详解docker 容器不自动退出结束运行的方法

    本文主要简单介绍 docker 容器与前置进程的关系,以及如何编写 Dockerfile/docker-compose.yml 优雅的让容器可以常驻运行. docker 容器的生命周期是同容器中的前置进程相关在一起的,这也是我们平时可能会遇到一些容器只是运行几秒便自动结束的原因:因为容器中没有一个常驻的前置进程,前置进程运行结束后,容器便自动退出了. 比如 docker hello-world # 一闪而过 输出一堆东西 docker run --name hello-world hello-w

  • 详解Docker 容器跨主机多网段通信解决方案

    一.MacVlan 实现Docker的跨主机网络通信的方案有很多,如之前博文中写到的通过部署 Consul服务实现Docker容器跨主机通信 Macvlan工作原理: Macvlan是Linux内核支持的网络接口.要求的Linux内部版本是v3.9–3.19和4.0+: 通过为物理网卡创建Macvlan子接口,允许一块物理网卡拥有多个独立的MAC地址和IP地址.虚拟出来的子接口将直接暴露在相邻物理网络中.从外部看来,就像是把网线隔开多股,分别接受了不同的主机上一样: 物理网卡收到包后,会根据收到

  • 详解Docker容器数据卷

    是什么 先来看看Docker的理念: 将运用与运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的容器之间希望有可能共享数据 Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了. 为了能保存数据在docker中我们使用卷. 一句话:有点类似我们Redis里面的RDB和AOF 能干嘛 卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系

  • 详解docker容器硬盘动态扩容

    扩容容器 默认来说,如果你使用 Device Mapper 的存储插件,所有的镜像和容器是从一个初始 10G 的文件系统中创建的.让我们来看看如何从一个更大的文件系统中创建一个容器. 首先,我们用 Ubuntu 的镜像来创建我们的容器.我们不需要在这个容器里运行任何东西,只需要这个文件(或者关联的文件系统)存在.为了演示,我们会在这个容器里运行 df ,来看一下根文件系统的大小. $ docker run -d ubuntu df -h / 4ab0bdde0a0dd663d35993e4010

随机推荐