在制作docker镜像我们都希望能够制作一个超小的镜像,那么该怎么做呢,网上有很多优化镜像大小的方法,今天就不在重复了,今天给大家分享一个从源头控制大小的方案。
Docker Scratch镜像是一个特殊的Docker镜像,它不基于任何其他镜像构建。相反,它是一个空白的镜像,只包含了Docker运行所需的最小文件系统和执行环境。这使得它非常适合用于构建轻量级容器化应用程序,因为它不包含任何额外的组件或库。
这个镜像不需要下载,在dockerfile中直接FROM引用即可。
接下来给大家演示一下做一个有bash命令的但是非常小的一个镜像。
编写获取bash命令的动态库的脚本
[root@localhost cc]# cat get_lib_info.sh
#!/bin/bash
# 函数:使用 ldd 和 awk 提取库文件路径
extract_library_paths() {
local binary_path="$1"
local paths=()
# 运行 ldd 命令,过滤并提取库文件路径
while IFS= read -r line; do
if [[ "$line" =~ ^/ ]]; then
paths+=("$line")
fi
done < <(ldd "$binary_path" | awk '/=>/ {if ($3 ~ /^\//) print $3}')
while IFS= read -r line; do
if [[ "$line" =~ ^/ ]]; then
paths+=("$line")
fi
done < <(ldd "$binary_path" | awk '{print $1}' | grep '^/')
# 返回路径数组
echo "${paths[@]}"
}
# 函数:解析符号链接路径
resolve_symlinks() {
local path="$1"
# 处理可能存在的符号链接链
while [[ -L "$path" ]]; do
target=$(readlink "$path")
if [[ "${target:0:1}" != "/" ]]; then
target=$(dirname "$path")/"$target"
fi
path="$target"
done
# 输出最终的真实路径
echo "$path"
}
# 主函数:处理二进制文件并生成解析后的路径
process_binary() {
local binary="$1"
local output_path="${2:-$(dirname "$0")}" # 如果未提供第二个参数 $2,则默认为脚本所在目录
local binary_name=$(basename "$binary")
echo "二进制文件 $binary 的库文件路径:"
# 提取库文件路径
library_paths=($(extract_library_paths "$binary"))
# 解析符号链接路径
resolved_paths=()
for path in "${library_paths[@]}"; do
resolved_path=$(resolve_symlinks "$path")
resolved_paths+=("$resolved_path")
done
for path in "${library_paths[@]}"; do
resolved_paths+=("$path")
done
# 打印解析后的路径
# for path in "${resolved_paths[@]}"; do
# echo "$path"
# done
# 创建解析后路径的 tar 压缩包
tar_filename="${output_path}/${binary_name##*/}.tar.gz"
tar zcvf "$tar_filename" "${resolved_paths[@]}"
echo "已创建压缩包:$tar_filename"
}
# 示例用法:
binary="/bin/bash"
# output_directory="/tmp" # 如果需要,可以修改为你希望的输出目录
process_binary "$binary" "$output_directory"
mkdir /tmp/test
tar zxvf $tar_filename -C /tmp/test
编写Dockerfile
[root@localhost ]# cat Dockerfile
FROM ubuntu:20.04
COPY get_lib_info.sh /
RUN chmod +x /get_lib_info.sh && \
/get_lib_info.sh
FROM scratch
COPY --from=0 /bin/bash /bin/bash
COPY --from=0 /tmp/test /
CMD ["/bin/bash"]
构建镜像
[root@localhost ]# docker build -t mybash .
[root@localhost ]# docker images mybash
REPOSITORY TAG IMAGE ID CREATED SIZE
mybash latest 11f3508d3dd1 23 seconds ago 3.61MB
验证
[root@localhost ]# docker run -it --rm mybash
bash-5.0# exit
exit
[root@localhost ]#