1. Docker 镜像

Docker 镜像是个只读的容器模板,它组成了 Docker 容器的静态文件系统运行环境 rootfs,是启动 Docker 容器的基础。

Docker 镜像是容器的静态视角,容器是镜像的运行状态。那么,怎么构建 Docker 镜像呢?这就不得不提 Liunx 的联合文件系统(union filesystem)了。

1.1 联合文件系统

联合文件系统是实现联合挂载技术的文件系统。联合挂载技术可以实现在一个挂载点同时挂载多个文件系统,将挂载点的原目录与被挂载内容进行整合,使得最终可见的文件系统包含整合之后的各层文件和目录。

以 aufs(advanced multi layered unification filesystem) 联合文件系统为例。首先创建 aufs 联合文件系统如下:

root@chunqiu:~/chunqiu/docker# ls -R
.:
beautifulGirl handsomeBoy mnt ./beautifulGirl:
chunqiu_girlfriend root ./beautifulGirl/root:
baby ./handsomeBoy:
chunqiu root ./handsomeBoy/root:
baby ./mnt:
root@chunqiu:~/chunqiu/docker# mount -t aufs -o dirs=./beautifulGirl/:./handsomeBoy/ none ./mnt
root@chunqiu:~/chunqiu/docker# df -hT | grep aufs
none aufs 150G 143G 840M 100% /root/chunqiu/docker/mnt
root@chunqiu:~/chunqiu/docker# ls -R ./mnt/
./mnt/:
chunqiu chunqiu_girlfriend root ./mnt/root:
baby

可以看到,目录 beautifulGirl 和 handsomeBoy 的内容被联合挂载到 mnt 目录下,修改 mnt 目录下的文件:

root@chunqiu:~/chunqiu/docker/mnt# echo 'who?' > chunqiu_girlfriend
root@chunqiu:~/chunqiu/docker/mnt# echo 'chunqiu' > chunqiu
root@chunqiu:~/chunqiu/docker/mnt# echo 'who?' > root/baby root@chunqiu:~/chunqiu/docker# ls -R ./beautifulGirl/ handsomeBoy/
./beautifulGirl/:
chunqiu chunqiu_girlfriend root ./beautifulGirl/root:
baby handsomeBoy/:
chunqiu root handsomeBoy/root:
baby root@chunqiu:~/chunqiu/docker# cat beautifulGirl/chunqiu beautifulGirl/chunqiu_girlfriend
chunqiu
who?
root@chunqiu:~/chunqiu/docker# cat handsomeBoy/chunqiu root@chunqiu:~/chunqiu/docker# cat beautifulGirl/root/baby
who?
root@chunqiu:~/chunqiu/docker# cat handsomeBoy/root/baby

看起来很奇怪,修改 mnt 下 chunqiu 的内容会将改动写到 beautifulGirl 目录下,而修改 root 目录下的 baby 修改只显示在 beautifulGirl 目录下。

这是因为 mount aufs 命令未指定目录的权限,默认第一个出现的目录是可读写目录,而后面出现的目录是只读目录。所以,写入文件实际上都是写到可读写目录 beautifulGirl 目录下。

那如果删除文件呢?这里介绍一种特殊的删除联合文件系统的特性,称为 whiteout 如下:

root@chunqiu:~/chunqiu/docker/handsomeBoy# touch whiteout
root@chunqiu:~/chunqiu/docker/handsomeBoy# ls
chunqiu root whiteout root@chunqiu:~/chunqiu/docker/mnt# ls
chunqiu chunqiu_girlfriend root whiteout
root@chunqiu:~/chunqiu/docker/mnt# rm -rf whiteout root@chunqiu:~/chunqiu/docker/handsomeBoy# ls
chunqiu root whiteout root@chunqiu:~/chunqiu/docker/beautifulGirl# ls -al
total 28
drwxr-xr-x 5 root root 4096 May 8 06:11 .
drwxr-xr-x 5 root root 4096 May 8 05:43 ..
-rw-r--r-- 1 root root 8 May 8 05:56 chunqiu
-rw-r--r-- 1 root root 5 May 8 05:56 chunqiu_girlfriend
drwxr-xr-x 2 root root 4096 May 8 05:44 root
-r--r--r-- 2 root root 0 May 8 05:45 .wh.whiteout

