尧图精选

ClickHouse 裸机镜像(bare image)深度解析:从 scratch 验证数据库的最小操作系统依赖

🕒 发布时间:2026/9/10 19:48:22 📁 来源:尧图网络
ClickHouse 裸机镜像bare image深度解析从 scratch 验证数据库的最小操作系统依赖【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse导读本文围绕仓库docker/bare/目录下的最小 ClickHouse Docker 镜像展开讲解如何以FROM scratch构建一个仅包含单一二进制与核心 glibc 运行库的 ClickHouse 容器并用它依次运行clickhouse local、clickhouse client与clickhouse server从而精确检验 ClickHouse 对宿主操作系统除内核外的隐式依赖边界。读完本文你将掌握 bare 镜像的prepare构建脚本细节、三种运行方式、chroot 替代方案并理解它与仓库中 Ubuntu / Alpine / Distroless 等完整镜像的定位差异。一、bare 镜像是什么一个能跑就行的最小容器在 docker/bare/README.md 中ClickHouse 官方给出了一个极具实验性质的 Docker 镜像——bare裸机镜像。它的定位不是生产部署而是一个showcase展示品用于检查 ClickHouse 在操作系统内核之外对操作系统还隐式依赖了多少东西。这句话是理解整个镜像的钥匙。ClickHouse 通常以 Ubuntu、Alpine 等发行版镜像为基础分发这些镜像携带了大量文件系统工具、库文件、配置与用户体系。bare 镜像则反其道而行之它从一个完全空白的scratch根文件系统出发只把让 ClickHouse 能运行起来的最小文件集合塞进去用结果反向回答——一个不含任何发行版软件的容器究竟能否把 ClickHouse 跑起来从源码结构看整个 docker/bare 目录只有三个文件分工非常清晰文件作用Dockerfile仅两行FROM scratchADD root /把prepare生成的root/目录整体拷入空镜像prepare一个 bash 脚本负责组装root/目录的内容二进制、动态库、配置文件README.md使用说明与镜像缺失项清单二、构建流程prepare脚本逐行拆解构建 bare 镜像的第一步是运行prepare脚本它会基于当前仓库已经编译好的构建产物组装根文件系统。核心命令如下源码见 docker/bare/prepare./prepare docker build --tag clickhouse-bare .prepare脚本内部的关键逻辑可以拆成几段理解1. 定位构建产物SRC_DIR../.. BUILD_DIR${SRC_DIR}/build脚本假定你已经在ClickHouse仓库根目录执行过 CMake 构建产物位于build/programs/clickhouse。也就是说bare 镜像使用的是本地编译出的 ClickHouse 单一二进制而不是从官方仓库下载的发行包——这正是它能够精确反映当前这个构建运行时依赖的前提。2. 组装最小目录骨架mkdir root pushd root mkdir lib lib64 etc tmp root cp ${BUILD_DIR}/programs/clickhouse .创建了lib、lib64、etc、tmp、root五个目录并拷贝 ClickHouse 主二进制到根目录命名为/clickhouse。3. 拷贝动态库——隐式依赖的核心证据cp /lib/x86_64-linux-gnu/{libc.so.6,libdl.so.2,libm.so.6,libpthread.so.0,librt.so.1,libnss_dns.so.2,libresolv.so.2} lib cp /lib64/ld-linux-x86-64.so.2 lib64这是整个脚本最有信息量的一行。ClickHouse 在构建时大量使用静态链接内置第三方依赖但它仍然需要这 7 个来自宿主发行版的动态库libc.so.6 / ld-linux-x86-64.so.2glibc 本体与动态链接器任何 glibc 构建的 ELF 程序都离不开libdl.so.2 / libm.so.6 / libpthread.so.0 / librt.so.1glibc 的动态装载、数学函数、线程与实时时钟模块libnss_dns.so.2 / libresolv.so.2DNS 名字解析组件——ClickHouse 需要解析主机名才能工作。注意脚本中有一句注释点明了这一点BTW, .so files are acceptable from any Linux distribution for the last 12 years (at least).顺带一提至少近 12 年来.so 文件可以来自任何 Linux 发行版。这解释了为什么可以放心把宿主机上的 glibc 直接拷进镜像——glibc 在二进制层面具有良好的跨发行版兼容性。4. 网络配置与瘦身cp /etc/resolv.conf ./etc strip clickhouse拷贝/etc/resolv.conf为容器提供 DNS 解析配置与上面的libnss_dns.so.2、libresolv.so.2配套使用执行strip clickhouse去掉调试符号进一步缩小镜像体积。5. chroot 专用的注释段# This is needed for chroot but not needed for Docker: # mkdir proc # sudo mount --bind /proc proc脚本末尾注释掉了proc目录的挂载逻辑因为 Docker 会自动提供/proc但如果你打算用 chroot 方式运行就需要手动取消注释并绑定挂载/proc。6. 仅两行的 Dockerfiledocker/bare/Dockerfile 的简洁程度令人印象深刻FROM scratch ADD root /scratch是 Docker 中一个预置的空镜像不包含任何文件。ADD root /把prepare脚本组装好的整个目录树原样作为镜像的根文件系统。最终镜像里没有 shell、没有包管理器、没有 init 系统、没有用户体系——只有一个 ClickHouse 二进制和它赖以为生的几个库文件。三、三种运行方式local / client / server镜像构建完成后可以用同一个/clickhouse二进制以三种模式运行。官方 README 给出的命令均配合--network host原因在于 bare 镜像不含任何网络配置工具直接共享宿主网络命名空间最省事。1. 运行 clickhouse-localdocker run -it --rm --network host clickhouse-bare /clickhouse local --query SELECT 1clickhouse local是 ClickHouse 的无服务器模式不启动监听端口的守护进程直接在本地执行 SQL 并输出结果。这是验证 bare 镜像依赖是否齐全最快速的方式——一条SELECT 1足以确认二进制能正常加载动态库、初始化运行环境。2. 运行 clickhouse-client 交互式客户端docker run -it --rm --network host clickhouse-bare /clickhouse client/clickhouse是一个多命令的单一二进制类似 busybox 的架构client子命令会启动交互式客户端连接到默认地址通常是localhost:9000。配合--network host客户端可以直接访问宿主机上运行的 ClickHouse 服务器。3. 运行 clickhouse-serverdocker run -it --rm --network host clickhouse-bare /clickhouse server这是最有说服力的一种运行方式在没有任何发行版文件系统、没有clickhouse系统用户、没有数据目录声明的情况下直接启动完整服务器。server子命令会读取默认路径如/etc/clickhouse-server/config.xml的配置由于 bare 镜像没有这些文件实际运行时会退回到编译期内置的默认配置与默认数据目录/var/lib/clickhouse等。4. 替代方案直接用 chroot 运行bare 镜像的文件系统本身就是一组普通目录因此完全可以用 chroot 替代 Dockersudo chroot . /clickhouse server前提是先把prepare脚本中的proc挂载注释取消并手动执行mkdir proc sudo mount --bind /proc proc这个用法恰好揭示了 bare 镜像并非 Docker 专属的特性——root/目录就是一个可以被 chroot 直接当作新根的最小 Linux 用户空间。四、底层原理ClickHouse 对操作系统的隐式依赖清单综合prepare脚本内容可以整理出 ClickHouse 运行时对操作系统的依赖层次操作系统内核进程调度、内存管理、系统调用fork、mmap、epoll、io_uring 等、/proc与/sys虚拟文件系统——这些由内核提供容器与宿主共享glibc 核心库libc.so.6、ld-linux-x86-64.so.2、libdl.so.2、libm.so.6、libpthread.so.0、librt.so.1——程序启动、内存分配、数学运算、线程与定时器的基础DNS 解析栈libnss_dns.so.2、libresolv.so.2/etc/resolv.conf——ClickHouse 需要解析远端主机名例如连接其他副本、Keeper 或外部字典时依赖的 NSSName Service Switch机制文件系统布局约定/tmp、/root、/etc等目录的存在性超出 bare 范围、但完整镜像具备的项clickhouse系统用户、CA 证书、/var/lib/clickhouse数据卷等。其中第 2、3 项正是 README 所称OS 之外的内核依赖的具体内容——bare 镜像通过实验证明了 ClickHouse 的隐式依赖收敛在一小撮 glibc 库和 DNS 配置上其余第三方依赖均已静态编入二进制。五、横向对比从 bare 到 Ubuntu / Alpine / Distrolessbare 镜像的价值需要在与仓库内其他镜像的对比中才能完全显现。docker/目录下共维护了多套镜像方案1. 官方 Ubuntu 镜像docker/server/Dockerfile以ubuntu:22.04为基础是功能最完整的生产镜像显式创建clickhouse用户与组固定 uid/gid 为 101注释说明这是为了 rootless 容器与 OpenShift 任意 uid 场景安装ca-certificates、locales、tzdata、busybox等基础软件声明VOLUME /var/lib/clickhouse持久化数据暴露9000native 协议、8123HTTP 接口、9009副本间通信端口提供 entrypoint.sh 与 docker_related_config.xml 实现环境变量驱动的用户/数据库初始化。2. Alpine 镜像docker/server/Dockerfile.alpine以alpinemusl libc为基底但通过glibc-donor多阶段构建从 Ubuntu 借用整套 glibc 库libc.so.6、libdl.so.2、libnss_*.so.2等——这恰恰从侧面印证了 bare 镜像揭示的事实ClickHouse 的 glibc 依赖集合是可枚举、可移植的。3. Distroless 镜像docker/server/Dockerfile.distroless更进一步基于gcr.io/distroless/base-nossl-debian13:nonroot不含 shell、包管理器与 coreutils入口直接使用编译好的clickhouse docker-init子命令对应源码 programs/docker-init/docker-init.cpp以非 root 用户uid/gid 101运行。4. 定位总结镜像基础用户体系shell证书适用场景barescratch无无无依赖研究 / 最小化验证Ubuntuubuntu:22.04clickhouse (101)busybox有通用生产部署Alpinealpine glibc 移植clickhouse (101)busybox有体积敏感的生产部署Distrolessdistroless-debian13101:101无无强安全加固场景六、它缺失了什么bare 镜像的边界清单docker/bare/README.md 末尾如实列出了 bare 镜像相比完整镜像缺少的部分clickhouse系统用户服务器进程默认以 root 运行缺少运行服务器的专用低权限用户数据卷VOLUME没有为服务器声明任何持久化卷数据落在容器可写层容器删除即丢失CA 证书没有证书信任链基于 TLS 的对外连接HTTPS、加密副本通信等会无法验证其他大量细节官方 README 明确see other docker images for comparison参见仓库中其他镜像作对比完整差异可对照 docker/server/README.md 阅读。这四条缺失清单反过来定义了 bare 镜像的使用边界它适合实验、教学、依赖审计与镜像瘦身研究但不适合任何依赖 DNS 解析、TLS、多用户权限隔离或数据持久化的生产场景。七、结语把隐式依赖变成显式知识bare 镜像虽然只有三个文件、几十行脚本却完成了一次漂亮的减法实验它用FROM scratch证明了 ClickHouse 的运行时内核之外依赖被收敛到了 glibc 动态库与 DNS 配置这一可枚举的小集合上。对镜像维护者而言它是审计依赖变化的探针——一旦未来某个构建开始需要新的动态库prepare脚本必须同步更新否则clickhouse local --query SELECT 1会立即失败对开发者而言它也是一个理解容器最小化与静态/动态链接边界的绝佳教学样本。下次当你思考ClickHouse 到底依赖操作系统什么时不妨亲手构建一次 bare 镜像让实验替你回答。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →