--- tags: [microservice, docker, container, image-optimization] create time: 2026-05-05 15:30 --- # 容器化 — 参考手册 ## 概述 Docker 容器是微服务交付的标准单元。它解决了"在我机器上是好的"这个经典问题——**开发、测试、生产使用完全一致的运行时环境**。 本文档是总入口:核心概念、决策矩阵、速查表见本页;详细教程和实操指南在子文档中。 ```mermaid graph TB CODE["源代码"] --> BUILD["CI 构建镜像"] BUILD --> SCAN["安全扫描
Trivy / Snyk"] SCAN --> REGISTRY["镜像仓库
Harbor / ECR / ACR"] REGISTRY --> K8s["Kubernetes 部署"] style BUILD fill:#e3f2fd style REGISTRY fill:#fff3e0 style K8s fill:#e8f5e9 ``` ## 快速导航 | 主题 | 定位 | 文档 | |------|------|------| | Dockerfile 最佳实践 | **教程**:多阶段构建、BuildKit、缓存技巧 | [[01-容器化/01-Dockerfile最佳实践]] | | 多架构构建 | **进阶**:Buildx、跨平台编译 | [[01-容器化/02-多架构构建]] | | 镜像安全 | **安全**:漏洞扫描、distroless、签名 | [[01-容器化/03-镜像安全]] | ## .dockerignore 模板 ``` .git .gitignore *.md vendor/ tests/ *.log .DS_Store .idea/ .vscode/ ``` > [!tip] 为什么 .dockerignore 很重要? > > 如果不排除 `.git` 目录,整个版本历史都会被打包进镜像(增加数百 MB)。如果排除不当,可能遗漏必要的配置文件。建议每个项目根目录都包含此文件。 ## 层缓存核心原则 > **经常变动的内容靠近 COPY,少变的放前面**。 > > ```dockerfile > # ✅ 好:只有 go.mod/go.sum 变化时才重新下载依赖 > COPY go.mod go.sum ./ > RUN go mod download > COPY . . > RUN go build > ``` ## 基础镜像选型 | 基础镜像 | 典型 Go 服务大小 | 适用场景 | |---------|-----------------|---------| | `ubuntu:22.04` | ~35 MB | 兼容性要求高 | | `debian:bookworm-slim` | ~20 MB | 需要 glibc 的动态链接程序 | | `alpine:3.19` | ~7 MB | 小体积优先,注意 musl libc 兼容 | | `distroless/static` | ~5 MB | 生产推荐,无 shell | | `scratch` | <取决于二进制 | 仅静态链接二进制可运行 | > [!warning] Alpine 与 musl libc > > Alpine 使用 musl libc 而非 glibc。某些 C 扩展(如 `node-gyp`、部分 Python wheel)可能无法编译或运行时行为不一致。Go 服务通过 `CGO_ENABLED=0` 规避了此问题,但 Node.js/Python 应用需谨慎评估。 ## 镜像仓库方案对比 | 仓库方案 | 特点 | 适用场景 | |---------|------|---------| | **Harbor** | 自托管,RBAC + 扫描 | 国内企业首选 | | **ECR / ACR / GCR** | 云厂商托管 | 全云环境 | | **Docker Hub** | 公共免费 | 开源项目 | ## BuildKit 特性速查 ```bash export DOCKER_BUILDKIT=1 docker build --cache-from=harbor.example.com/app/cache:latest . docker build --ssh default . docker build --secret id=token,env=GITHUB_TOKEN . ``` ## 常见问题排查 | 症状 | 原因 | 解决 | |------|------|------| | `exec: "app": not found` | 多阶段 COPY 路径错误 | 检查绝对路径和文件名拼写 | | `standard_init_linux.go: exec user process caused: permission denied` | 没有执行权限或缺少换行符 | `chmod +x`, 确保 Linux 换行 | | `service unavailable` (K8s) | HEALTHCHECK 未就绪 | 增大 `--start-period` | | 镜像体积异常大 | `.git` 未排除或多层 RUN 未清理 | 检查 `.dockerignore`,合并 RUN 并 `rm -rf` | | `cannot execute: executable file not found` | 架构不匹配(arm64 → amd64) | 确认 `TARGETARCH` 或手动指定 `--platform` | ## 关联笔记 - [[hhs/MS/05-部署运维/02-Kubernetes]] — K8s 以 Pod 为部署单元,镜像来自 Docker - [[hhs/MS/05-部署运维/03-CICD与GitOps]] — CI/CD 流水线中的镜像构建环节