在只读目录 handsomeBoy 下创建文件 whiteout,这个文件被映射到 mnt 目录下。在 mnt 目录下删除该文件,会发现 handsomeBoy 下这个文件还是存在(因为它是只读目录),而在可读写目录 beautifulGril 下多了个隐藏文件 .wh.whiteout。这就是 whiteout 的特性,它是上层目录覆盖下层相同名字目录,用于隐藏低层分支的机制。

这里简要介绍了联合文件系统,可以发现它将目录以层级的形式表现出来。相比于联合文件系统,容器文件系统利用联合挂载技术将可读写层(read-write layer 以及 volumes),init-layer,只读层组合在一起呈现给容器内的进程,进程是感受不到这些层级结构的。那么,让我们开始容器文件系统的学习吧。

1.2 Docker overlay2 最佳实践

容器文件系统有多种存储驱动实现方式,aufs,devicemapper,overlay,overlay2 等。这里选其中一种 overlay2 加以介绍。

在介绍 overlay2 之前需要先介绍下 docker 镜像相关概念,理解它们是后续介绍的基础:

  • registry/repository: registry 是 repository 的集合,repository 是镜像的集合。
  • image:image 是存储镜像相关的元数据,包括镜像的架构,镜像默认配置信息,镜像的容器配置信息等等。它是“逻辑”上的概念,并无物理上的镜像文件与之对应。
  • layer:layer(镜像层) 组成了镜像,单个 layer 可以被多个镜像共享。

使用 docker info 命令查看宿主机上使用的存储驱动是否是 overlay2 (配置 overlay2 可看 这里):

[root@k8s-master-node-1 centos]# docker info | grep overlay
Storage Driver: overlay2

宿主机上已经配置好了 overlay2 存储驱动,使用 docker pull 下载 ubuntu 镜像:

[root@k8s-master-node-1 overlay2]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
345e3491a907: Pull complete
57671312ef6f: Pull complete
5e9250ddb7d0: Pull complete
Digest: sha256:cf31af331f38d1d7158470e095b132acd126a7180a54f263d386da88eb681d93
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest

可以看到 ubuntu 镜像分为三层,那怎么找到这三层呢?

首先查看 ubuntu 镜像:

[root@k8s-master-node-1 centos]# docker image ls | grep ubuntu
ubuntu latest 7e0aa2d69a15 2 weeks ago 72.7MB

镜像的短 ID 为 7e0aa2d69a15,通过它可以查找到镜像的三层结构。查看目录:

[root@k8s-master-node-1 centos]# cd /var/lib/docker/image/overlay2/
distribution/ imagedb/ layerdb/ repositories.json

这个目录是查找的入口,非常重要。它存储了镜像管理的元数据。其中, repositories.json 记录了 repo 与镜像 ID 的映射关系。imagedb 记录了镜像架构,操作系统,构建镜像的容器 ID 和配置以及 rootfs 等信息。layerdb 记录了每层镜像层的元数据。

通过短 ID 查找 repositories.json 文件,找到镜像 ubuntu 的长 ID,通过长 ID 在 imagedb 中找到该镜像的元数据:

[root@k8s-master-node-1 overlay2]# cat repositories.json | grep 7e0aa2d69a15
...
{"ubuntu:latest":"sha256:7e0aa2d69a153215c790488ed1fcec162015e973e49962d438e18249d16fa9bd"} [root@k8s-master-node-1 overlay2]# cat imagedb/content/sha256/7e0aa2d69a153215c790488ed1fcec162015e973e49962d438e18249d16fa9bd
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439",
"sha256:63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107",
"sha256:2f140462f3bcf8cf3752461e27dfd4b3531f266fa10cda716166bd3a78a19103"]
}
...

这里仅保留我们想要的元数据 rootfs。在 rootfs 中看到 layers 有三层,这三层即对应镜像的三层镜像层。并且,自上而下分别映射到容器的底层到顶层。找到了镜像的三层,接下来的问题是每层的文件内容在哪里呢?

layerdb 元数据会给我们想要的信息,通过底层 diff-id: ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439 我们查到最底层镜像层的 cache_id,通过 cache_id 即可查找到镜像层的文件内容:

