docker最大的贡献就是定义了容器镜像的分层的存储格式,docker镜像技术的基础是联合文件系统(UnionFS),其文件系统是分层的。这样既可以充分利用共享层,又可以减少存储空间占用。
联合挂载系统的工作原理:读:如果文件在upperdir(容器)层,直接读取文件;如果文件不在upperdir(容器)层,则从镜像层(lowerdir)读取。
目前docker支持的联合文件系统有很多种,包括:AUFS、overlay、overlay2、DeviceMapper、VSF等。
Linux 中各发行版实现的 UnionFS 各不相同,所以docker在不同 linux 发行版中使用的也不同。通过docker info 命令可以查看当前系统所使用哪种 UnionFS,常见的几种发行版使用如下:
CentOS, Storage Driver: overlay2、overlay,devicemapper debain, Storage Driver: aufs RedHat, Storage Driver: devicemapper,overlay2
查看docker容器使用的文件系统使用的命令如下,其中Storage Driver: overlay2代表使用的是overlay2联合文件系统。
- [root@master01 diff]# docker info
- Containers: 27
- Running: 18
- Paused: 0
- Stopped: 9
- Images: 30
- Server Version: 20.10.12
- Storage Driver: overlay2
- Backing Filesystem: xfs
- Supports d_type: true
- Native Overlay Diff: true
- userxattr: false
- Logging Driver: json-file
- Cgroup Driver: systemd
- 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: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux
- Default Runtime: runc
- Init Binary: docker-init
- containerd version: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
- runc version: v1.1.4-0-g5fd4c4d
- init version: de40ad0
- Security Options:
- seccomp
- Profile: default
- Kernel Version: 3.10.0-1127.18.2.el7.x86_64
- Operating System: CentOS Linux 7 (Core)
- OSType: linux
- Architecture: x86_64
- CPUs: 4
- Total Memory: 3.7GiB
- Name: master01
- ID: EXII:NDBF:JXGN:XQ4U:4U64:AXUJ:YL6W:RR3U:FXBN:6YXP:RA2I:SR4Q
- Docker Root Dir: /var/lib/docker
- Debug Mode (client): false
- Debug Mode (server): false
- Registry: https://index.docker.io/v1/
- Labels:
- Experimental: false
- Insecure Registries:
- 127.0.0.0/8
- Registry Mirrors:
- https://coy8g925.mirror.aliyuncs.com/
- Live Restore Enabled: fals
修改对应文件系统,可以通过/etc/docker/daemon.json文件的 "storage-driver":参数
- [root@master01 diff]# cat /etc/docker/daemon.json
- {
- "registry-mirrors": ["https://coy8g925.mirror.aliyuncs.com"],
- "exec-opts": ["native.cgroupdriver=systemd"],
- "log-driver": "json-file",
- "log-opts": {
- "max-size": "100m"
- },
- "storage-driver": "overlay2",
- "storage-opts": [
- "overlay2.override_kernel_check=true"
- ]
- }
下面我们就以Centos发行版的overlay2文件系统进行介绍,其实不管是什么发行版,其原理都如出一辙。
如上图所示,OverlayFS将单个Linux主机上的两个目录合并成一个目录,这些目录被称为层,统一过程被称为联合挂载。OverlayFS关联的底层目录称为lowerdir,lowerdir是只读的镜像层(image layer),其中就包含bootfs/rootfs层,bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,当boot成功 kernel 被加载到内存中,bootfs就被umount了,rootfs(root file system)包含的就是典型Linux系统中的/dev、/proc、/bin、/etc等标准目录。lowerdir是可以分很多层的,除了bootfs/rootfs层以外,还可以通过Dockerfile建立很多image层。
对应的高层目录upperdir层是lowerdir的上一层,只有这一层可读可写的,其实就是Container层,在启动一个容器的时候会在最后的image层的上一层自动创建,所有对容器数据的更改都会发生在这一层。
联合挂载后merged层就是联合挂载层,也就是给用户暴露的统一视觉,将image层和container层结合,就如最上边的图中描述一致,同一文件,在此层会展示离它最近的层级里的文件内容,或者可以理解为,只要container层中有此文件,便展示container层中的文件内容,若container层中没有,则展示image层中的。
如下容器的整体结构
在centos操作系统下,对应联合文件系统overlay2目录是:/var/lib/docker/overlay2,使用docker inspect [容器ID]就可以看到这几个层所在的位置。示例
- "GraphDriver": {
- "Data": {
- "LowerDir": "/var/lib/docker/overlay2/102d27169c96ad73ae4213a447c69b8e14087cd79d9e666c2003429f865ac5fb-init/diff:/var/lib/docker/overlay2/a53aa8c552f5b9b40d4b94129d537441b968337c56d04ad465fccf1eec7b37de/diff:/var/lib/docker/overlay2/4b00943a82da4802be44f92017a82238bb0ae06f96580853c656984b62186b49/diff:/var/lib/docker/overlay2/bb812dc007c420ff6c38b9611847fce1cda5238afd062cd30b22a6f2f753d894/diff:/var/lib/docker/overlay2/a316058c91cf41f77fe2a9ba7930892691d28666bf4a10334f9fdf53665080f0/diff:/var/lib/docker/overlay2/4adf725bc5b919de590d71f3d89d0d11390b119223a7ab8dc13042253b33a109/diff:/var/lib/docker/overlay2/f576260e3b514adb4ce01668655d844680cdd8d6a0d9944363b0fa911fe70e23/diff:/var/lib/docker/overlay2/1acd908dc03b74b46c9b5a0874094e6f1e4ac5f941a92bc156eaa0ed6526a83b/diff:/var/lib/docker/overlay2/7564ce96c2b6969404180c8cf21c6a6f38f910c603c44c5c334c5a313d733bde/diff:/var/lib/docker/overlay2/033b441edd57c8fd0ed4ce92ffcdd75558edb027931ba43299f441d491c9b505/diff:/var/lib/docker/overlay2/e1b6ed62f93346445da2850f67b0bd2db38fdb48ce80f8f2dab18c0911ec68ab/diff:/var/lib/docker/overlay2/b93cb93f4a4c31c55cdacf68e206c2242198edd9987a10c1cc4e97f740f43caa/diff:/var/lib/docker/overlay2/caca9bc683e4219d42032ea936eb2e7c9bbc2e7b9794a86ffc82f751bfef55cc/diff:/var/lib/docker/overlay2/8b9134c075f56815dce7cf90c4ee0969059776eb3a51a65fcac2c72db9880376/diff:/var/lib/docker/overlay2/bc0532b62b0b18999419346eac9ba6be627b671a44087c25779dcf8fcf7f5fbe/diff",
- "MergedDir": "/var/lib/docker/overlay2/102d27169c96ad73ae4213a447c69b8e14087cd79d9e666c2003429f865ac5fb/merged",
- "UpperDir": "/var/lib/docker/overlay2/102d27169c96ad73ae4213a447c69b8e14087cd79d9e666c2003429f865ac5fb/diff",
- "WorkDir": "/var/lib/docker/overlay2/102d27169c96ad73ae4213a447c69b8e14087cd79d9e666c2003429f865ac5fb/work"
- },
- "Name": "overlay2"
- },
启动镜像时挂载的目录以及镜像中的文件都可以在这里找到
/var/lib/docker/overlay2/
/var/lib/docker/overlay2/
/var/lib/docker/overlay2/
/var/lib/docker/overlay2/
容器启动不了的一个处理技巧
如果在管理容器的时候,通过docker exec编辑容器里面的文件造成容器启动不了,通过通过docker inspect查看对应容器的UpperDir,在Linux操作系统层级进入UpperDir的目录下,找到对应的文件,修改成正确的就可以了。