多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

3分钟上手容器init工具tini:ENTRYPOINT到Docker --init的5种引入方式完全指南

3分钟上手容器init工具tini:ENTRYPOINT到Docker --init的5种引入方式完全指南 3分钟上手容器init工具tiniENTRYPOINT到Docker --init的5种引入方式完全指南【免费下载链接】tiniA tiny but valid init for containers项目地址: https://gitcode.com/gh_mirrors/ti/tinitini是一款专为容器打造的微型 init 工具它只占用约 10KB 的体积就能替你解决容器里 PID 1 不会回收僵尸进程、信号传递失灵这两大经典坑。本文带你用 3 分钟搞清楚 tini 是干什么的并给出从Docker --init参数到 DockerfileENTRYPOINT的5 种引入方式新手照抄即可。为什么容器需要 tini 这个 init 进程很多人第一次写 Dockerfile 就直接CMD [./app]然后踩到两个莫名其妙的坑僵尸进程堆积应用内部产生的子进程退出后无人收尸僵尸进程不断累积严重时耗尽 PID 让整个容器不可用SIGTERM 不生效docker stop发送的 SIGTERM 信号被 PID 1 默认忽略容器只能等 10 秒超时后被 SIGKILL 强杀优雅停机流程全部失效。tini 的全部工作就三件事简单到几乎没有学习成本启动你的真实程序作为它唯一的子进程把收到的信号转发给子进程保证默认信号处理器可用周期性回收僵尸进程并在第一个子进程退出时原样透传其退出码。核心逻辑全部在这一个 C 文件里src/tini.c官方说明见 README.md。3 分钟快速上手ENTRYPOINT 标准姿势把 tini 放进镜像后标准用法只有两行# 让 tini 成为 ENTRYPOINT注意 -- 分隔符 ENTRYPOINT [/tini, --] # 你的真实程序继续写在 CMD 里 CMD [/your/program, -and, -its, arguments]⚠️ 新手最容易忽略的细节务必带上--。如果启动时报tini: invalid option -- c之类的错误说明你的程序参数被 tini 误当成了自己的选项加上--即可。tini 自身的参数写在--之前例如/tini -v -- /your/program。参数解析逻辑见 src/tini.c。5 种引入方式从最省事到完全掌控方式一Docker 1.13 自带 tini直接加--init参数最省事✅如果你用的是 Docker 1.13 或更新版本包括所有 Docker CE 版本tini 已经内置在 Docker 里了什么都不用装docker run --init your-image一个参数搞定连 Dockerfile 都不用改。这是官方推荐的最快路径适合我不想改镜像的场景。方式二在 Dockerfile 中下载二进制并写入 ENTRYPOINT最通用需要固化在镜像里时从 Release 下载静态二进制即可整个文件只有 10KB 量级几乎不增加镜像体积ENV TINI_VERSIONv0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod x /tini ENTRYPOINT [/tini, --]两点贴心提示镜像启动失败时可换用静态链接版tini-static它只依赖自身、不再依赖 libc二进制有 GPG 签名密钥595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7和 SHA256 校验和安全敏感场景建议验证后再使用。方式三包装你已有的 entrypoint 脚本零改造老镜像镜像里已经有/docker-entrypoint.sh这类启动脚本不用推倒重来把 tini 套在外面一层ENTRYPOINT [/tini, --, /docker-entrypoint.sh]原有的启动逻辑原封不动tini 完全透明地接管信号转发与僵尸回收——这是迁移存量镜像成本最低的方式。方式四用系统包管理器直接安装最干净主流发行版的官方仓库都有 tini 现成包一条命令安装发行版安装命令安装后路径Alpine LinuxRUN apk add --no-cache tini/sbin/tiniDebianBusterapt-get install tini/usr/bin/tiniNixOSnix-env --install tini标准路径Arch LinuxAUR 源安装标准路径以 Alpine 为例装完照旧写 ENTRYPOINTRUN apk add --no-cache tini ENTRYPOINT [/sbin/tini, --] 注意不同发行版的安装路径不同/tini、/sbin/tini、/usr/bin/tiniENTRYPOINT 里别写错。方式五从源码编译 tini完全掌控想在旧内核头文件环境编译、或需要定制构建时仓库自带完整的 CMake 工程两条命令出二进制export CFLAGS-DPR_SET_CHILD_SUBREAPER36 -DPR_GET_CHILD_SUBREAPER37 cmake . make第一行的 CFLAGS 保证即使构建机内核头文件较旧 3.4产物也带 subreaper 支持——宿主内核能跑 Docker就一定能用得上它。构建配置见 CMakeLists.txt产物同时输出动态版tini和静态版tini-static。CI 环境的完整搭建参考 ci/run_build.sh 和 ci/install_deps.sh。常用参数速查表tini 的选项不多记住下面这张表就够用了选项定义见 src/tini.c参数作用对应环境变量典型场景-v最多 3 次提高详细输出级别TINI_VERBOSITY排查信号/退出码问题-s注册为 subreaperLinux ≥ 3.4TINI_SUBREAPERtini 无法以 PID 1 运行时回收僵尸-e code将指定退出码重映射为 0可多次使用—Java 应用收到 SIGTERM 后以 143 退出被判定为失败-g向整个子进程组发信号TINI_KILL_PROCESS_GROUPdocker stop时把信号传递给 shell 下的全部子进程-p signal父进程退出时 tini 收到的信号—守护进程/嵌套场景两个高频用法示例# Java 应用把 143SIGTERM视为正常退出 tini -e 143 -- java -jar app.jar # 让 Ctrl-C / docker stop 能终止整棵进程树 tini -g -- sh -c sleep 10⚠️ tini 检测到自己既不是 PID 1、又没注册为 subreaper 时会打印警告如果日志里没有这个警告说明僵尸回收链路是健康的。上手指令清单✅ 最快验证docker run --init your-image确认docker stop能优雅退出✅ 固化进镜像Dockerfile 加ENTRYPOINT [/tini, --]--不要省✅ 老镜像改造ENTRYPOINT [/tini, --, /your-entrypoint.sh]包装即可✅ 退出码异常先用-vvv看日志再用-e重映射或用-g处理进程组信号✅ 体积焦虑动态版约 10KB静态版不足 1MB可放心上生产。tini 把容器里最容易被忽视的 init 职责压缩成了一个极小的 C 程序。花 3 分钟把它加进你的镜像信号与僵尸进程这两类问题从此基本告别。【免费下载链接】tiniA tiny but valid init for containers项目地址: https://gitcode.com/gh_mirrors/ti/tini创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表