[root@k8s-master-node-1 ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439]# ls
cache-id diff size tar-split.json.gz [root@k8s-master-node-1 ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439]# cat cache-id
1c3b24824b7026813cc6e62b1f217f5b5bf17d67c2bc30a90bc68d286348b7b7
[root@k8s-master-node-1 ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439]# cat diff
sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439 [root@k8s-master-node-1 ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439]# pwd
/var/lib/docker/image/overlay2/layerdb/sha256/ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439 // 使用 cacheID 查找文件内容
[root@k8s-master-node-1 ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439]# cd /var/lib/docker/overlay2/1c3b24824b7026813cc6e62b1f217f5b5bf17d67c2bc30a90bc68d286348b7b7/
[root@k8s-master-node-1 1c3b24824b7026813cc6e62b1f217f5b5bf17d67c2bc30a90bc68d286348b7b7]# ls
committed diff link
[root@k8s-master-node-1 1c3b24824b7026813cc6e62b1f217f5b5bf17d67c2bc30a90bc68d286348b7b7]# cd diff/
[root@k8s-master-node-1 diff]# ls
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var [root@k8s-master-node-1 1c3b24824b7026813cc6e62b1f217f5b5bf17d67c2bc30a90bc68d286348b7b7]# cat link
5OLEHO4UPBPTXSVUTVZ2JB2WJR

上示例中,镜像元数据和镜像层内容是分开存储的。因此通过 cache-id 我们需要到 /var/lib/docker/overlay2 目录下查看镜像层内容,它就存在 diff 目录下,其中 link 存储的是镜像层对应的短 ID,后面会看到它的用场。

找到了镜像层的最底层,接着查找镜像层的“中间层”,发现在 layerdb 目录下没有 diff-id 63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107 的镜像层:

[root@k8s-master-node-1 layerdb]# cd sha256/63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107
bash: cd: sha256/63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107: No such file or directory
[root@k8s-master-node-1 layerdb]#

这是因为 docker 引入了内容寻址机制,该机制会根据文件内容来索引镜像和镜像层。docker 利用 rootfs 中的 diff_id 计算出内容寻址的 chainID,通过 chainID 获取 layer 相关信息,最终索引到镜像层文件内容。

对于最底层镜像层其 diff_id 即是 chainID。因此我们可以查找到它的文件内容。除最底层外,chainID 需通过公式 chainID(n) = SHA256(chain(n-1) diffID(n)) 计算得到,计算“中间层” chainID:

[root@k8s-master-node-1 layerdb]# echo -n "sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439 sha256:63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107" | sha256sum -
8d8dceacec7085abcab1f93ac1128765bc6cf0caac334c821e01546bd96eb741 -

根据 “中间层” chainID 查找文件内容:

[root@k8s-master-node-1 8d8dceacec7085abcab1f93ac1128765bc6cf0caac334c821e01546bd96eb741]# ls
cache-id diff parent size tar-split.json.gz
[root@k8s-master-node-1 8d8dceacec7085abcab1f93ac1128765bc6cf0caac334c821e01546bd96eb741]# cat cache-id
4d615a437c68f0853db7749bf3d7d268efaebbe045a2af4d8b8e1148fc1acd91
[root@k8s-master-node-1 8d8dceacec7085abcab1f93ac1128765bc6cf0caac334c821e01546bd96eb741]# cat diff
sha256:63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107 [root@k8s-master-node-1 8d8dceacec7085abcab1f93ac1128765bc6cf0caac334c821e01546bd96eb741]# cat parent
sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439 [root@k8s-master-node-1 4d615a437c68f0853db7749bf3d7d268efaebbe045a2af4d8b8e1148fc1acd91]# ls
committed diff link lower work
[root@k8s-master-node-1 4d615a437c68f0853db7749bf3d7d268efaebbe045a2af4d8b8e1148fc1acd91]# ls diff/
etc usr var
// 镜像层文件内容
[root@k8s-master-node-1 4d615a437c68f0853db7749bf3d7d268efaebbe045a2af4d8b8e1148fc1acd91]# cat link
GALK5TGULR45FL2NKY54EPAQ3C
// 镜像层文件内容短 ID
[root@k8s-master-node-1 4d615a437c68f0853db7749bf3d7d268efaebbe045a2af4d8b8e1148fc1acd91]# cat lower
l/5OLEHO4UPBPTXSVUTVZ2JB2WJR
// “父”镜像层文件内容短 ID

找到最底层文件内容和“中间层”文件内容,再去找最顶层文件内容就变的不难了,这里就不多做赘述啦~

这一节知道了如何去查找镜像的镜像层文件内容,那么 docker 容器是怎么将镜像和容器结合起来的呢?为什么说“镜像是容器的静态视角,容器是镜像的运行状态”呢?接着往下看。

1.2.1 docker 容器与镜像

通过 docker run 命令启动一个镜像为 ubuntu 的容器:

