首页 > 其他分享 >[Docker] 将容器打包成镜像、镜像分层机制详解

[Docker] 将容器打包成镜像、镜像分层机制详解

时间:2023-01-08 10:45:59浏览次数:46  
标签:layer layer1 union 文件系统 详解 file 镜像 Docker

目录

commit 命令

# 将容器打包成镜像的命令,:TAG可有可无
docker commit -m="commit信息" -a="作者名" 容器ID 你的镜像名:TAG

创建一个容器

# 以Mariadb为例,我们启动一个mariadb镜像,然后进入这个镜像做一些修改
docker run -it mariadb bash

上面的命令是创建一个 mariadb 镜像的容器并进入这个容器,我们在要在这个容器里新建一个文件夹,然后把我们修改过的这个容器打包成一个新的镜像
image
新建一个test文件夹
image
现在我们已经准备好了要打包的容器啦

打包镜像

因为需要容器ID,我们先查看一下容器ID

# 如果你的容器正在运行中,用这个命令
docker ps

# 如果你的容器当前没有运行,那就用这个命令来查看容器信息
docker ps -a

image
第一行就是我们要打包的容器,执行 commit 命令:

docker commit -m="test commit" -a="kirizi" 30f034aea26a my_image01:1.0

image
执行成功返回了镜像ID,再用 docker images命令看看我们的所有镜像:
image
可以看到第一行就是我们刚刚创建的my_image01:1.0,并且注意看最后一列 SIZE列,我们的my_image01mariadb的镜像大小几乎是一样的。

# 查看镜像信息
docker inspect 镜像ID

我们使用docker inspect来看看我们的镜像和原始镜像的区别在哪儿
image
image
image
image
这是我们的镜像的信息,一些值得注意的信息

# 这个image id是我们用来创建这个容器的mariadb的镜像id,Volumes是
"Image": "a748acbaccae",

# docker的文件分层机制,可以看到我们的镜像文件分了9层
"RootFS": {
	"Type": "layers",
	"Layers": [
		"sha256:6515074984c6f8bb1b8a9962c8fb5f310fc85e70b04c88442a3939c026dbfad3",
		"sha256:ef35264eddcdd186fd3a3a994135ee9848f945d75c2ed81fb3db2adf6c3d2fa7",
		"sha256:daec9799caa31439c45c0eda941688a825b2c16abc63cace00d6f6d15c540ce3",
		"sha256:fd44d9fa9cd41d4a154323aa232b22e650b45ad92085a249f9febcd97b2af209",
		"sha256:e77dd0f2e017c73e064e20c166f30e2dd11ed9534a773c848c9bb73a7d6c4004",
		"sha256:cdbb3a99fe5526710d8c51ae42e6eb1a106fa53fb4494c3a9ea7326a88460002",
		"sha256:9a3285a0ae185ce0cc550989d474f5ec59f687fb5f9f3af48dd9fecc942c0900",
		"sha256:9d646cb6b224d9bf1400b776ea4c2684371815902a48abe77e6fdd5058040fbe",
		"sha256:6e28cb318b18cec6896c847a8291f1dc0c8653ee2560a6ee19ff3ad1995737ff"
	]
},

再看看原始的 mariadb image的信息
image
其他地方都跟my_image01差不多,就不贴上来了,主要看看这个 RootFS 字段,可以发现我们自己的镜像有9层,而这个只有8层,并且这8层和my_image01的前8层是一样的,这就是 docker 的镜像分层存储机制,也就是联合文件系统。

联合文件系统

联合文件系统(union file system),直接用百度去搜这个关键词搜出来的都是个 docker 相关的东西,但其实联合文件系统不是 docker 创造出来的,它是一种 linux 文件系统。
联合文件系统工作在其他文件系统的上一层,它聚合了多个文件系统里的文件到同一个根目录下,比起文件系统,它更像是一个挂载机制。
image
在上图我们可以看到由 XFSext3这两个文件系统控制的不同的路径都被挂载到了 /mnt 目录下,比较流行的联合文件系统有 UnionFS, AUFS, OverlayFS等,docker默认使用的文件系统是overlay2,可以使用docker info命令查看当前的文件系统:
image

