一、Docker镜像加载原理
1. bootfs:
- 主要包含boot加载器(bootloader)和内核(kernel)
- Linux刚启动时会加载bootfs文件系统,Docker镜像的最底层就是bootfs
- 当boot加载完成之后整个内核就在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统会卸载bootfs
2. rootfs:
- 在bootfs之上
- 包含的就是典型的Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。
- rootFS就是各种不同操作系统发行版,比如Ubuntu,Centos等。
3. 对于一个镜像:
- 对比发行版的centos系统,一个centos镜像只有200M+,是因为镜像的bootfs使用了主机的kernel,镜像只用提供rootfs
- 因此,不同的Linux版本,bootfs基本一致,rootfs会有差别,不同版本的Linux系统可以公用bootfs
- 因此,镜像的启动是秒级别的
二、Docker镜像分层
[root@QK ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
f7ec5a41d630: Already exists
a36224ca8bbd: Pull complete
7630ad34dcb2: Pull complete
e74b2f747260: Pull complete
ebc61c7bf222: Pull complete
1aafd9c07208: Pull complete
Digest: sha256:eff56acc5fc7b909183da93236ba09d3b8cb7d6db31d5b25e9a46dac9b5e699b
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
[root@QK ~]# docker image inspect redis:latest
[
{
"Id": "sha256:ccee4cdf984f11952441cbab30146dae792c8d9fb668e762c78a49e7db858082",
"RepoTags": [
"redis:latest"
],
"RepoDigests": [
"redis@sha256:eff56acc5fc7b909183da93236ba09d3b8cb7d6db31d5b25e9a46dac9b5e699b"
],
"Parent": "",
"Comment": "",
"Created": "2021-05-03T22:56:33.179589462Z",
"Container": "a9bc56dfb6a1e418143c3b575ec4960962e86d0de60f3048dee7dab96c2e91e9",
"ContainerConfig": {
"Hostname": "a9bc56dfb6a1",
"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.3",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.3.tar.gz",
"REDIS_DOWNLOAD_SHA=98ed7d532b5e9671f5df0825bb71f0f37483a16546364049384c63db8764512b"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"redis-server\"]"
],
"Image": "sha256:c63a85b819427249f9273933cc11f230c39df444c59222d4d6bae97437d16d7e",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "19.03.12",
"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.3",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.3.tar.gz",
"REDIS_DOWNLOAD_SHA=98ed7d532b5e9671f5df0825bb71f0f37483a16546364049384c63db8764512b"
],
"Cmd": [
"redis-server"
],
"Image": "sha256:c63a85b819427249f9273933cc11f230c39df444c59222d4d6bae97437d16d7e",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 105379404,
"VirtualSize": 105379404,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/cb6b00fcb37ea4e79c0d979db67992dcba17fc4ac1e96751c3bbaa3aff8ca027/diff:/var/lib/docker/overlay2/6c259d997f34f111e445ade0a331eb5de57a9054847084f4fabd4d5180b9045d/diff:/var/lib/docker/overlay2/f1649663e99a7935f44fe0c1f91964b8c28f179077d302229f8d8f959a822416/diff:/var/lib/docker/overlay2/fbe849d4ec1984c0e49099bdfe165c25616a1d681d1b7acd608873b1adaeae91/diff:/var/lib/docker/overlay2/21038c1c4da24db78b085f41575bc4f4fd2d2585949b74b48567180a16c510f5/diff",
"MergedDir": "/var/lib/docker/overlay2/34a7c23b6f3b9c2ff2e7e6f74e98615bb222bdef5ea57149fcc24ba61dc1f209/merged",
"UpperDir": "/var/lib/docker/overlay2/34a7c23b6f3b9c2ff2e7e6f74e98615bb222bdef5ea57149fcc24ba61dc1f209/diff",
"WorkDir": "/var/lib/docker/overlay2/34a7c23b6f3b9c2ff2e7e6f74e98615bb222bdef5ea57149fcc24ba61dc1f209/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:7e718b9c0c8c2e6420fe9c4d1d551088e314fe923dce4b2caf75891d82fb227d",
"sha256:89ce1a07a7e4574d724ea605b4877f8a73542cf6abd3c8cbbd2668d911fa5353",
"sha256:9eef6e3cc2937e452b2325b227ca28120a70481be25404ed9aad27fa81219fd0",
"sha256:ee748697d275b904f1d5604345d70b647a8c145b9f05aeb5ca667e1f256e43d8",
"sha256:f1f7964d40afa49c6ef63ab11af91044e518a2539f567783ce997d3cea9ce8f6",
"sha256:3d9fda8ff875e549d54e9d7504ce17d27423fe27dafbb92127c603dddad7fa13"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
由此可见:
- Docker镜像都起始于一个基础镜像层,当进行修改或增加新内容时,就会在之前的镜像上,创建新的镜像层
- 镜像都是分层下载,如果需要下载的某一层,其他镜像已包含,则无需下载,直接复用
三、Docker镜像与容器
- Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像顶部
- 新的层叫容器层,容器之下的叫镜像层
- 镜像层是不变的,用户所有操作都会在镜像层上面添加一层容器层
- 通过pull下载的镜像是无法改变的,run启动的镜像其实已经在镜像层的基础上加了一层容器层
- 所有的操作都是基于容器层的
- 可以把自定义的容器层和镜像层打包成一个新的镜像层,供其他人下载使用,其他人的操作会在你的基础上再次添加容器曾
四、Commit镜像
docker commit -a="qk" -m="mytomcat" 容器ID 目标镜像:版本号
# docker commit -a="作者" -m="信息" 容器ID 目标镜像:版本号
- 启动Tomcat镜像,并建立新的会话,复制webapps.dist文件夹下的所以文件至webapps下
- 把修改的容器提交在本地成为一个新的镜像,
[root@QK ~]# docker run -it -p 8080:8080 tomcat
[root@QK ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d68a7a76d2f tomcat "catalina.sh run" 37 seconds ago Up 36 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp trusting_margulis
[root@QK ~]# docker exec -it 3d68a7a76d2f /bin/bash
root@3d68a7a76d2f:/usr/local/tomcat# cd webapps
root@3d68a7a76d2f:/usr/local/tomcat/webapps# ls
root@3d68a7a76d2f:/usr/local/tomcat/webapps# cd ..
root@3d68a7a76d2f:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@3d68a7a76d2f:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@3d68a7a76d2f:/usr/local/tomcat# cd webapps
root@3d68a7a76d2f:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
root@3d68a7a76d2f:/usr/local/tomcat/webapps#
root@3d68a7a76d2f:/usr/local/tomcat/webapps# exit
exit
[root@QK ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d68a7a76d2f tomcat "catalina.sh run" 14 minutes ago Up 14 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp trusting_margulis
[root@QK ~]# docker commit -a="qk" -m="mytomcat" 3d68a7a76d2f tomcat02:1.0
sha256:60fcf1318d2586c77da865acac7d99a597b848918d361e651cb0eefa970b9d19
[root@QK ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 60fcf1318d25 30 seconds ago 672MB
redis latest ccee4cdf984f 3 days ago 105MB
tomcat latest c0e850d7b9bb 2 weeks ago 667MB
nginx latest 62d49f9bab67 3 weeks ago 133MB
hello-world latest d1165f221234 2 months ago 13.3kB
centos latest 300e315adb2f 5 months ago 209MB
elasticsearch 7.6.2 f29a1ee41030 13 months ago 791MB
[root@QK ~]#
- 新的镜像和原来的镜像相比,大了一点点,也说明新的镜像是在原镜像的基础上封装的