[root@k8s-master-node-1 centos]# docker ps | grep ubuntu
156d4506b7ae ubuntu "/bin/bash" 24 hours ago Up 23 hours great_williamson [root@k8s-master-node-1 centos]# mount | grep overlay
overlay on /var/lib/docker/overlay2/5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d/merged type overlay
(rw,relatime,lowerdir=/var/lib/docker/overlay2/l/Q6HPGILSGOQG5JGUURP2357S4X:/var/lib/docker/overlay2/l/Y2WW3FGR4WZDFTNZTTLGI7L24E:/var/lib/docker/overlay2/l/GALK5TGULR45FL2NKY54EPAQ3C:/var/lib/docker/overlay2/l/5OLEHO4UPBPTXSVUTVZ2JB2WJR,upperdir=/var/lib/docker/overlay2/5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d/diff,workdir=/var/lib/docker/overlay2/5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d/work)

可以看到,启动容器会 mount 一个 overlay 的联合文件系统到容器内。这个文件系统由三层组成:

  • lowerdir:只读层,即为镜像的镜像层。
  • upperdir:读写层,该层是容器的读写层,对容器的读写操作将反映在读写层。
  • workdir: overlayfs 的内部层,用于实现从只读层到读写层的 copy_up 操作。
  • merge:容器内作为同一视图联合挂载点的目录。

这里需要着重介绍的是容器的 lowerdir 镜像只读层,查看只读层的短 ID:

Q6HPGILSGOQG5JGUURP2357S4X

Y2WW3FGR4WZDFTNZTTLGI7L24E
GALK5TGULR45FL2NKY54EPAQ3C
5OLEHO4UPBPTXSVUTVZ2JB2WJR

镜像层只有三层这里的短 ID 却有四个?

在 /var/lib/docker/overlay2/l 目录下我们找到了答案:

[root@k8s-master-node-1 l]# pwd
/var/lib/docker/overlay2/l [root@k8s-master-node-1 l]# ls -l Q6HPGILSGOQG5JGUURP2357S4X
lrwxrwxrwx 1 root root 77 May 7 08:47 Q6HPGILSGOQG5JGUURP2357S4X -> ../5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d-init/diff [root@k8s-master-node-1 l]# ls -l Y2WW3FGR4WZDFTNZTTLGI7L24E
lrwxrwxrwx 1 root root 72 May 7 08:13 Y2WW3FGR4WZDFTNZTTLGI7L24E -> ../7e27874bb1acb324bf692d0fb53ad0ebaed0837cfe650eab42cd9f8c2c592c85/diff
[root@k8s-master-node-1 l]# ls -l GALK5TGULR45FL2NKY54EPAQ3C
lrwxrwxrwx 1 root root 72 May 7 08:13 GALK5TGULR45FL2NKY54EPAQ3C -> ../4d615a437c68f0853db7749bf3d7d268efaebbe045a2af4d8b8e1148fc1acd91/diff
[root@k8s-master-node-1 l]# ls -l 5OLEHO4UPBPTXSVUTVZ2JB2WJR
lrwxrwxrwx 1 root root 72 May 7 08:13 5OLEHO4UPBPTXSVUTVZ2JB2WJR -> ../1c3b24824b7026813cc6e62b1f217f5b5bf17d67c2bc30a90bc68d286348b7b7/diff [root@k8s-master-node-1 l]# ls -R ../5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d-init/diff
../5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d-init/diff:
dev etc ../5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d-init/diff/dev:
console pts shm ../5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d-init/diff/dev/pts: ../5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d-init/diff/dev/shm: ../5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d-init/diff/etc:
hostname hosts mtab resolv.conf

镜像层 Y2WW3FGR4WZDFTNZTTLGI7L24E / GALK5TGULR45FL2NKY54EPAQ3C / 5OLEHO4UPBPTXSVUTVZ2JB2WJR 分别对应镜像的三层镜像层文件内容,它们分别映射到镜像层的 diff 目录。而 Q6HPGILSGOQG5JGUURP2357S4X 映射的是容器的初始化层 init,该层内容是和容器配置相关的文件内容,它是只读的。

启动了容器,docker 将镜像的内容 mount 到容器中。那么,如果在容器内写文件会对镜像有什么影响呢?

1.2.2 容器内写文件

不难理解,镜像层是只读的,在容器中写文件其实是将文件写入到 overlay 的可读写层。

这里有几个 case 可以测试:

  • 读写层不存在该文件,只读层存在。
  • 读写层存在该文件,只读层不存在。
  • 读写层和只读层都不存在该文件。

