08 - AI 公司 ACR 镜像仓库规划
一、命名空间规划
ACR 的命名空间(Namespace)用于组织镜像,类似于 Docker Hub 的组织名。
ACR 实例
├── robotics-base # 基础镜像(公共依赖、运行环境)
├── robotics-training # 训练相关镜像
├── robotics-serving # 推理/API 服务镜像
├── robotics-data # 数据平台镜像
├── robotics-infra # 基础设施镜像(工具/中间件定制)
└── robotics-third-party # 第三方镜像转存(加速拉取)二、镜像分类
基础镜像层(robotics-base)
这些镜像是其他镜像的基础,变化频率最低:
robotics-base/
├── cuda-runtime:12.1-ubuntu22.04 # CUDA 运行时
├── cuda-devel:12.1-ubuntu22.04 # CUDA 开发环境
├── pytorch-base:2.2.0-cuda12.1 # PyTorch 基础
├── python-base:3.11-slim # Python 运行时
├── ros2-base:humble # ROS2 基础(机器人)
└── node-base:20-alpine # Node.js 基础dockerfile
# robotics-base/pytorch-base 示例
FROM nvidia/cuda:12.1.0-cudnn8-devel-ubuntu22.04
RUN apt-get update && apt-get install -y \
python3.11 python3-pip git wget \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir \
torch==2.2.0 \
torchvision==0.17.0 \
numpy pandas scipy
WORKDIR /workspace构建策略:手动构建,版本锁定,变更需审批。
训练镜像(robotics-training)
robotics-training/
├── vision-train:v1.2.0 # 视觉模型训练
├── llm-finetune:v2.0.1 # 大模型微调
├── rl-policy:v1.0.3 # 强化学习策略训练
├── data-preprocess:v1.1.0 # 数据预处理
├── sim-gazebo:v1.0.0 # Gazebo 仿真
└── sim-isaac:v1.0.0 # Isaac Sim 仿真dockerfile
# robotics-training/vision-train 示例
FROM registry-vpc.cn-hangzhou.aliyuncs.com/robotics-base/pytorch-base:2.2.0-cuda12.1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ /workspace/src/
COPY configs/ /workspace/configs/
CMD ["python", "src/train.py"]构建策略:CI 自动构建,每次代码合并到 main 自动触发。
推理/API 镜像(robotics-serving)
robotics-serving/
├── api-gateway:v3.1.2 # API 网关
├── llm-server:v2.0.0 # LLM 推理服务
├── vision-server:v1.5.0 # 视觉推理服务
├── ota-server:v1.2.0 # OTA 更新管理
├── device-manager:v1.1.0 # 设备管理服务
└── admin-web:v2.3.1 # 管理后台前端dockerfile
# robotics-serving/llm-server 多阶段构建
FROM registry-vpc.cn-hangzhou.aliyuncs.com/robotics-base/python-base:3.11-slim AS builder
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
FROM registry-vpc.cn-hangzhou.aliyuncs.com/robotics-base/python-base:3.11-slim
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH
RUN adduser --disabled-password --gecos '' appuser
USER appuser
COPY src/ /app/src/
WORKDIR /app
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=10s CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]构建策略:CI 自动构建 + 安全扫描,部署需审批。
数据平台镜像(robotics-data)
robotics-data/
├── data-collector:v1.0.0 # 数据采集服务
├── annotation-tool:v2.1.0 # 标注工具
├── data-pipeline:v1.3.0 # 数据处理管道
└── data-quality:v1.0.0 # 数据质量检查第三方镜像转存(robotics-third-party)
robotics-third-party/
├── nginx:1.25-alpine
├── redis:7-alpine
├── postgres:16-alpine
├── prometheus:v2.50.0
├── grafana:10.3.0
├── argocd:v2.10.0
└── ingress-nginx-controller:v1.10.0为什么要转存:
- 国内拉取 Docker Hub / registry.k8s.io 速度慢或失败
- 锁定版本,避免上游意外变更
- VPC 内网拉取更快
三、Tag 规范
<image>:<version>[-<variant>]
版本格式:
├── 语义化版本: v1.2.3
├── Git commit: abc1234
├── 日期+commit: 20260315-abc1234
├── 分支标记: main-abc1234 / feature-xxx-abc1234
└── 特殊: latest (仅限开发环境)推荐 CI 中的 Tag 策略
bash
# 开发分支: branch-commitsha
TAG="${BRANCH_NAME}-$(git rev-parse --short HEAD)"
# 例: feature-slam-abc1234
# main 分支: 日期-commitsha
TAG="$(date +%Y%m%d)-$(git rev-parse --short HEAD)"
# 例: 20260315-abc1234
# Release tag: 语义化版本
TAG="${GIT_TAG}"
# 例: v1.2.3
# 构建并推送
IMAGE="registry-vpc.cn-hangzhou.aliyuncs.com/robotics-serving/api-gateway"
docker build -t ${IMAGE}:${TAG} .
docker push ${IMAGE}:${TAG}K8s Deployment 中使用
yaml
# 生产环境:使用确切版本 tag
image: registry-vpc.cn-hangzhou.aliyuncs.com/robotics-serving/api-gateway:v3.1.2
# 开发环境:可以用 branch tag
image: registry-vpc.cn-hangzhou.aliyuncs.com/robotics-serving/api-gateway:main-abc1234铁律:生产环境永远不用 latest。
四、CI/CD 镜像构建流水线
┌──────────────────────────────────────────────────────────┐
│ GitHub / GitLab │
│ │
│ Push / PR Merge │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ CI Pipeline │ │
│ │ │ │
│ │ 1. Lint + Test │ │
│ │ 2. Docker Build │ │
│ │ 3. 安全扫描 │ ← Trivy 扫描镜像漏洞 │
│ │ 4. Push to ACR │ │
│ │ 5. 更新 manifests│ ← 修改 values.yaml 中的 image tag │
│ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ ArgoCD │ │
│ │ 检测 Git 变更 │ │
│ │ 自动同步到 K8s │ │
│ └──────────────────┘ │
└──────────────────────────────────────────────────────────┘GitHub Actions 示例
yaml
# .github/workflows/build-push.yml
name: Build and Push
on:
push:
branches: [main]
paths: ['src/**', 'Dockerfile', 'requirements.txt']
env:
REGISTRY: registry-vpc.cn-hangzhou.aliyuncs.com
NAMESPACE: robotics-serving
IMAGE: api-gateway
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set tag
run: echo "TAG=$(date +%Y%m%d)-${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Login to ACR
run: docker login -u ${{ secrets.ACR_USERNAME }} -p ${{ secrets.ACR_PASSWORD }} ${{ env.REGISTRY }}
- name: Build
run: docker build -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }} .
- name: Scan
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }}
exit-code: 1
severity: CRITICAL,HIGH
- name: Push
run: docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }}
- name: Update manifests
run: |
cd k8s-manifests
sed -i "s|image:.*${{ env.IMAGE }}:.*|image: ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }}|g" serving/deployment.yaml
git add . && git commit -m "deploy: ${{ env.IMAGE }}:${{ env.TAG }}" && git push五、镜像安全策略
扫描策略
| 阶段 | 工具 | 行为 |
|---|---|---|
| 构建时 | Trivy (CI) | CRITICAL/HIGH 阻断构建 |
| 推送后 | ACR 自动扫描 | 报告漏洞,标记风险镜像 |
| 运行时 | ACK 准入策略 | 禁止拉取有 CRITICAL 漏洞的镜像 |
镜像签名(可选进阶)
bash
# cosign 签名镜像(供应链安全)
cosign sign --key cosign.key \
registry-vpc.cn-hangzhou.aliyuncs.com/robotics-serving/api-gateway:v3.1.2ACK 准入策略
yaml
# 只允许从指定 ACR 拉取镜像
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
# 或使用 OPA/Gatekeeper
# 规则:image 必须以 registry-vpc.cn-hangzhou.aliyuncs.com/robotics- 开头六、镜像瘦身实践
| 方法 | 效果 | 适用场景 |
|---|---|---|
| 使用 slim/alpine 基础镜像 | 减少 70-80% | 所有 |
| 多阶段构建 | 减少 50-90% | Go/Rust/前端 |
| .dockerignore | 减少构建时间 | 所有 |
| 合并 RUN 指令 | 减少层数 | 所有 |
| 清理安装缓存 | 减少 10-30% | apt/pip/npm |
| distroless 镜像 | 最小化攻击面 | Go/Java 运行时 |
dockerfile
# 训练镜像优化示例
FROM nvidia/cuda:12.1.0-cudnn8-devel-ubuntu22.04 AS builder
RUN pip install --user --no-cache-dir \
torch==2.2.0 torchvision==0.17.0 \
&& find /root/.local -name "*.pyc" -delete \
&& find /root/.local -name "__pycache__" -type d -exec rm -rf {} + \
&& find /root/.local -name "tests" -type d -exec rm -rf {} +
FROM nvidia/cuda:12.1.0-cudnn8-runtime-ubuntu22.04
# runtime 镜像比 devel 小得多(没有编译工具链)
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH
COPY src/ /workspace/src/
WORKDIR /workspace
CMD ["python", "src/train.py"]七、个人版 vs 企业版选择
初创公司初期:个人版足够
| 指标 | 你的需求 | 个人版限制 |
|---|---|---|
| 命名空间 | 6 个 | 3 个 |
| 仓库数 | ~20 个 | 300 个 |
| 镜像扫描 | 需要 | 基础支持 |
| 多地域 | 暂不需要 | 不支持 |
问题:个人版只有 3 个命名空间,你需要 6 个。
解决方案:
- 合并为 3 个命名空间:
robotics-prod(serving + base)、robotics-dev(training + data)、robotics-ops(infra + third-party) - 或直接升级企业版基础版(每月几百元)
成长期:升级企业版
当需要以下功能时升级:
- 多地域镜像同步(跨区域部署)
- 高级安全扫描 + 镜像签名
- P2P 加速(大规模集群同时拉取)
- Helm Chart 托管
