镜像是docker容器的基石,容器是镜像的运行实例,有了镜像才能启动容器
[root@foundation0 ~]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 latest 0a3eb3fde7fd 4 years ago 140 MB
在列出的信息中,可以看到几个字段信息:
为什么一个rhel7只有140MB
Linux操作系统由内核空间和用户空间组成(rootfs bootfs)
内核空间是kernel
,Linux刚启动的时候会加载bootfs
文件系统,之后bootfs会被卸载掉
用户空间的文件系统是rootfs
,包括我们熟悉的/dev,/proc,/bin
等目录
对于base
镜像来说,底层直接用host的kernel,自己只需要提供rootfs就行了
而对于一个精简版的os
,rootfs
可以很小,只需要包括最基本的命令,工具和程序就可以了
rootfs
比如Ubuntu 使用upstat 管理服务 apt管理软件包 而centos 7 使用systemd和yum 这些都是用户空间上的区别 Linux kernel差别不大uname -r
来查看最大的一个好处是:共享资源
那么一个疑问是:如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如/etc下的文件,这时其他容器的/etc是否也会被修改???
答案是不会
修改会被限制在单个容器内
这就是我们接下来要学习的容器copy-on-write特性
容器层是可写的
当容器启动时,一个新的可写层被加载到镜像的顶部
这一层通常被叫做“容器层”,“容器层”之下的都叫“镜像层”
所有对容器的改动,无论添加,删除,还是修改文件都只会发生在容器层,只有容器层是可写的,容器层下面的所有镜像层都是只读的
注意!!一个镜像层最多127层(镜像层最好不要太多)
具体细节
镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统,如果不同层中有一个相同路径的文件,比如/a,上层的/a会覆盖下层的/a,也就是说用户只能访问到山层中的文件/a,在容器层中,用户看到的是一个叠加之后的文件系统
1.
添加文件,在容器中创建文件时,新文件被添加到容器层中
2.
读取文件,在容器中读取某个文件时,docker会从上往下依次在各个镜像层中查找到此文件,一旦找到,打开并读入内存
3.
修改文件,在容器中修改已经存在的文件时,docker会从上往下依次在各个镜像层中查找到此文件,一旦找到,立即将其复制到容器层,然后修改
4
.删除文件,在容器中删除文件时,docker也是从上往下依次在镜像层中查找此文件,找到后,会在容器层中记录下此删除操作
只有当修改的时候才复制一份数据,这种特性被称作copy-on-write
可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改
这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享
docker run -it --name ubuntu
run
:创建并运行一个容器 -it
:以交互式的形式 --name
:给容器起个名字 ubuntu:镜像名称
我们可以看到 容器和虚拟机共享内核。到底怎么共享的呢?
[root@docker docker]# hostnamectl
Static hostname: docker
Icon name: computer-vm
Chassis: vm
Machine ID: e26d28698aed47fb9ec897d00ec96f27
Boot ID: 4f549a312dff439b80de72c1c74a0682
Virtualization: kvm
Operating System: Red Hat Enterprise Linux Server 7.5 (Maipo)
CPE OS Name: cpe:/o:redhat:enterprise_linux:7.5:GA:server
Kernel: Linux 3.10.0-862.el7.x86_64
Architecture: x86-64
[root@server3 sysctl.d]# docker run -it --name vm1 ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7413c47ba209: Pull complete
0fe7e7cbb2e8: Pull complete
1d425c982345: Pull complete
344da5c95cec: Pull complete
Digest: sha256:c303f19cfe9ee92badbbbd7567bc1ca47789f79303ddcef56f77687d4744cd7a
Status: Downloaded newer image for ubuntu:latest
Try 'uname --help' for more information.
root@b16f9eaab99e:/# uname -r 3.10.0-514.el7.x86_64
[root@docker docker]# docker run -it --name vm1 ubuntu
root@4154d58490f2:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@4154d58490f2:/# touch file1 #改变的是容器层
root@4154d58490f2:/# touch file2
1.Copy-on-Write可写容器层
2.容器层意所有镜像层都是只读的
3.docker从上往下依次查找文件
4.容器层保存镜像变换的部分 并不会对镜像本身进行任何修改
5.一个镜像最多127层
[root@server3 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 3556258649b2 2 weeks ago 64.2 MB
game2048 latest 19299002fdbe 2 years ago 55.5 MB
[root@server3 ~]# docker history ubuntu:latest # 保存每一层的镜像修改
IMAGE CREATED CREATED BY SIZE COMMENT
3556258649b2 2 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
2 weeks ago /bin/sh -c mkdir -p /run/systemd && echo '... 7 B
2 weeks ago /bin/sh -c set -xe && echo '#!/bin/sh' >... 745 B
2 weeks ago /bin/sh -c [ -z "$(apt-get indextargets)" ] 987 kB
2 weeks ago /bin/sh -c #(nop) ADD file:3ddd02d976792b6... 63.2 MB
"missing“的意思是 这些操作不是在本机操作的 所有找不到 这并没有什么关系
busybox:这个镜像非常的轻量级 适合我们在学习和实验中去使用
[root@server3 ~]# docker run -it --name test busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
ee153a04d683: Pull complete
Digest: sha256:9f1003c480699be56815db0f8146ad2e22efea85129b5b5983d0e0fb52d9ab70
Status: Downloaded newer image for busybox:latest
/ # echo helloworld >testfile
/ # ls
bin etc proc sys tmp var
dev home root testfile usr
/ # cat testfile
helloworld
/ # exit #退出并停止运行 ctrl p+q 退出不停止运行
[root@server3 ~]# docker ps -a #注意:我们只是退出了运行中的容器 并没有删除它
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6789012d8958 busybox "sh" About a minute ago Exited (0) 5 seconds ago test
docker start test
[root@server3 ~]# docker attach test 的容器
[root@server3 ~]# docker commit test test:v1 #
sha256:c1a9c80bccb0b51e410cc90bbe56460c4b84e2119741aee133d99a45da702857
[root@server3 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v1 c1a9c80bccb0 5 seconds ago 1.22 MB
ubuntu latest 3556258649b2 2 weeks ago 64.2 MB
busybox latest db8ee88ad75f 3 weeks ago 1.22 MB
game2048 latest 19299002fdbe 2 years ago 55.5 MB
[root@server3 ~]# docker history test:v1
IMAGE CREATED CREATED BY SIZE COMMENT
c1a9c80bccb0 24 seconds ago sh 59 B
db8ee88ad75f 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
3 weeks ago /bin/sh -c #(nop) ADD file:9ceca008111a4dd... 1.22 MB
缺点是:我们无法得知我们对这个容器到底做了什么操作 虽然它已经被保存了
[root@server3 ~]# docker rm 6789012d8958
Error response from daemon: You cannot remove a running container 6789012d89587629aa79031fdde5101671265849ed92b042f5e1dda7b7909f07. Stop the container before attempting removal or use -f
[root@server3 ~]# docker rm -f 6789012d8958
6789012d8958
[root@server3 ~]# docker rm -f 6789012d8958
6789012d8958
[root@server3 ~]# docker run -it --name vm1 test:v1
/ # ls
bin etc proc sys tmp var
dev home root testfile usr
/ # cat testfile
helloworld