我们简单构建一种读写层和只读层都不存在的场景:

root@156d4506b7ae:/etc# touch temp.txt
root@156d4506b7ae:/etc# ls
temp.txt ...

查看读写层是否有该文件:

[root@k8s-master-node-1 diff]# cd /var/lib/docker/overlay2/5d0cbbdeb08f0b3087d6635f764aa51654eb6b9fbdc7265248fd9815855c2a4d/diff
[root@k8s-master-node-1 diff]# ls
etc
[root@k8s-master-node-1 diff]# ls etc/
temp.txt

1.2.3 docker commit

上节提到容器内写文件会反映在 overlay 的可读写层,那么读写层的文件内容可以做成镜像吗?

可以。docker 通过 commit 和 build 操作实现镜像的构建。commit 将容器提交为一个镜像,build 在一个镜像的基础上构建镜像。

使用 commit 将上节的容器提交为一个镜像:

[root@k8s-master-node-1 diff]# docker commit 156d4506b7ae
sha256:71cf2c4aad14d18e9d0ee8bfb2cdd16ea5216f68c6d4d81062143fe58fbe48a4
[root@k8s-master-node-1 diff]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 71cf2c4aad14 9 seconds ago 72.7MB

image 短 ID 71cf2c4aad14 即为容器提交的镜像,查看镜像的 imagedb 元数据:

[root@k8s-master-node-1 diff]# cat /var/lib/docker/image/overlay2/imagedb/content/sha256/71cf2c4aad14d18e9d0ee8bfb2cdd16ea5216f68c6d4d81062143fe58fbe48a4
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:ccdbb80308cc5ef43b605ac28fac29c6a597f89f5a169bbedbb8dec29c987439",
"sha256:63c99163f47292f80f9d24c5b475751dbad6dc795596e935c5c7f1c73dc08107",
"sha256:2f140462f3bcf8cf3752461e27dfd4b3531f266fa10cda716166bd3a78a19103",
"sha256:7dd12b1505cdc6bebe28cf63d5b374890908dcc9b1a23ca4dcc21e9de033c209"]
}
...

可以看到镜像层自上而下的前三个镜像层 diff_id 和 ubuntu 镜像层 diff_id 是一样的,说明每层镜像层可以被多个镜像共享。而多出来的一层镜像层内容即是上节我们写入文件的内容:

[root@k8s-master-node-1 diff]# echo -n "sha256:3dd8c8d4fd5b59d543c8f75a67cdfaab30aef5a6d99aea3fe74d8cc69d4e7bf2 sha256:7dd12b1505cdc6bebe28cf63d5b374890908dcc9b1a23ca4dcc21e9de033c209" | sha256sum -
0f3060e8fee611c68417fecbfc52734563ddea02157eaa7624fa23043af0bfb6 - [root@k8s-master-node-1 diff]# cd /var/lib/docker/image/overlay2/layerdb/sha256/0f3060e8fee611c68417fecbfc52734563ddea02157eaa7624fa23043af0bfb6/
[root@k8s-master-node-1 0f3060e8fee611c68417fecbfc52734563ddea02157eaa7624fa23043af0bfb6]# ls
cache-id diff parent size tar-split.json.gz [root@k8s-master-node-1 48e27ff2ff5302bd2dfd244610a61cc5032ec88b79b0953eb2c933a1f4146a36]# ls
diff link lower work
[root@k8s-master-node-1 48e27ff2ff5302bd2dfd244610a61cc5032ec88b79b0953eb2c933a1f4146a36]# cd diff/
[root@k8s-master-node-1 diff]# ls etc/
temp.txt

