1. 介绍 Overlay2 的基本原理
Overlay2 是一种联合文件系统(Union Filesystem),它允许将多个目录(称为层)合并成一个统一的视图。Overlay2 的主要用途是在容器技术中,用于构建容器的文件系统。它的核心思想是通过将多个只读层和一个可写层叠加在一起,形成一个单一的文件系统视图。
Overlay2 的组成
- Lowerdir(下层目录):只读层,通常包含基础镜像的文件系统。
- Upperdir(上层目录):可写层,用于存储对文件系统的修改。
- Workdir(工作目录):用于 Overlay2 内部操作的工作目录。
- Merged(合并目录):最终呈现的统一视图,用户通过这个目录访问文件系统。
Overlay2 的工作原理
- 文件读取:当用户访问
merged
目录时,Overlay2 会优先从upperdir
查找文件。如果文件不存在,则从lowerdir
查找。 - 文件写入:当用户修改文件时,Overlay2 会将修改写入
upperdir
,而不会影响lowerdir
的内容。 - 文件删除:删除文件时,Overlay2 会在
upperdir
中创建一个“白名单”文件,标记该文件已被删除。
2. 介绍 Overlay2 的使用方法
2.1 创建目录结构
首先,创建一个包含 lower
、upper
、work
和 merged
的目录结构:
root@compute01:~# mkdir -p rootfs/{lower,upper,work,merged}
root@compute01:~# mkdir -p rootfs/lower/{bin,lib,lib64,proc}
2.2 准备 Lowerdir
在 lower
目录中放置基础文件系统。例如,复制 bash
及其依赖库:
root@compute01:~# cp /bin/bash rootfs/lower/bin/
查看程序是静态连接还是动态连接:
root@compute01:~# file /bin/bash
/bin/bash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7a6408ba82a2d86dd98f1f75ac8edcb695f6fd60, for GNU/Linux 3.2.0, stripped
dynamically linked 动态连接,依赖系统的动态链接库
查看动态链接库的依赖:
root@compute01:~# ldd /bin/bash linux-vdso.so.1 (0x00007ffec584f000)libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f5110bcf000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f51109a6000)/lib64/ld-linux-x86-64.so.2 (0x00007f5110d6e000)
2.3 使用脚本复制依赖库
创建脚本 create_container_bin.sh
,用于检测可执行文件的依赖库,自动移动到对应的目录:
#!/bin/bash
# ./create_container_bin.sh shell命令
# example:./create_container_bin.sh bash# 检查是否提供了命令参数
if [ -z "$1" ]; thenecho "Usage: $0 <command>"exit 1
fi# 获取命令的绝对路径
command_path=$(which $1)# 检查命令是否存在
if [ ! -f "$command_path" ]; thenecho "Command $1 not found"exit 1
fi# 创建目标目录
lowdir_target_dir="rootfs/lower"
bindir_target_dir="rootfs/lower/bin"
mkdir -p $lowdir_target_dir
mkdir -p $bindir_target_dir# 获取命令的依赖库并复制到目标目录
ldd $command_path | egrep -o '/lib[^\ ]*' | while read lib; do# 检查库文件是否存在,防止某些库文件可能丢失或不存在if [ -f "$lib" ]; thencp --parents $lib $lowdir_target_direlseecho "Library $lib not found, skipping."fi
done# 复制命令到rootfs/bin目录
cp $command_path $bindir_target_direcho "All dependencies copied to $lowdir_target_dir"
echo "Command $1 copied to $bindir_target_dir"
复制 bash
环境到 rootfs
目录:
root@compute01:~# ./create_container_bin.sh bash
All dependencies copied to rootfs/lower
Command bash copied to rootfs/lower/bin
查看 rootfs/lower
目录结构:
root@compute01:~# tree rootfs/lower/
rootfs/lower/
├── bin
│ ├── bash
│ ├── ls
│ ├── mount
│ ├── ps
│ └── umount
├── lib
│ └── x86_64-linux-gnu
│ ├── libblkid.so.1
│ ├── libc.so.6
│ ├── libcap.so.2
│ ├── libgcrypt.so.20
│ ├── libgpg-error.so.0
│ ├── liblz4.so.1
│ ├── liblzma.so.5
│ ├── libmount.so.1
│ ├── libpcre2-8.so.0
│ ├── libprocps.so.8
│ ├── libselinux.so.1
│ ├── libsystemd.so.0
│ ├── libtinfo.so.6
│ └── libzstd.so.1
└── lib64└── ld-linux-x86-64.so.24 directories, 20 files
2.4 挂载 Overlay2 文件系统
使用 mount
命令挂载 Overlay2 文件系统:
root@compute01:~# mount -t overlay overlay -o lowerdir=./rootfs/lower,upperdir=./rootfs/upper,workdir=./rootfs/work ./rootfs/merged/
2.5 创建命名空间并切换根文件系统
使用 unshare
创建新的命名空间,并通过 chroot
切换到 merged
目录:
root@compute01:~# unshare --fork --pid --mount --uts --ipc --net --user --map-root-user chroot rootfs/merged /bin/bash
bash-5.1#
2.6 挂载虚拟文件系统
在新的命名空间中挂载 /proc
文件系统:
bash-5.1# mount -t proc proc /proc
2.7 验证环境
运行 ps
命令查看进程信息,验证环境是否正常工作:
bash-5.1# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
0 1 0.0 0.0 8160 4240 ? S 12:14 0:00 /bin/bash
0 8 0.0 0.0 4604 3724 ? S 12:14 0:00 /bin/bash
0 14 0.0 0.0 7064 2384 ? R+ 12:15 0:00 ps -aux
查看 /proc
目录:
bash-5.1# ls proc/
1 cgroups dma interrupts keys mdstat pagetypeinfo softirqs timer_list zoneinfo
13 cmdline driver iomem kmsg meminfo partitions stat tty
8 consoles dynamic_debug ioports kpagecgroup misc pressure swaps uptime
acpi cpuinfo execdomains irq kpagecount modules schedstat sys version
bootconfig crypto fb kallsyms kpageflags mounts scsi sysrq-trigger version_signature
buddyinfo devices filesystems kcore loadavg mtrr self sysvipc vmallocinfo
bus diskstats fs key-users locks net slabinfo thread-self vmstat
2.8 退出并清理
退出容器环境并卸载 Overlay2 文件系统:
bash-5.1# exit
exit
root@compute01:~# umount /root/rootfs/merged
3. 结合实验过程说明 Overlay2 的使用方法
在实验中,我们通过以下步骤完成了 Overlay2 的使用:
- 创建了
rootfs
目录结构,包括lower
、upper
、work
和merged
。 - 使用
create_container_bin.sh
脚本复制bash
及其依赖库到lower
目录。 - 挂载 Overlay2 文件系统,将
lower
和upper
目录合并到merged
目录。 - 使用
unshare
创建新的命名空间,并通过chroot
切换到merged
目录。 - 挂载
/proc
文件系统,验证容器环境。 - 退出容器并卸载 Overlay2 文件系统。
4. 总结 Overlay2 的优点和缺点
优点
- 高效的文件系统管理:通过只读层和可写层的分离,减少了文件系统的冗余。
- 快速启动:容器可以共享基础镜像的只读层,减少了启动时间。
- 节省存储空间:多个容器可以共享同一个基础镜像,减少了存储开销。
缺点
- 复杂性:Overlay2 的实现较为复杂,调试和维护需要一定的技术能力。
- 性能开销:在频繁修改文件的情况下,
upperdir
可能会成为性能瓶颈。 - 依赖底层文件系统:Overlay2 的性能和稳定性依赖于底层文件系统(如 ext4、xfs 等)。
Overlay2 在容器技术中扮演了重要角色,为容器的文件系统管理提供了高效、灵活的解决方案。希望这篇博客能帮助你更好地理解 Overlay2!