容器rootfs
挂载在容器根目录上、用来为容器进程提供隔离后执行环境的文件系统,就是所谓的“容器镜像”;
它还有一个更为专业的名称:rootfs (根文件系统)。
所以,一个最常见的rootfs,或者说容器镜像,会包括如下所示的一些目录和文件,比如/bin /etc/ proc等等:
[root@node01 test]# docker run -it busybox /bin/sh / # ls / bin dev etc home proc root sys tmp usr var
而你进入容器之后执行的/bin/sh,就是/bin目录下的可执行文件,跟宿主机的/bin/sh安全不同。
现在你应该可以理解,对Docker项目来说,它最核心的管理实际上是为待创建的用户进程:
1、启用Linux NameSpace隔离配置;
2、设置指定的Cgroup限制参数;
3、切换进程的根目录(Change Root)
这样一个完整的容器就诞生了。另外需要明确的是rootfs只是一个操作系统所包含的文件、配置和目录,
并不包括操作系统的内核(bootfs包含了BootLoader和Kernel), 在Linux操作系统中,这两部分是分开存放的,操作系统只有在开机启动
时才会加载指定版本的内核。
所以说,rootfs 只包括了操作系统的“躯壳”,并没有包括操作系统的“灵魂”。
https://studygolang.com/articles/14942
https://zhuanlan.zhihu.com/p/86890896
Aufs
1)准备如下目录和文件 $ tree . |-- a | |-- a.log | `-- x.log `-- b |-- b.log `-- x.log 2)执行挂载命令 $ mkdir mnt $ mount -t aufs -o dirs=./a:./b none ./mnt $ tree ./mnt ./mnt |-- a.log |-- b.log `-- x.log 可以看到被挂载的mnt目录合并了目录a和目录b 3)修改 $ echo test > mnt/x.log $ cat mnt/x.log test $ cat a/x.log test $ cat b/x.log 你会发现x.log在a、b目录都存在,在修改后只有a目录生效了,原因是我们在mount aufs命令中,没有指a、b目录的权限,默认上来说,命令行上第一个(最左边)的目录是可读可写的,后面的全都是只读的,所以会出现上面这种情况,你也可以在挂载的时候自己指定权限(mount -t aufs -o dirs=./a=rw:./b=rw none ./mnt),如果你有兴趣可以去尝试一下,这里就不再演示了。 那么再试一下修改b目录(只读目录)才有的b.log文件试一下呢: $ echo test > mnt/b.log $ cat mnt/b.log test $ cat b/b.log $ cat a/b.log test 你会发现,b目录下的文件没有被修改,而是在a目录(可读写目录)创建了一个b.log。 4)删除 $ touch b/bb.log $ rm mnt/a.log $ rm mnt/bb.log $ ls -al mnt -rw-r--r-- 1 root root 0 Sep 19 23:11 b.log -rw-r--r-- 1 root root 0 Sep 19 23:11 x.log $ ls -al a -rw-r--r-- 1 root root 0 Sep 19 23:15 .wh.bb.log -rw-r--r-- 1 root root 0 Sep 19 23:11 b.log -rw-r--r-- 1 root root 0 Sep 19 23:11 x.log $ ls -al b -rw-r--r-- 1 root root 0 Sep 19 23:11 b.log -rw-r--r-- 1 root root 0 Sep 19 23:14 bb.log -rw-r--r-- 1 root root 0 Sep 19 23:11 x.log 你会看到在mnt目录中删除a.log和bb.log后,a目录(可读写)中的a.log真的删除了,而b目录(只读)中的bb.log还在,只是a目录中多个.wh.bb.log这个文件。 一般来说只读目录都会有whiteout的属性,所谓whiteout的意思,就是如果在union中删除的某个文件,实际上是位于一个readonly的目录上,那么,在mount的union这个目录中你将看不到这个文件,但是readonly这个层上我们无法做任何的修改,所以,我们就需要对这个readonly目录里的文件作whiteout。AUFS的whiteout的实现是通过在上层的可写的目录下建立对应的whiteout隐藏文件来实现的。 所以上面的rm mnt/bb.log操作和touch a/.wh.bb.log效果相同。
为什么要有volumn
简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。换句话说,宿主机和容器建立/a:/b
的映射,那么对容器/b
的写入即对宿主机/a
的写入(反之也可)。
volumn的作用:
- 将容器以及容器产生的数据分离开来
人们很容易想到volumn是为了持久化数据,其实容器只要你不删除,它就在那里,停掉的容器也可以重新启动运行,所以容器是持久的。
估计也正是因为如此,
docker cp
、docker commit
和docker export
还不支持Volume(只是对容器本身的数据做了相应处理)。 - 容器间共享数据
docker volume
// 创建一个容器,包含两个数据卷
$ docker run -v /var/volume1 -v /var/volume2 -name Volume_Container ubuntu14.04 linux_command
// 创建App_Container容器,挂载Volume_Container容器中的数据卷
$ docker run -t -i -rm -volumes-from Volume_Container -name App_Container ubuntu14.04 linux_command
// 这样两个容器就可以共用这个数据卷了
// 最后可以专门安排一个容器,在应用结束时,将数据卷中的内容备份到主机上
docker run -rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
在默认方式下,volume就是在/var/lib/docker/volumes
目录下创建一个文件夹,并将该文件夹挂载到容器的某个目录下(以UFS文件系统的方式挂载)。当然,我们也可以指定将主机的某个特定目录(该目录要显式指定)挂载到容器的目录中。
docker run -v /container/dir imagename command
docker run -v /host/dir:/container/dir imagename command
docker run -v dir:/container/dir imagename command
第三种方式相当于docker run -v /var/lib/docker/volumes/dir:/container/dir imagename command
到目前为止,容器的创建/销毁期间来管理Volume(创建/销毁)是唯一的方式。
- 该容器是用
docker rm -v
命令来删除的(-v是必不可少的)。 docker run
中使用了--rm
参数
即使用以上两种命令,也只能删除没有容器连接的Volume。连接到用户指定主机目录的Volume永远不会被docker删除。
root@ubuntu:/home/ubuntu# mkdir dirA root@ubuntu:/home/ubuntu# touch dirA/a.txt root@ubuntu:/home/ubuntu# touch dirA/x.txt root@ubuntu:/home/ubuntu# mkdir dirB root@ubuntu:/home/ubuntu# touch dirB/x.txt root@ubuntu:/home/ubuntu# touch dirB/b.txt root@ubuntu:/home/ubuntu# mkdir dirC
root@ubuntu:/home/ubuntu# tree ./dirC ./dirC ├── a.txt ├── b.txt └── x.txt 0 directories, 3 files root@ubuntu:/home/ubuntu# echo test > dirC/x.txt root@ubuntu:/home/ubuntu# cat dirA/x.txt test root@ubuntu:/home/ubuntu# cat dirB/x.txt root@ubuntu:/home/ubuntu# cat dirB/a.txt cat: dirB/a.txt: No such file or directory root@ubuntu:/home/ubuntu#
查看容器aufs
https://cizixs.com/2017/09/13/docker-aufs-storage-driver/
root@ubuntu:/home/ubuntu# docker info Client: Debug Mode: false Server: Containers: 2 Running: 1 Paused: 0 Stopped: 1 Images: 3 Server Version: 19.03.13 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: kata-runtime runc Default Runtime: runc Init Binary: docker-init containerd version: 8fba4e9a7d01810a393d5d25a3621dc101981175 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd init version: fec3683 Security Options: apparmor seccomp Profile: default Kernel Version: 5.0.0-23-generic Operating System: Ubuntu 18.04.3 LTS OSType: linux Architecture: aarch64 CPUs: 64 Total Memory: 251.1GiB Name: ubuntu ID: P7KG:LNSP:MDTB:FIE6:F23Q:MIW5:7QIX:KABU:CCLO:Z3ST:5TPT:D742 Docker Root Dir: /var/lib/docker Debug Mode: true File Descriptors: 31 Goroutines: 50 System Time: 2020-10-12T11:53:33.848913703+08:00 EventsListeners: 0 Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false WARNING: No swap limit support root@ubuntu:/home/ubuntu# docker info | grep 'Root Dir' WARNING: No swap limit support Docker Root Dir: /var/lib/docker root@ubuntu:/home/ubuntu#
root@ubuntu:/var/lib/docker/overlay2# df -h Filesystem Size Used Avail Use% Mounted on udev 126G 0 126G 0% /dev tmpfs 26G 1.7M 26G 1% /run /dev/sdc3 218G 14G 194G 7% / tmpfs 126G 0 126G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 126G 0 126G 0% /sys/fs/cgroup /dev/sdc2 465M 81M 356M 19% /boot /dev/sdc1 243M 252K 243M 1% /boot/efi tmpfs 26G 0 26G 0% /run/user/1000 /dev/loop0 86M 86M 0 100% /snap/core/9994 /dev/loop1 45M 17M 25M 41% /tmp/my-rootfs overlay 218G 14G 194G 7% /var/lib/docker/overlay2/8534450bbe83e64ff72f91ead54c343eddd227751e07ddc06e260df4db0a37d5/merged none 218G 14G 194G 7% /home/ubuntu/dirC root@ubuntu:/var/lib/docker/overlay2#
root@ubuntu:/var/lib/docker/overlay2# umount /home/ubuntu/dirC root@ubuntu:/var/lib/docker/overlay2# df -h Filesystem Size Used Avail Use% Mounted on udev 126G 0 126G 0% /dev tmpfs 26G 1.7M 26G 1% /run /dev/sdc3 218G 14G 194G 7% / tmpfs 126G 0 126G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 126G 0 126G 0% /sys/fs/cgroup /dev/sdc2 465M 81M 356M 19% /boot /dev/sdc1 243M 252K 243M 1% /boot/efi tmpfs 26G 0 26G 0% /run/user/1000 /dev/loop0 86M 86M 0 100% /snap/core/9994 /dev/loop1 45M 17M 25M 41% /tmp/my-rootfs overlay 218G 14G 194G 7% /var/lib/docker/overlay2/8534450bbe83e64ff72f91ead54c343eddd227751e07ddc06e260df4db0a37d5/merged