docker 镜像管理之 overlay2 最佳实践的更多相关文章

  1. 2、docker镜像管理

    Docker镜像管理 镜像是Docker容器的基础,想运行一个Docker容器就需要有镜像.我们上面已经学会了使用search搜索镜像.那么这个镜像是怎么创建的呢? 创建镜像 镜像的创建有以下几种方法 ...

  2. Docker镜像管理基础篇

    Docker镜像管理基础篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Docker Images Docker镜像还有启动容器所需要的文件系统及其内容,因此,其用于创建并启 ...

  3. 三、docker镜像管理

    一.docker镜像管理 1.1.镜像搜索-search 从docker镜像仓库模糊搜索镜像 用法: docker search 镜像关键字 [root@zutuanxue ~]# docker se ...

  4. Devops(四):Docker 镜像管理

    参考 <Docker中上传镜像到docker hub中> <Docker 镜像管理> <通过容器提交镜像(docker commit)以及推送镜像(docker push ...

  5. Docker学习第一天(Docker入门&&Docker镜像管理)

    简介 今天小区的超市买零食老板给我说再过几天可能就卖完了我有点诧异,老板又说厂家不生产了emmm 今天总算开始docker了! 1.Docker? 1.什么是Docker Docker 是一个开源的应 ...

  6. 004.Docker镜像管理

    一 镜像基本操作 镜像是一个包含程序运行必要依赖环境和代码的只读文件,其本质是磁盘上一系列文件的集合.它采用分层的文件系统,将每一次改变以读写层的形式增加到原来的只读文件上.镜像是容器运行的基石. 1 ...

  7. docker镜像的获取、查看、删除、docker镜像管理、docker容器管理

    在不想弄乱本地及其环境下该如何进行系软件的安装? 下载安装docker工具 获取该软件的docker镜像(你以后想要用各种工具,基本都能够搜索docker search nginx:版本号到合适的镜像 ...

  8. paas架构之docker——镜像管理

    1. 镜像管理 1.1. 列出镜像 Sudo docker images 1.2. 查看镜像 Sudo docker images xxxx 1.3. 拉取镜像 Sudo docker pull ub ...

  9. Docker镜像管理

    镜像是docker的三大核心概念之一.可以用来创建容器. Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统被称为UnionFS.镜像可以基于Dockerfile构建,Dockerf ...

  10. 3、Docker镜像管理基础

    Docker image     # docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE redis -alpine 23d561d12e92 d ...

随机推荐

  1. Chrome扩展开发实战:快速填充表单

    大家好,我是 dom 哥.我正在写关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星 . 填表单是打工人经常面对的场景,作为一个前端,我经常开发一些PC端的页面,它们主要由表单和表格构成 ...

  2. 2023 年最后一波工具安利「GitHub 热点速览」

    2023 年还有两周就要接近尾声了,2023 年的热点速览还有一波工具好安利:比如上周推荐之后上了热榜的远程调试工具 page-spy-web,让调试像呼吸一般自然方便:还有轻量级的搜索引擎 oram ...

  3. Codeforces #475 div2

    题目链接:http://codeforces.com/contest/964 A题 答案n/2+1: B题 讨论三种情况 c>b c==b c<b C题 数论,逆元+快速幂,但是我一直卡在 ...

  4. StingBuilder与StringBuffer包含的常见方法(图示)

    StingBuilder与StringBuffer包含的常见方法

  5. 神经网络优化篇:详解神经网络的权重初始化(Weight Initialization for Deep NetworksVanishing / Exploding gradients)

    神经网络的权重初始化 这是一个神经单元初始化地例子,然后再演变到整个深度网络. 来看看只有一个神经元的情况,然后才是深度网络. 单个神经元可能有4个输入特征,从\(x_{1}\)到\(x_{4}\), ...

  6. 面试Java时碰到过的那些问题

    项目终于忙完了,难得不加班,但回到家中却不知道干啥,打开自己的云笔记,看到了以前面试时碰到的一些面试题,下面将会把以前面试时被问到的问题都分享出来,下面的题看看小伙伴们可以答的怎样吧 HashMap实 ...

  7. CWE4.8:2022年危害最大的25种软件安全问题

    摘要:我们来看下新版的<2022年危害最大的25种安全问题>在安全预防上会给了我们哪些安全提示. 本文分享自华为云社区<CWE4.8 -- 2022年危害最大的25种软件安全问题&g ...

  8. 输入的查询SQL语句,是如何执行的?

    摘要:输入一条语句,返回一个结果,却不知道这条语句在 MySQL 内部的执行过程. 本文分享自华为云社区<一条查询SQL是如何执行的>,作者: 共饮一杯无 . 执行如下SQL,我们看到的只 ...

  9. NDPQ(NDP+PQ),定义分布式数据库新方向

    摘要:云服务提供商构建新的云原生关系数据库系统,专门为云基础架构设计,通常采用将计算和存储分离到独立扩展的分布式层的设计. 本文分享自华为云社区<性能提升100倍!GaussDB(for MyS ...

  10. React Native UI界面还原,组件布局与动画效果

    写React Native UI和写 Android XML layout 布局 ,个人感觉是大同小异 在<ReactJS到React-Native,架构原理概述>里面提过 web 环境中 ...