推荐阅读#
SlimToolkit 是什么#
SlimToolkit(原名 DockerSlim)用来精简 Docker 镜像,解决镜像太大、启动慢的问题,顺带减少攻击面。实际能减多少看应用,官方说能缩到原来的几十分之一,别当成承诺。
它的工作方式比较特殊:不是静态扫文件,而是真的把容器跑起来,用 ptrace 跟踪运行过程中实际访问了哪些文件,再只把这些文件打进新镜像。所以精简效果好不好,前提是探针跑测试时覆盖了应用真正会走的代码路径——漏掉的路径对应文件会被删掉,等运行到才报缺文件。
安装#
使用官方安装脚本进行一键安装:
curl -sL https://raw.githubusercontent.com/slimtoolkit/slim/master/scripts/install-slim.sh | sudo -E bash -
验证安装#
slim --version
GitLab CI/CD 集成#
在流水线的 build 之后加一个 optimize 阶段,对刚构建好的镜像跑 slim。
基础流水线配置#
stages:
- build
- optimize
- deploy
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: "/certs"
build-image:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
optimize-image:
stage: optimize
image: docker:latest
services:
- docker:dind
before_script:
- apk add --no-cache curl
- curl -sL https://raw.githubusercontent.com/slimtoolkit/slim/master/scripts/install-slim.sh | sh -
script:
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- slim build --target $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA-slim
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA-slim
示例项目#
完整的集成示例整理在 GitLab 仓库:mshekow-docker-slim-example,包含自动构建、优化前后对比和多环境部署,可以直接跑。
几个实际会碰到的问题#
1. 应用测试用例设计#
为确保精简后的镜像正常运行,需要设计全面的测试用例:
# 示例:Web 应用测试用例
slim build --target myapp:latest \
--http-probe-cmd /health \
--http-probe-cmd /api/status \
--include-path /app/config \
--include-path /app/static
2. 关键文件保护#
对于特定应用场景,需要显式包含必要文件:
# 保护配置文件和静态资源
slim build --target myapp:latest \
--preserve-path /etc/ssl/certs \
--preserve-path /app/templates \
--preserve-path /usr/share/zoneinfo
3. 分阶段优化#
# 渐进式优化策略
optimize-conservative:
script:
- slim build --target $IMAGE --continue-after 60s
optimize-aggressive:
script:
- slim build --target $IMAGE --remove-file-artifacts
精简后容易踩的坑#
精简靠的是运行时分析,所以动态加载的文件(运行到才加载的库、配置)最容易被误删。共享库和运行时依赖要特别留意,配置文件路径要确保被探针覆盖到,拿不准的用 --include-path 或 --preserve-path 显式保留。
验证环节别省:功能测试走一遍核心业务路径,确认没缺文件;镜像拉取和启动时间对比一下,看优化有没有实际收益。
用之前要想清楚的#
最大的代价是调试:精简后的镜像没有 shell、没有常用工具,出了问题基本没法进容器排查,建议保留一份未精简的镜像专门用于调试。其次是测试负担变重,要保证探针覆盖所有路径,否则生产环境会随机缺文件。
换来的好处是镜像小、拉取快、攻击面小。适合镜像多、拉取慢的场景,比如大量微服务重复构建、边缘节点带宽受限。需要频繁调试的环境,权衡一下再上。
