swantron/minifier-cli
GitHub: swantron/minifier-cli
一款通过运行时追踪容器实际文件访问来自动构建极简 Docker 镜像的 Go 命令行工具。
Stars: 0 | Forks: 0
# minifier-cli
一款通过观察应用程序在运行时实际使用哪些文件,然后仅使用这些文件构建新镜像,从而创建最小化、安全加固容器镜像的工具。
## 它是什么
`minifier-cli` 通过以下方式创建显著更小且更安全的容器镜像:
1. **追踪** - 监控运行中的容器实际访问了哪些文件
2. **分析** - 解析依赖项并跟踪符号链接以查找所有必需的文件
3. **重新打包** - 仅使用必要文件构建新的 "FROM scratch" 镜像
**结果:** 体积减少 80-90%,同时保持完整功能。
## 工作原理
### 技术实现
**Tracer:**
- 使用 Docker 正常启动您的容器
- 后台 goroutine 每秒轮询一次
- 读取 `/proc/*/maps` 获取内存映射文件
- 读取 `/proc/*/fd` 获取打开的文件描述符
- 将去重后的文件列表写入追踪日志
**Analyzer:**
- 逐行解析追踪日志
- 使用 Go 的 `debug/elf` 包分析 ELF 二进制文件
- 提取导入的共享库(`.so` 文件)
- 查找动态链接器(PT_INTERP,如 `/lib64/ld-linux.so`)
- 递归解析所有依赖项
- 添加关键系统文件(passwd、group、hosts 等)
**Repackager:**
- 通过 JSON inspect 提取 Docker 元数据
- 保留 ENV、CMD、ENTRYPOINT、EXPOSE、VOLUME、LABEL、USER、WORKDIR
- 创建临时容器以从原始镜像复制文件
- 生成优化的 Dockerfile
- 从头构建新的最小化镜像
## 实际应用场景
### 1. 安全加固
**问题:** 第三方设备(如 Datadog Agent)附带不必要的工具,增加了攻击面。
**解决方案:**
```
minifier-cli trace start --image datadog/agent:latest --name dd-prod
# 在类似生产环境中运行 24 小时
# Ctrl+C 停止
minifier-cli repackage --name dd-prod --output datadog-minimal:prod
```
**结果:** 1.2GB → 150MB(减少 87%),移除了 shell、包管理器和调试工具
### 2. 法规合规性(NIST,PCI-DSS)
**问题:** 需要证明具有最小攻击面以满足合规性审计。
**优势:**
- 为审计人员提供确切的文件清单文档
- 满足“最小权限原则”要求
- 更容易进行安全扫描(需要检查的文件更少)
- 可重现的最小化构建
### 3. 遗留应用迁移
**问题:** 依赖未知的陈旧应用程序。
```
minifier-cli trace start --image legacy-app:old --name legacy
# 运行全面的测试套件以覆盖所有代码路径
# 完成后按 Ctrl+C
minifier-cli repackage --name legacy --output legacy-app:minimal
```
**结果:** 发现了确切的运行时需求,2.5GB → 300MB
### 4. CI/CD 优化
**问题:** Docker 拉取速度慢,registry 成本高。
**优势:**
- 更快的部署速度(nginx:80MB → 14MB)
- 降低数千次部署的存储成本
- 减少带宽使用
- 更快的自动伸缩
### 5. IoT / 边缘部署
**问题:** 边缘设备磁盘空间有限。
**优势:**
- 适用于资源受限的设备(Node.js:900MB → 120MB)
- 更快的 OTA 更新
- 每台设备可运行更多应用程序
### 6. 多阶段构建优化
**问题:** 不确定最终阶段应包含哪些文件。
**解决方案:** 追踪以发现实际依赖项,然后使用清单为 Dockerfile 的 COPY 语句提供依据。
## 与替代方案的比较
**对比多阶段 Docker 构建:**
- ✅ 自动化(无需手动选择文件)
- ✅ 基于运行时数据(而非猜测)
- ✅ 适用于任何现有镜像
**对比 Distroless 镜像:**
- ✅ 适用于现有镜像(无需重新构建)
- ✅ 保留您确切需要的依赖项
- ✅ 无需从头开始
**对比 Docker Slim:**
- ✅ 使用 Go 编写(更易于扩展)
- ✅ 简单的三步工作流
- ✅ 保留所有 Docker 元数据
## 安装
### 从源码构建
```
git clone https://github.com/swantron/minifier-cli
cd minifier-cli
go build -o minifier-cli .
```
## 最佳实践
### 追踪指南
**追踪具有代表性的工作负载:**
- 在类似生产环境中运行 24-48 小时
- 在追踪期间执行全面的测试套件
- 覆盖所有代码路径和功能
- 包括边缘情况和错误场景
**重要注意事项:**
⚠️ **必须访问启动文件:**
- Entrypoint 脚本需要被执行
- 可能需要针对不同模式进行多次追踪会话
⚠️ **动态加载:**
- 必须测试在运行时加载的插件
- 需要测试按名称加载数据库驱动程序
- 必须触发依赖于配置的功能
✅ **验证:**
- 在投入生产之前全面测试精简后的镜像
- 保留原始镜像作为备选
- 在 staging 环境中监控是否缺少文件
### 何时使用
**非常适合:**
- 对现有的第三方镜像进行安全加固
- 合规性要求(最小攻击面)
- 优化依赖未知的遗留应用
- 降低部署成本和带宽
- 有空间限制的边缘/IoT 部署
- 发现实际的运行时依赖项
**不适用于:**
- 您完全控制且可以正确重新构建的镜像
- 开发环境(需要调试工具)
- 行为频繁变化的镜像
- 具有复杂动态加载的应用程序
## 用法
### 交互模式 (v0.1)
该工具使用有状态的、多步骤的工作流:
#### 1. 开始追踪
```
minifier-cli trace start \
--image nginx:alpine \
--name my-nginx
```
此命令将:
- 以其默认配置启动容器
- 附加文件访问监视器以捕获访问的文件
- 将追踪到的文件写入临时目录
- 在前台运行(按 Ctrl+C 停止)
**注意:** Tracer 进程必须保持运行才能捕获文件。请在您可以保持打开的终端中运行它,或者使用 `tmux` 等终端多路复用器。
#### 2. 运行应用程序
在 tracer 运行期间,与您的容器交互以生成追踪数据:
```
# 在另一个终端中,生成流量
curl http://localhost:8080
curl http://localhost:8080/api/health
# 测试你需要的所有功能
# 发送类似生产的流量
# 运行你的测试套件
```
**运行具有代表性的时间段**(几分钟到几小时)以捕获所有必要的文件。
**⚠️ 警告**:您的精简镜像将仅包含在此追踪期间访问的文件。请确保运行您打算在生产中使用的每一项功能。
#### 3. 停止追踪
在运行 tracer 的终端中按 **Ctrl+C**。
容器继续在后台运行。追踪日志已保存并准备好进行分析。
#### 4. 重新打包
```
minifier-cli repackage \
--name my-nginx \
--output nginx-minimal:latest
```
此命令将:
- 读取追踪日志
- 分析 ELF 依赖项并解析符号链接
- 从原始镜像提取 Docker 元数据
- 仅复制必要的文件
- 构建新的 "FROM scratch" 镜像
**结果:** 体积大幅缩小且功能相同的镜像。
### 示例:完整工作流
```
# 1. 开始追踪 nginx
minifier-cli trace start --image nginx:alpine --name web
# 2. 在另一个终端中,生成 5 分钟的流量
for i in {1..300}; do
curl -s http://localhost:80 > /dev/null
sleep 1
done
# 3. 停止追踪(在追踪终端按 Ctrl+C)
# 4. 创建精简镜像
minifier-cli repackage --name web --output nginx-minimal:prod
# 5. 比较大小
docker images | grep nginx
# nginx:alpine 80.9MB
# nginx-minimal:prod 14MB (减小了 83%!)
# 6. 测试精简镜像
docker run -d -p 8080:80 nginx-minimal:prod
curl http://localhost:8080 # Should work!
```
### 高级选项
您也可以直接使用追踪日志:
```
minifier-cli repackage \
--log-file /path/to/trace.log \
--output minified-image:latest
```
## 工作原理(摘要)
1. **用户空间追踪**:每秒轮询 `/proc/*/fd` 和 `/proc/*/maps`,以捕获运行中容器内的所有文件访问
2. **依赖解析**:解析符号链接、ELF 二进制依赖项,并添加必要的系统文件
3. **镜像重新打包**:从原始镜像复制追踪到的文件,并从头构建新的最小化镜像
## 架构
```
minifier-cli/
├── cmd/ # CLI commands (cobra)
│ ├── root.go # Root command setup
│ ├── trace.go # trace start/stop commands
│ └── repackage.go # repackage command
├── pkg/
│ ├── session/ # Session state management
│ ├── tracer/ # eBPF tracer implementation
│ ├── analyzer/ # Dependency analysis engine
│ └── repackager/ # Docker image builder
└── main.go # Entry point
```
## 要求
- 已安装并正在运行 Docker
- 支持 eBPF 的 Linux 内核(用于追踪)
- `CAP_SYS_ADMIN` 和 `CAP_SYS_PTRACE` capabilities
## 限制
- **v0.1** 不支持 Java/JVM 应用程序
- 需要全面的手动测试以确保完全覆盖
- 仅捕获追踪期间内的文件访问
## 未来路线图
- **v0.2**:CI/测试套件模式 - 使用测试套件进行自动追踪
- 针对常见应用程序的配方文件(例如,`datadog.recipe.sh`)
- 增强的 ELF 依赖项解析
- 支持更多运行时环境
## 许可证
MIT — 查看 [LICENSE](LICENSE)。
## 贡献
欢迎贡献。请查看 [CONTRIBUTING.md](CONTRIBUTING.md) 了解指南。
## 测试
### 快速测试
运行自动化演示:
```
./demo.sh
```
或运行完整的测试套件:
```
./test.sh
```
请查看 [TESTING.md](TESTING.md) 获取详细的测试说明和场景。
### 运行单元测试
```
go test ./...
```
标签:Docker, Docker镜像, EVTX分析, WebSocket, 依赖分析, 安全防御评估, 容器, 日志审计, 系统减负, 请求拦截, 镜像构建, 镜像精简