首页 > 其他分享 >docker镜像详解

docker镜像详解

时间:2022-11-26 15:45:25浏览次数:55  
标签:false 详解 usr 镜像 docker sha256 root

Docker镜像详解

什么是镜像

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时(一个程序在运行或者在被执行的依赖)、库,环境变量和配置文件。
所有应用,直接打包docker,可以直接运行

Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统是UnionFS联合文件系统。
Docker的镜像实际由一层一层的文件系统组成:

  • bootfs(boot file system)主要包含bootloader和kernel。bootloader主要是引导加载kernel,完成后整个内核就都在内存中了。此时内存的使用权已由bootfs转交给内核,系统卸载bootfs。可以被不同的Linux发行版公用。
  • rootfs(root file system),包含典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同操作系统发行版(Ubuntu,Centos等)。因为底层直接用Host的kernel,rootfs只包含最基本的命令,工具和程序就可以了。
  • 分层理解
    所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的容器层。
    容器在启动时会在镜像最外层上建立一层可读写的容器层(R/W),而镜像层是只读的(R/O)。

rootfs (root file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。Rootfs(根文件系统),在引导之上。包含的就是典型linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。Rootfs就是各种不同的操作系统发行版,比如Ubuntu,CentOS等等。
image.png

平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M ?
image.png

对于一个精简的oS, rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别,因此不同的发行版可以公用bootfs。

分层理解

我们去下载一个镜像,注意下载日志,可以发现是分层进行下载的
image.png

思考∶为什么Docker镜像要采用这种分层的结构呢?

最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

:::tips
查看镜像分层的方式可以通过docker image inspect命令!
:::

[root@localhost ~]# docker image inspect redis:latest
[
    {
        "Id": "sha256:7614ae9453d1d87e740a2056257a6de7135c84037c367e1fffa92ae922784631",
        "RepoTags": [
            "redis:latest"
        ],
        "RepoDigests": [
            "redis@sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-12-21T12:42:49.755107412Z",
        "Container": "13d25f53410417c5220c8dfe8bd49f06abdbcd69faa62a9b877de02464bb04a3",
        "ContainerConfig": {
            "Hostname": "13d25f534104",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.2.6",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz",
                "REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"redis-server\"]"
            ],
            "Image": "sha256:e093f59d716c95cfce82c676f099b960cc700432ab531388fcedf79932fc81ec",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "20.10.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.2.6",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz",
                "REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab"
            ],
            "Cmd": [
                "redis-server"
            ],
            "Image": "sha256:e093f59d716c95cfce82c676f099b960cc700432ab531388fcedf79932fc81ec",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 112691373,
        "VirtualSize": 112691373,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/e9108002980c92a086707dd3fdaf92585a359803f62463eec03d44d552432e9e/diff:/var/lib/docker/overlay2/ee41879c2adad89d8e0847e4186d01a39dbaa48c3f71fcd725ca55278ee84c14/diff:/var/lib/docker/overlay2/d48921882961deb5ec301f7877e5a529f094475c25a044240f35957b013e2b9b/diff:/var/lib/docker/overlay2/b699114ebaf4efdba2086f24f289bbd2223f6159811f6d2ddf00f0184030883e/diff:/var/lib/docker/overlay2/3186fbc839e6e7d6ecc565b3378d22494f1ec8ee9454f8335a82883dbf21e450/diff",
                "MergedDir": "/var/lib/docker/overlay2/67146a76f119a87a206599fb753914929ecfd2093f19fa08d8893fbf7c0ee298/merged",
                "UpperDir": "/var/lib/docker/overlay2/67146a76f119a87a206599fb753914929ecfd2093f19fa08d8893fbf7c0ee298/diff",
                "WorkDir": "/var/lib/docker/overlay2/67146a76f119a87a206599fb753914929ecfd2093f19fa08d8893fbf7c0ee298/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
                "sha256:9b24afeb7c2f21e50a686ead025823cd2c6e9730c013ca77ad5f115c079b57cb",
                "sha256:4b8e2801e0f956a4220c32e2c8b0a590e6f9bd2420ec65453685246b82766ea1",
                "sha256:529cdb636f61e95ab91a62a51526a84fd7314d6aab0d414040796150b4522372",
                "sha256:9975392591f2777d6bf4d9919ad1b2c9afa12f9a9b4d260f45025ec3cc9b18ed",
                "sha256:8e5669d8329116b8444b9bbb1663dda568ede12d3dbcce950199b582f6e94952"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

image.png
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。、
image.png
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
image.png

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
image.png
image.png

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1].下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
image.png

特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!

image.png

commit镜像

docker commit 提交镜像成为一个新的副本
#原理与git相似
docker commit -m ="提交的一些信息"  -a="作者" 容器id  镜像名:[tag]

实战测试:

#启动一个默认的tomcat
#发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认 webapps下面是没有文件的!
#拷贝进去了基本的文件
#1.复制文件   
[root@localhost ~]#  docker exec -it   c488a6848f7d   /bin/bash
root@c488a6848f7d:/usr/local/tomcat# cd webapps
root@c488a6848f7d:/usr/local/tomcat/webapps#  ls
root@c488a6848f7d:/usr/local/tomcat/webapps# cd ../
root@c488a6848f7d:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@c488a6848f7d:/usr/local/tomcat# cd webapps
root@c488a6848f7d:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
#2.查看运行状态
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND             CREATED       STATUS       PORTS                                       NAMES
c488a6848f7d   fb5657adc892   "catalina.sh run"   3 hours ago   Up 3 hours   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   tender_zhukovsky
#3.进行镜像提交
[root@localhost ~]# docker commit -a=““"utoujun" -m="add webapps app"   c488a6848f7d  tomcat02:1.0
sha256:855f0e3d5375642f9a80d3b59e903c7e14984490372a41ae46750192996fa616
#4、将我们操作过的容器通过commit提交为一个镜像!
我们以后就使用我们修改过的镜像即可,
这就是我们自己的一个修改的镜像

image.png

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们以前学习VM时候,快照!

标签:false,详解,usr,镜像,docker,sha256,root
From: https://www.cnblogs.com/yutoujun/p/16927531.html

相关文章