参考原文:http://www.dockerinfo.net/image%e9%95%9c%e5%83%8f
基本概念
基础镜像
在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件。
由于 Docker 使用一个统一文件系统,Docker 进程认为整个文件系统是以读写方式挂载的。 但是所有的变更都发生顶层的可写层,而下层的原始的只读镜像文件并未变化。由于镜像不 可写,所以镜像是无状态的。
父镜像
每一个镜像都可能依赖于由一个或多个下层的组成的另一个镜像。我们有时说,下层那个 镜像是上层镜像的父镜像。
基础镜像
镜像ID
所有镜像都是通过一个 64 位十六进制字符串 (内部是一个 256 bit 的值)来标识的。 为简化使用,前 12 个字符可以组成一个短ID,可以在命令行中使用。短ID还是有一定的 碰撞机率,所以服务器总是返回长ID。
如何得到一个镜像
- 从远程仓库 pull 一个
- 从其他人处 copy 一个
- 自己制作docker file build 一个镜像
镜像的分层下载
当我们去 pull 一个镜像的时候,会下载许多个镜像。
这个类似于 git 存在的控制版本
安装了 centos 第一层
安装了 docker 第二层
UnionFS(联合文件系统) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加。同时可以将不同物理位置的目录挂在到同一个虚拟文件系统下。union文件系统是docker镜像的基础。镜像可以通过分层来进行继承。基于基础镜像可以制作各种镜像。[root@localhost ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
7d63c13d9b9b: Pull complete
a2c3b174c5ad: Pull complete
283a10257b0f: Pull complete
7a08c63a873a: Pull complete
0531663a7f55: Pull complete
9bf50efb265c: Pull complete
Digest: sha256:a89cb097693dd354de598d279c304a1c73ee550fbfff6d9ee515568e0c749cfe
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
[root@localhost ~]#
特性:一次同事加载多个文件系统,从外面看起来只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
UFS参考:https://blog.csdn.net/songcf_faith/article/details/82787946
看一下这张图
第一层是一个内核
第二层是一个debian的镜像
第三层是安装了一个 emacs 叠加在内核之上
第四层是安装了一个apache2 的中间件
上文中说到的 UFS
最底层是bootfs(boot file system),主要包含了bootloader 和 kernel, bootloader 主要是引导加载 kernel,linux刚启动时会加载 bootfs文件系统。在docker镜像最底层的 bootfs。这一层与我们典型的 LINUX、UNIX系统是一样的,包含 boot 加载器和内核。当 boot加载完成之后整个内核就都在内存中了。此时内存的使用权已由bootsf 转交给 kernel。系统也会卸载 bootfs。
rootfs(root file system)。在bootfs之上。包含的就是典型的 linux 系统中的 /dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版。
注:如果某个镜像需要修改内核中的参数,则牵一发而动全身。因为docker 共用 宿主机的内核。
在下载的时候,可以看到之前下载过的镜像,不需要再下载了
相对详细的解答:
总结:
docker镜像是只读的,当容器启动的时候,一个新的可写层会被加载到镜像的顶部。
这一层就是容器层,其它层都是镜像层。
当你丛 hub 上 pull 一个镜像的时候。
你的新操作就在一个可写的容器层上开辟了,你发布一个自己的docker 镜像时,就意味着 你需要把前面的镜像和你自己添加的内容打包到一个镜像!
下面一层一层的那个就叫 layer
如何发布自己的一个镜像
docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
[root@localhost ~]# docker run -it --name mynginx nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/10/21 14:00:06 [notice] 1#1: using the "epoll" event method
2021/10/21 14:00:06 [notice] 1#1: nginx/1.21.3
2021/10/21 14:00:06 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/10/21 14:00:06 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
2021/10/21 14:00:06 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/10/21 14:00:06 [notice] 1#1: start worker processes
2021/10/21 14:00:06 [notice] 1#1: start worker process 32
2021/10/21 14:00:06 [notice] 1#1: start worker process 33
^P
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9821cf90d1ba nginx "/docker-entrypoint.…" 19 seconds ago Up 19 seconds 80/tcp mynginx
[root@localhost ~]# docker exec -it 9821cf90d1ba /bin/bash
root@9821cf90d1ba:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@9821cf90d1ba:/# mkdir 1
root@9821cf90d1ba:/# ls
1 bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@localhost ~]# docker commit -m="add a files" -a"waiting4" ^C
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9821cf90d1ba nginx "/docker-entrypoint.…" 10 minutes ago Up 10 minutes 80/tcp mynginx
[root@localhost ~]# docker commit -m="add a files" -a="waiting4" 9821cf90d1ba jginx:1.0
sha256:99250f27e4f729b31fd7d6097555ff749921a8351267bef8a81ef948549c9f2e
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jginx 1.0 99250f27e4f7 9 seconds ago 133MB
redis latest 7faaec683238 9 days ago 113MB
nginx latest 87a94228f133 9 days ago 133MB
centos latest 5d0da3dc9764 5 weeks ago 231MB
[root@localhost ~]#