OverlayFS为例,我们做几个实验看看联合文件系统是怎么工作的:

联合文件系统实践

前置准备

# 我这里是起一个ubuntu docker容器来进行这个实验,大家如果觉得麻烦也可以直接用自己的宿主机进行
# 用docker进行实验的话要记得--privileged=True加这个命令,不然mount命令会因为没有权限而执行失败
docker run --name ubuntu01 -it --privileged=True ubuntu:18.04 bash

# 创建一个文件夹用来存放我们实验用的各种文件
mkdir test_unionfs
cd test_unionfs

# 创建几个基础文件夹
mkdir layer1 layer2 layer3 union_layer

# 创建虚拟磁盘分区
dd if=/dev/zero of=fs1 bs=1024 count=1024
dd if=/dev/zero of=fs2 bs=1024 count=1024
dd if=/dev/zero of=fs3 bs=1024 count=1024

# 创建几个不同的文件系统
mkfs -t ext2 fs1
mkfs -t ext3 fs2
mkfs -t ext4 fs3

# 挂载分区到基础文件夹
mount fs1 layer1
mount fs2 layer2

# 创建几个文件
touch layer1/file_of_layer1 layer1/file
echo "file from layer1" > layer1/file

touch layer2/file_of_layer2 layer2/file
echo "file from layer2" > layer2/file

# 取消挂载
umount layer1
umount layer2

image

不使用联合文件系统的挂载

# 挂载fs1到union_layer
mount fs1 union_layer
ls union_layer
cat union_layer/file

# 挂载fs2到union_layer
mount fs2 union_layer
ls union_layer
cat union_layer/file

image

可以看到当我们把 fs2 挂载到 union_layer 的时候原本挂载的 fs1 里的东西就看不见了,只能看见新挂载的fs2里的文件(fs1还是挂载在union_layer上的,因为我们没有取消挂载,可以使用df命令查看当前所有挂载的目录,可以看到union_layer是挂载着两个文件系统的),也就是一个挂载点不能同时挂载多个卷,但是联合文件系统却可以做到这一点

使用联合文件系统进行挂载

# 在实验一里我们挂载了文件系统到 union_layer,先取消挂载,因为我们挂载了两个文件系统,所以要执行两次
umount union_layer
umount union_layer

# 挂载文件系统 -o ro 表示使用只读模式,也就是我们无法修改该文件系统中的原始文件,layer1、layer2 模拟docker image 里的的只读层
mount -o ro fs1 layer1
mount -o ro fs2 layer2

# layer3模拟 docker 容器的最顶层,也就是可读写的容器层,所以它需要读写权限
mount fs3 layer3

# 创建工作目录
mkdir layer3/upper layer3/workdir

# 使用 overlay 作为联合文件系统
mount -t overlay -o \
lowerdir=layer1:layer2,\
upperdir=layer3/upper,\
workdir=layer3/workdir \
none union_layer

ls union_layer

image
现在 union_layer里可以同时看到 layer1layer2里的文件了,如果我们在union_layer里修改file file_of_layer1 file_of_layer2这些文件会怎么样呢,看看实验三:

写时复制机制

# 在layer3是无法看见layer1和layer2里的文件的,这里的layer3就是模拟的我们docker里的container layer
cat layer3/file
>"No such file or directory"

# 看看layer1里的file文件里有啥
cat layer1/file
"file from layer1"

# 看看layer2里的file文件里有啥
cat layer2/file
>"file from layer2"

cat union_layer/file
>"file from layer1"

