docker 联合文件系统 深入解读
[toc]
作用
获取容器/镜像的元数据(JSON格式)
命令格式
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
options 说明
option | 说明 |
---|---|
-f | 指定返回值的模板文件 |
-s | 如果类型为容器,则显示文件总大小 |
--type | 返回指定类型的JSON |
筛选
获取 IP 地址:
docker inspect tomcat7 | grep IPAddress
获取 Dir :
我主要是希望很熟悉 Data 字段,所以后面重点说明~
[root@VM-4-6-centos 123]# docker inspect -s 40da9cff87a0 |grep "Dir"
"LowerDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57-init/diff:/var/lib/docker/overlay2/2e6f81e45b3db01494296c925185d77831443eca0dd3cbf119f8d32190f90d5c/diff:/var/lib/docker/overlay2/ebf60447144fb679348fc4534bc30b68ce19618aac23b39ee93e5f941d6b13bc/diff:/var/lib/docker/overlay2/eb6694dc2ad08ab91f8f4e3f00bf7481d2c59df52c3a1553f0b7f3c3512179ed/diff:/var/lib/docker/overlay2/c4acacb9aa7f0e60af79eeb6cb7506d736df1789710da7f7e53747feffaead95/diff:/var/lib/docker/overlay2/29165236db2b92b69ae83bc679d17cf7237880dde09e5d3c1f5890ca6e907861/diff:/var/lib/docker/overlay2/3b17651312652668a9c2ef61df2a957ca7ceeb6307166a23a5726ca8dbaf1c23/diff:/var/lib/docker/overlay2/23a2a19d74c1945307e606a0df77496e2bdca76b85ea9058bd76a1cb9e1be205/diff:/var/lib/docker/overlay2/2916a80e9370af849f411871cad64cbb13d04617c91e66f45a16cbe979ffe88f/diff:/var/lib/docker/overlay2/d78b6c08a6749d7b88e7eb4fac33de1355cb1d926fcb01a8b1c72361d1867cbc/diff:/var/lib/docker/overlay2/be49972d15fe94755593cfd846c231d2a18e625a256fa86fe62e131e711f200a/diff",
"MergedDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57/merged",
"UpperDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57/diff",
"WorkDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57/work"
"WorkingDir": "/application",
docker GraphDriver
这里我们了解一下 docker 的镜像存储,在Docker中,一个很重要的概念就是 GraphDriver
,它主要用于管理和维护镜像,包括把镜像从仓库下载下来,到运行时把镜像挂载起来可以被容器访问等,都是GraphDriver
去完成的。
我们以 Golang 镜像为准:
docker inspect -s golang
字段 GraphDriver:
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57-init/diff:/var/lib/docker/overlay2/2e6f81e45b3db01494296c925185d77831443eca0dd3cbf119f8d32190f90d5c/diff:/var/lib/docker/overlay2/ebf60447144fb679348fc4534bc30b68ce19618aac23b39ee93e5f941d6b13bc/diff:/var/lib/docker/overlay2/eb6694dc2ad08ab91f8f4e3f00bf7481d2c59df52c3a1553f0b7f3c3512179ed/diff:/var/lib/docker/overlay2/c4acacb9aa7f0e60af79eeb6cb7506d736df1789710da7f7e53747feffaead95/diff:/var/lib/docker/overlay2/29165236db2b92b69ae83bc679d17cf7237880dde09e5d3c1f5890ca6e907861/diff:/var/lib/docker/overlay2/3b17651312652668a9c2ef61df2a957ca7ceeb6307166a23a5726ca8dbaf1c23/diff:/var/lib/docker/overlay2/23a2a19d74c1945307e606a0df77496e2bdca76b85ea9058bd76a1cb9e1be205/diff:/var/lib/docker/overlay2/2916a80e9370af849f411871cad64cbb13d04617c91e66f45a16cbe979ffe88f/diff:/var/lib/docker/overlay2/d78b6c08a6749d7b88e7eb4fac33de1355cb1d926fcb01a8b1c72361d1867cbc/diff:/var/lib/docker/overlay2/be49972d15fe94755593cfd846c231d2a18e625a256fa86fe62e131e711f200a/diff",
"MergedDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57/merged",
"UpperDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57/diff",
"WorkDir": "/var/lib/docker/overlay2/0a0abda0165a1342ddac4ba3263352d79564e9a56dfdb497ac66e25030bb5b57/work"
}
},
📜 对上面的解释
- LowerDir:包含容器内所有层的文件系统,最后一层除外
- UpperDir:容器最上层的文件系统。这也是反映任何运行时修改的地方。
- MergedDir:文件系统所有层的组合视图。
- WorkDir:用于管理文件系统的内部工作目录。
容器内
docker exec -it golang:latest /bin/bash
根目录:
root@cbd9c47e79e3:/# cd /; mkdir 111;cd 111; echo "this a test file" >> test.txt; ls
test.txt
go version go1.19.3 linux/amd64
root@cbd9c47e79e3:/111# whereis go
go: /usr/local/go /usr/local/go/bin/go
Go语言工作目录:
root@cbd9c47e79e3:/usr/local/go/bin# ls -al go
-rwxr-xr-x 1 root root 15301490 Oct 31 20:20 go
root@cbd9c47e79e3:/usr/local/go/bin# pwd
/usr/local/go/bin
root@cbd9c47e79e3:/usr/local/go/bin# ./go version
go version go1.19.3 linux/amd64
lower
最后一层除外
:这个意思就是我们的可写层,我们对容器的修改,都是在这层上面进行的,即我们容器里面的 cd /; mkdir 111;cd 111; echo "this a test file" >> test.txt;
这个文件在LowerDir里看不到。
MergedDir
在这里我们可以看到整个容器里面的文件系统,包括修改的(注意是容器)
[root@VM-4-6-centos merged]# cd /var/lib/docker/overlay2/4ff3e2faabfa51f38c884c1321e20609352f5e009239d146161ec75bc806c3c5/merged
[root@VM-4-6-centos merged]# ls
111 bin boot dev etc go home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
测试里面的环境变量
是不是可以将里面的 Go语言 环境变量位置配置到主机中???我觉得这样好玩
当前位置:
[root@VM-4-6-centos bin]# ls
go gofmt
[root@VM-4-6-centos bin]# pwd
/var/lib/docker/overlay2/4ff3e2faabfa51f38c884c1321e20609352f5e009239d146161ec75bc806c3c5/merged/usr/local/go/bin
[root@VM-4-6-centos bin]# cp go golangtext
加入环境变量:
[root@VM-4-6-centos bin]# cp go golangtext
# 加入环境变量
[root@VM-4-6-centos root]# cat /etc/profile.d/mypath
export GO_TEST=$"/var/lib/docker/overlay2/4ff3e2faabfa51f38c884c1321e20609352f5e009239d146161ec75bc806c3c5/merged/usr/local/go"
export PATH=$PATH:$GO_TEST/bin
测试:
[root@VM-4-6-centos root]# golangtext version
go: cannot find GOROOT directory: /root/.g/go
UpperDir
WorkDir
:用于管理文件系统的内部工作目录
我们在 Dockerfile 中可指定 workspaces,即使在 GitHub 的 codespaces 中,workspaces 也是非常重要的。
[root@VM-4-6-centos root]# cd /var/lib/docker/overlay2/4ff3e2faabfa51f38c884c1321e20609352f5e009239d146161ec75bc806c3c5/work
[root@VM-4-6-centos work]# ls
work
[root@VM-4-6-centos work]# cd work/
[root@VM-4-6-centos work]# ls
推荐文章
/proc/<pid>/root
我们到现在知道了 Pid
在 docker 中起到了多么重要的作用,这个关乎着我们未来构建 docker 的计划~
有一种更简单的方法可以从主机找到容器的文件系统。使用容器内进程的主机 PID,您可以简单地运行:
sudo ls /proc/<pid>/root
Linux 已经负责为您提供进程的挂载命名空间视图。
获取命名空间
提示
容器进程就像 Linux 主机上的其他进程一样,只在命名空间内运行,以使它们与系统的其余部分隔离。
因此,您可以使用 nsenter
命令输入目标容器的命名空间
# Get the host PID of the process in the container
PID=$(docker container inspect mycontainer | jq '.[0].State.Pid')
# Use nsenter to go into the container’s mount namespace.
sudo nsenter -m -t $PID /bin/bash
获取 PID
前提:我们知道了 容器 ID
docker inspect -f '{{.State.Pid}}'
💡简单的一个案例如下:
[root@VM-4-6-centos work]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cbd9c47e79e3 golang "bash" About an hour ago Up About an hour jolly_chandrasekhar
40da9cff87a0 docker.io/halohub/halo:1.6.0 "/bin/sh -c 'java ..." 11 days ago Restarting (1) 2 days ago halo-next
0b35d2dcb578 3293172751/halo_myblog:2.0 "/bin/sh -c 'java ..." 3 weeks ago Up 11 days 0.0.0.0:8090->8090/tcp halo2
[root@VM-4-6-centos work]# docker inspect -f '{{.State.Pid}}' cbd9c47e79e3
1050
或者你还可以通过container 获取
docker container top
/proc/<pid>/root
查看[root@VM-4-6-centos work]# ll /proc/1050/root/
total 76
drwxr-xr-x 2 root root 4096 Nov 25 16:10 111
drwxr-xr-x 1 root root 4096 Nov 15 18:23 bin
drwxr-xr-x 2 root root 4096 Sep 3 20:10 boot
drwxr-xr-x 5 root root 360 Nov 25 15:28 dev
drwxr-xr-x 1 root root 4096 Nov 25 15:28 etc
drwxrwxrwx 4 root root 4096 Nov 16 12:16 go
drwxr-xr-x 2 root root 4096 Sep 3 20:10 home
drwxr-xr-x 1 root root 4096 Nov 16 12:16 lib
drwxr-xr-x 2 root root 4096 Nov 14 08:00 lib64
drwxr-xr-x 2 root root 4096 Nov 14 08:00 media
drwxr-xr-x 2 root root 4096 Nov 14 08:00 mnt
drwxr-xr-x 2 root root 4096 Nov 14 08:00 opt
dr-xr-xr-x 159 root root 0 Nov 25 15:28 proc
drwx------ 2 root root 4096 Nov 14 08:00 root
drwxr-xr-x 1 root root 4096 Nov 25 15:28 run
drwxr-xr-x 1 root root 4096 Nov 15 18:23 sbin
drwxr-xr-x 2 root root 4096 Nov 14 08:00 srv
dr-xr-xr-x 13 root root 0 Nov 25 15:28 sys
drwxrwxrwt 1 root root 4096 Nov 16 12:16 tmp
drwxr-xr-x 1 root root 4096 Nov 14 08:00 usr
drwxr-xr-x 1 root root 4096 Nov 14 08:00 var
容器进程目录下有什么?
[root@VM-4-6-centos work]# cd /proc/1050/
[root@VM-4-6-centos 1050]# ls
attr comm fd map_files net pagemap schedstat statm wchan
autogroup coredump_filter fdinfo maps ns patch_state sessionid status
auxv cpuset gid_map mem numa_maps personality setgroups syscall
cgroup cwd io mountinfo oom_adj projid_map smaps task
clear_refs environ limits mounts oom_score root stack timers
cmdline exe loginuid mountstats oom_score_adj sched stat uid_map
查看 /mountinfo
[root@VM-4-6-centos 1050]# cat mountinfo | head -n 10
659 493 0:157 / / rw,relatime - overlay overlay rw,lowerdir=/var/lib/docker/overlay2/l/PIDEMVBEIEE3VONRURI4Z4EUJX:/var/lib/docker/overlay2/l/BWR7ZEPY4UYAKRS3ZCHZZ6EGTP:/var/lib/docker/overlay2/l/34HR5PAPLZ5473EG5FNPRQLLYQ:/var/lib/docker/overlay2/l/AGIW6BJEBXJNUEBZI67DHV73UC:/var/lib/docker/overlay2/l/6XDUP6AULW7Z4AT5NPHVTGD4SH:/var/lib/docker/overlay2/l/WRKLDD6PZE5FYTSPKPED7F3N7L:/var/lib/docker/overlay2/l/PLPE7MKV5TXKVZFBCSK7ZPA7FD:/var/lib/docker/overlay2/l/BT7MBYLOPX66TO6QWWYBELSZN2,upperdir=/var/lib/docker/overlay2/4ff3e2faabfa51f38c884c1321e20609352f5e009239d146161ec75bc806c3c5/diff,workdir=/var/lib/docker/overlay2/4ff3e2faabfa51f38c884c1321e20609352f5e009239d146161ec75bc806c3c5/work
660 659 0:160 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
661 659 0:161 / /dev rw,nosuid - tmpfs tmpfs rw,mode=755
662 661 0:162 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=666
663 659 0:163 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro
664 663 0:164 / /sys/fs/cgroup ro,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755
665 664 0:22 /system.slice/docker-cbd9c47e79e39457d638b8d0552aeb2c646dbd7ade72f41f8ffc48ea91188322.scope /sys/fs/cgroup/systemd ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd
666 664 0:24 /system.slice/docker-cbd9c47e79e39457d638b8d0552aeb2c646dbd7ade72f41f8ffc48ea91188322.scope /sys/fs/cgroup/blkio ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio
667 664 0:25 /system.slice/docker-cbd9c47e79e39457d638b8d0552aeb2c646dbd7ade72f41f8ffc48ea91188322.scope /sys/fs/cgroup/hugetlb ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,hugetlb
668 664 0:26 /system.slice/docker-cbd9c47e79e39457d638b8d0552aeb2c646dbd7ade72f41f8ffc48ea91188322.scope /sys/fs/cgroup/net_prio,net_cls ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,net_prio,net_cls
可以看到容器已挂载了一个覆盖文件系统作为其根。它还报告与 docker inspect
报告相同类型的信息,包括容器文件系统的 LowerDir
和 UpperDir
。它不直接显示 MergedDir
,但您只需使用 UpperDir
并将 diff
更改为merged
,您就可以查看容器的文件系统。
最后
希望我们都可以深入理解容器,能尝试其中的一些技术。一旦你体验到不再受容器代码限制的自由,你可能再也回不去了。它所需要的只是简单地访问 //proc/<pid>/root
~