15.7.6 构建与发布最佳实践与安全加固
构建与发布应围绕“可重复、可追溯、可审计、可回滚、安全可信”。本节给出可落地的流程、命令与排错示例,确保在CI/CD中可直接复用。
原理草图:构建与发布安全链路#
构建与发布最佳实践(含示例)#
1) 固定基础镜像与摘要(digest)#
目标:避免latest漂移,保证可追溯。
# 文件: Dockerfile
# 固定版本 + digest(示例digest需从仓库获取)
FROM ubuntu:22.04@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef AS base
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
命令解释:
- @sha256: 固定镜像摘要,避免同标签被覆盖。
- rm -rf /var/lib/apt/lists/* 清理缓存,缩小镜像体积。
2) 多阶段构建与瘦身#
# 文件: Dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /src
COPY . .
RUN go build -o /out/app
FROM alpine:3.19
RUN adduser -D -H -s /sbin/nologin appuser
USER appuser
WORKDIR /app
COPY --from=builder /out/app /app/app
EXPOSE 8080
ENTRYPOINT ["/app/app"]
预期效果:最终镜像仅含二进制与运行库,显著减少体积与漏洞面。
3) 构建上下文控制(.dockerignore)#
# 文件: .dockerignore
.git
*.log
tmp/
node_modules/
说明:减少构建上下文体积,避免机密泄露。
4) 统一标签规范与可回滚#
# 示例变量
APP=myapp
VERSION=1.3.2
BUILD=20240120.1
GIT_SHA=1a2b3c4
# 构建镜像
docker build -t registry.example.com/$APP:$VERSION -t registry.example.com/$APP:$VERSION-$BUILD-$GIT_SHA .
# 推送
docker push registry.example.com/$APP:$VERSION
docker push registry.example.com/$APP:$VERSION-$BUILD-$GIT_SHA
解释:语义化版本 + 构建号 + 提交哈希,支持精确回滚。
安全加固实践(含命令)#
1) 镜像安全扫描#
以 Trivy 为例(安装与扫描):
# 安装(Ubuntu示例)
sudo apt-get update
sudo apt-get install -y wget
wget https://github.com/aquasecurity/trivy/releases/latest/download/trivy_0.49.1_Linux-64bit.deb
sudo dpkg -i trivy_0.49.1_Linux-64bit.deb
# 扫描镜像
trivy image registry.example.com/myapp:1.3.2
预期效果:列出高危漏洞与受影响包。
2) 镜像签名与验证(cosign)#
# 安装(示例)
curl -L https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o cosign
chmod +x cosign && sudo mv cosign /usr/local/bin/
# 生成密钥
cosign generate-key-pair
# 签名镜像
cosign sign --key cosign.key registry.example.com/myapp:1.3.2
# 验证签名
cosign verify --key cosign.pub registry.example.com/myapp:1.3.2
3) 运行时最小权限#
# 运行时只读文件系统 + 去root用户
docker run -d --name myapp \
--read-only \
--user 10001:10001 \
--cap-drop ALL \
-p 8080:8080 \
registry.example.com/myapp:1.3.2
解释:
- --read-only:防止容器内写入。
- --cap-drop ALL:降低系统权限面。
CI/CD最小可行流水线(示例)#
# 文件: .gitlab-ci.yml
stages: [build, scan, sign, push]
variables:
IMAGE: registry.example.com/myapp
VERSION: "1.3.2"
build:
stage: build
script:
- docker build -t $IMAGE:$VERSION .
scan:
stage: scan
script:
- trivy image $IMAGE:$VERSION
sign:
stage: sign
script:
- cosign sign --key $COSIGN_KEY $IMAGE:$VERSION
push:
stage: push
script:
- docker push $IMAGE:$VERSION
常见问题与排错#
1) 构建失败:无法拉取基础镜像
# 检查网络与镜像仓库
docker pull ubuntu:22.04
# 若公司内网,确认镜像加速器配置
cat /etc/docker/daemon.json
systemctl restart docker
2) 扫描失败:数据库下载超时
# 手动更新漏洞库
trivy image --download-db-only
3) 运行时报错:权限不足
# 排查容器用户与文件权限
docker exec -it myapp id
docker exec -it myapp ls -l /app
练习#
1) 基于 alpine:3.19 编写多阶段构建Dockerfile,将Go程序构建后运行,要求镜像体积 < 20MB。
2) 为镜像 myapp:1.0.0 添加语义化标签与提交哈希标签,并验证可回滚性。
3) 使用 Trivy 扫描镜像并修复一个高危漏洞(更新基础镜像或移除依赖)。
4) 使用 cosign 对镜像签名并在部署时校验签名有效性。