# 当前layer3/upper里是没有东西的,如果我们在挂载了layer1和layer2的union_layer层里进行了文件的修改
# 那么修改之后的文件会存储在layer3/upper,这也就是linux里的写时复制(cow)技术
cat layer3/upper/file
> No such file or directory

echo "file from union_layer" > union_layer/file

# 可以看到现在layer3/upper/file里已经有了我们刚刚写到union_layer/file里的内容了
cat layer3/upper/file
> "file from union_layer"

# image 层 layer1 里的内容不变
cat layer1/file
> "file from layer1"

# 移除挂载层里的文件
rm union_layer/file

# image层里的文件不会受到影响,它是只读的
ls layer1
> file  file_of_layer1  lost+found

ll layer3/upper/file
> c--------- 1 root root 0, 0 Jan  7 15:17 layer3/upper/file

image
image
image

再回到 docker 中,我们来看看在 docker 里是到底怎么通过联合文件系统实现镜像分层的:
image
结合上面的实验再看这张图是不是就很清晰啦,我们实验中的 layer1layer2模拟的是 docker 里的 image layerlayer3模拟的是container layer,挂载的那个 union_layer 模拟的是container mount
container mount层让我们可以同时看到container layerimage layer 里的文件内容,而我们的修改都会存储在container layer,不会影响到image layer
image layer是可以复用的只读层,就像我们文章一开始所打包的那个镜像,我们使用一个镜像创建了容器,并且在这个容器里新建了一个文件,把我们新建了文件的这个容器打包成新的镜像,这个新的镜像只比原来的镜像多了一层,这一层就是图上的container layer

标签:layer,layer1,union,文件系统,详解,file,镜像,Docker
From: https://www.cnblogs.com/kirizi/p/17032261.html

相关文章

  • nohup命令详解
    原文地址:https://www.cnblogs.com/sddai/p/14681585.html1.nohup用途:不挂断地运行命令。语法:nohupCommand[Arg…][&]无论是否将nohup命令的输出重定向......
  • 玩转SpringBoot之定时任务详解
        pom文件<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins......
  • 【Python】pip的镜像安装异常解决方案
    在安装pip的出现异常提示:ERROR:Couldnotfindaversionthatsatisfiestherequirementpillow(fromversions:none)ERROR:Nomatchingdistributionfoundfor......
  • 先学什么:Docker 还是 Kubernetes?
    介绍谈到容器化和编排,经常出现的两个工具是Docker和Kubernetes。两者都很强大,在行业中被广泛使用,但对于刚起步的人来说,可能很难知道先学哪一个。Docker是一个容器化......
  • 【Python】open及file函数详解
    open函数python内置函数,一般用于本地文件的读写操作,创建一个 file 对象,调用file()方法进行读写。Tips:file对象需要调用close#参数@params:file:str|by......
  • Docker修改容器内部文件的方法
    Docker修改容器内部文件的方法一共有三种,下面进行一一介绍。1、进入容器内部修改使用下面的命令以命令行的形式可以进入容器的内部对文件进行修改。dockerexec-it容......
  • Docker学习使用01
    安装官网地址:https://docs.docker.com/engine/install/centos/1.卸载旧版本yumremovedocker\docker-client\docker-client-......
  • docker 安装rabbitmq
    1、firewall-cmd--zone=public--add-port=5672/tcp--add-port=15672/tcp--permanent&&firewall-cmd--reloadfirewall-cmd--list-portsmkdir-p/root/cloud/ra......
  • Isaac Sim 机器人仿真器介绍、安装与 Docker [1]
    前言与参考此文书写于:January6,2023,更新于January6,2023;可能会随着时间的变化此教程会有过时概念哦IsaacSim相关参考链接:官方文档地址官方dockerimage镜......
  • 安装docker harbor私有镜像仓库
    软件:harbor-offline-installer-v2.5.3.tgz  docker-compose前提条件:已安装部署docker环境1下载软件wgethttps://ghproxy.com/https://github.com/goharbor/harbor/relea......