Docker 镜像优化与安全?

2025年 阅读约 10 分钟 面试指南 · Linux/Docker

深入解析Docker镜像优化与安全:镜像瘦身策略、安全扫描工具(Trivy/Clair)、镜像签名(Docker Content Trust)、私有仓库Harbor、容器运行时安全,附面试模拟问答。

一句话总结

Docker 镜像优化:选最小基础镜像(alpine < slim < 完整版)、多阶段构建(分离构建与运行)、合并 RUN 层(减少镜像层数)、.dockerignore(排除无关文件)。安全实践:非 root 运行(USER 指令)、镜像安全扫描(Trivy/Clair 扫描 CVE 漏洞)、镜像签名(Docker Content Trust 防篡改)、私有仓库(Harbor 提供漏洞扫描+镜像管理)、只读文件系统(--read-only)、限制资源(--memory/--cpus)。

初级理解

镜像瘦身策略

# 1. 选择最小基础镜像 # Java 应用镜像大小对比: # openjdk:11 → ~600MB(完整 JDK) # openjdk:11-jre → ~300MB(只有 JRE) # openjdk:11-jre-slim → ~200MB(精简版) # openjdk:11-jre-alpine → ~100MB(Alpine Linux) # distroless-java:11 → ~120MB(Google 无发行版) # 2. 多阶段构建(前面已讲) # 构建阶段用 maven:3.8-openjdk-11 # 运行阶段用 openjdk:11-jre-slim # 最终镜像不含 Maven/JDK 编译工具 # 3. 减少层数 # 不推荐(4层): RUN apt update RUN apt install -y curl RUN apt install -y vim RUN apt clean # 推荐(1层): RUN apt update && \ apt install -y curl vim && \ apt clean && \ rm -rf /var/lib/apt/lists/* # 4. 清理临时文件 # 在同一个 RUN 中安装和清理 # 不要在单独的 RUN 中清理(前面的层已固化)

中级深入

镜像安全扫描

# Trivy(Aqua Security,推荐) # 安装: # Linux: curl -sfL https://raw.githubusercontent.com/... | sh # Mac: brew install trivy # 扫描镜像: trivy image nginx:latest trivy image --severity HIGH,CRITICAL myapp:latest # 输出:CVE 编号、严重程度、影响组件、修复版本 # 集成到 CI/CD: # GitHub Actions 示例: - name: Scan image uses: aquasecurity/trivy-action@master with: image-ref: myapp:${{ github.sha }} format: table exit-code: 1 # 有高危漏洞则失败 severity: CRITICAL,HIGH # Docker Scout(Docker 官方): docker scout quickview myapp:latest docker scout recommendations myapp:latest

私有仓库 Harbor

# Harbor 功能: # 1. 镜像存储与管理 # 2. 漏洞扫描(集成 Trivy/Clair) # 3. 镜像签名(Notary) # 4. 访问控制(项目/角色/用户) # 5. 镜像复制(跨数据中心同步) # 6. 镜像清理策略(保留最近 N 个版本) # Harbor 部署(docker-compose): wget https://github.com/goharbor/harbor/releases/... tar xzf harbor-offline-installer-*.tgz cd harbor cp harbor.yml.tmpl harbor.yml # 编辑 harbor.yml(配置域名、密码等) ./install.sh # 使用: docker login harbor.example.com docker tag myapp:latest harbor.example.com/project/myapp:v1 docker push harbor.example.com/project/myapp:v1

高级进阶

容器运行时安全

# 1. 非 root 用户运行 docker run --user 1000:1000 myapp # 或在 Dockerfile 中: USER 1000 # 2. 只读文件系统 docker run --read-only myapp # 需要写入的目录用 tmpfs 或 volume docker run --read-only \ -v /tmp \ -v /var/run \ myapp # 3. 限制容器能力(Capabilities) # 默认容器有部分 root 能力 # 去掉不必要的能力: docker run --cap-drop=ALL \ --cap-add=NET_BIND_SERVICE \ myapp # 4. 禁止特权模式 # 不推荐(危险): docker run --privileged myapp # 推荐:只添加必要的能力 # 5. 资源限制(防资源耗尽) docker run \ --cpus=2 \ --memory=512m \ --memory-swap=1g \ --pids-limit=100 \ myapp # 6. 安全选项 docker run \ --security-opt=no-new-privileges \ --security-opt=seccomp=/path/to/profile.json \ myapp

镜像签名(Docker Content Trust)

# Docker Content Trust(DCT): # 对镜像进行数字签名,确保镜像未被篡改 # 启用 DCT: export DOCKER_CONTENT_TRUST=1 # 签名并推送: docker trust signer add --key signer.pem alice registry.example.com docker trust sign registry.example.com/myapp:latest # 拉取时自动验证签名: docker pull registry.example.com/myapp:latest # 如果签名无效或不存在,拒绝拉取 # Notary 架构: # 1. 开发者签名镜像 # 2. 签名存储在 Notary 服务 # 3. 拉取时验证签名 # 4. 确保镜像来源可信、未被篡改

实战场景

# 场景1:CI/CD 集成安全扫描 # Jenkinsfile / GitHub Actions: stages: - build - scan # 安全扫描 - push - deploy # 扫描阶段: trivy image --severity HIGH,CRITICAL \ --exit-code 1 myapp:${BUILD_ID} # 有高危漏洞则构建失败 # 场景2:生产环境容器安全配置 docker run -d \ --name myapp \ --user 1000:1000 \ # 非 root --read-only \ # 只读文件系统 --cap-drop=ALL \ # 去掉所有能力 --cap-add=NET_BIND_SERVICE \ # 只加绑定端口 --cpus=2 \ # CPU 限制 --memory=512m \ # 内存限制 --pids-limit=100 \ # 进程数限制 --security-opt=no-new-privileges \ myapp:latest # 场景3:定期扫描运行中的容器 docker ps -q | xargs -I {} \ docker inspect {} --format='{{.Image}}' \ | sort -u | xargs -I {} trivy image {}

面试模拟

面试官:如何优化 Docker 镜像大小?

你:1)选最小基础镜像(alpine/slim);2)多阶段构建(分离构建和运行环境);3)合并 RUN 指令减少层数;4).dockerignore 排除无关文件;5)清理包管理器缓存(同一 RUN 中清理);6)使用 distroless 镜像(不含 shell 和包管理器)。

面试官:Docker 容器安全有哪些实践?

你:1)非 root 用户运行(USER 指令);2)镜像安全扫描(Trivy 扫描 CVE);3)镜像签名(DCT 防篡改);4)只读文件系统(--read-only);5)限制容器能力(--cap-drop);6)资源限制(--memory/--cpus);7)使用私有仓库(Harbor);8)定期更新基础镜像。