深入理解Docker镜像仓库,掌握镜像分发、版本管理和安全最佳实践。
Docker 仓库 是用于存储和分发Docker镜像的服务。仓库可以分为公共仓库和私有仓库。
Docker仓库的主要功能:
最著名的公共仓库是 Docker Hub,此外还有各种云服务商提供的仓库服务。
注册表 (Registry) 是存储仓库的服务,仓库 (Repository) 是存储特定镜像集合的地方。一个注册表可以包含多个仓库。
Docker官方提供的公共仓库,包含大量官方和社区镜像。
AWS ECR、Google Container Registry、Azure Container Registry等。
使用Docker Registry或Harbor等工具搭建私有仓库。
Docker Hub是Docker官方提供的镜像仓库服务,包含官方镜像、验证发布者镜像和社区镜像。
# 登录Docker Hub
docker login
# 使用指定用户名登录
docker login -u username
# 从文件读取密码(用于CI/CD环境)
cat /path/to/password.txt | docker login -u username --password-stdin
# 登出Docker Hub
docker logout
# 查看当前登录信息
docker info | grep Username
# 官方镜像(无用户名前缀)
docker pull nginx
docker pull ubuntu:20.04
# 用户镜像(用户名/镜像名格式)
docker pull username/my-app
# 指定标签
docker pull username/my-app:1.0.0
docker pull username/my-app:latest
# 指定架构
docker pull username/my-app:1.0.0-amd64
私有仓库用于存储企业内部镜像,提供更好的安全性和控制能力。
# 使用Docker运行私有Registry
docker run -d \
-p 5000:5000 \
--name registry \
-v /data/registry:/var/lib/registry \
registry:2
# 使用TLS证书运行安全Registry
docker run -d \
-p 5000:5000 \
--name registry \
-v /path/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
# 标记镜像指向私有仓库
docker tag my-app:latest localhost:5000/my-app:latest
# 推送镜像到私有仓库
docker push localhost:5000/my-app:latest
# 从私有仓库拉取镜像
docker pull localhost:5000/my-app:latest
# 使用域名访问私有仓库
docker tag my-app:latest registry.example.com:5000/my-app:latest
docker push registry.example.com:5000/my-app:latest
Harbor是VMware开源的企业级Registry,提供更多企业级功能:
# 使用Docker Compose安装Harbor
wget https://github.com/goharbor/harbor/releases/download/v2.5.0/harbor-offline-installer-v2.5.0.tgz
tar xzf harbor-offline-installer-v2.5.0.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml
# 编辑harbor.yml配置
./install.sh
使用Dockerfile构建应用镜像
为镜像添加合适的标签,包含仓库地址和版本信息
将镜像推送到目标仓库
在目标环境拉取镜像并部署
# 语义化版本标签
my-app:1.0.0 # 主版本.次版本.修订版本
my-app:1.0 # 主要版本
my-app:1 # 主要版本系列
# 预发布版本
my-app:1.0.0-rc.1 # 发布候选版本
my-app:1.0.0-beta.1 # 测试版本
my-app:1.0.0-alpha.1 # 开发版本
# 环境特定标签
my-app:latest # 最新稳定版本(生产慎用)
my-app:stable # 稳定版本
my-app:dev # 开发版本
my-app:test # 测试版本
my-app:staging # 预生产版本
# 基于Git提交的标签
my-app:git-${COMMIT_SHA:0:8} # 提交哈希前8位
my-app:branch-${BRANCH_NAME} # 分支名称
my-app:${BUILD_NUMBER} # 构建编号
# 实际示例
my-app:git-a1b2c3d4
my-app:branch-feature-login
my-app:build-123
# 多架构镜像标签
my-app:1.0.0-amd64 # AMD64架构
my-app:1.0.0-arm64 # ARM64架构
my-app:1.0.0-armv7 # ARMv7架构
# 使用manifest列表(推荐)
my-app:1.0.0 # 自动选择合适架构
| 命令 | 描述 | 示例 |
|---|---|---|
docker pull |
从仓库拉取镜像 | docker pull nginx:latest |
docker push |
推送镜像到仓库 | docker push myrepo/my-app:1.0 |
docker tag |
为镜像创建标签 | docker tag my-app:1.0 myrepo/my-app:1.0 |
docker search |
搜索Docker Hub上的镜像 | docker search nginx |
docker images |
列出本地镜像 | docker images |
docker rmi |
删除本地镜像 | docker rmi my-app:1.0 |
docker save |
将镜像保存为tar文件 | docker save -o my-app.tar my-app:1.0 |
docker load |
从tar文件加载镜像 | docker load -i my-app.tar |
docker export |
将容器导出为tar文件 | docker export container > app.tar |
docker import |
从tar文件导入镜像 | docker import app.tar my-app:1.0 |
# 启用Docker内容信任
export DOCKER_CONTENT_TRUST=1
# 推送签名镜像
docker push myrepo/my-app:1.0
# 拉取并验证签名镜像
docker pull myrepo/my-app:1.0
# 禁用内容信任
export DOCKER_CONTENT_TRUST=0
# 使用Docker Scout扫描镜像(Docker Desktop)
docker scout quickview my-app:latest
# 使用Trivy扫描镜像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image my-app:latest
# 使用Grype扫描镜像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock anchore/grype my-app:latest
# 使用Alpine Linux基础镜像
FROM alpine:3.18
# 使用Distroless基础镜像(Google)
FROM gcr.io/distroless/base-debian11
# 使用Scratch空镜像
FROM scratch
在国内访问Docker Hub可能较慢,可以配置镜像加速器提高拉取速度。
在Docker Desktop设置中配置镜像加速器:
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
]
}
# 创建或编辑Docker配置文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
]
}
EOF
# 重启Docker服务
sudo systemctl daemon-reload
sudo systemctl restart docker
name: Build and Push Docker Image
on:
push:
branches: [ main ]
tags: [ 'v*' ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t my-app:${{ github.sha }} .
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push Docker image
run: |
docker tag my-app:${{ github.sha }} ${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.sha }}
docker tag my-app:${{ github.sha }} ${{ secrets.DOCKER_USERNAME }}/my-app:latest
docker push ${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.sha }}
docker push ${{ secrets.DOCKER_USERNAME }}/my-app:latest
image: docker:latest
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
stages:
- build
- push
build:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
push:
stage: push
script:
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
only:
- main
| 特性 | Docker Hub | AWS ECR | Google GCR | 自建Registry |
|---|---|---|---|---|
| 成本 | 免费+付费 | 按使用量付费 | 按使用量付费 | 基础设施成本 |
| 私有仓库 | 有限免费 | 支持 | 支持 | 完全支持 |
| 安全性 | 基础 | IAM集成 | IAM集成 | 完全可控 |
| 漏洞扫描 | 付费功能 | 基础扫描 | 基础扫描 | 依赖工具 |
| 与云服务集成 | 有限 | 深度集成 | 深度集成 | 自定义 |
| 适用场景 | 个人/小团队 | AWS用户 | GCP用户 | 企业/合规需求 |
使用多阶段构建减小镜像大小,只包含运行应用所需的文件。
FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]
创建.dockerignore文件排除不必要的文件,减小构建上下文和镜像大小。
# .dockerignore 文件示例
.git
node_modules
npm-debug.log
Dockerfile
.dockerignore
README.md
在生产环境中避免使用latest标签,使用明确的版本标签确保部署一致性。
# 不推荐
docker run my-app:latest
# 推荐
docker run my-app:1.2.3
docker run my-app:1.2.3-git-a1b2c3d4
定期更新基础镜像以获取安全补丁和性能改进。
# 使用特定版本的基础镜像
FROM node:18.16.0-alpine
# 定期检查并更新到新版本
FROM node:18.17.0-alpine
在CI/CD流水线中集成镜像漏洞扫描,确保部署的镜像没有已知安全漏洞。
# GitHub Actions 扫描步骤
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: 'my-app:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
问题描述: 推送镜像到仓库时出现认证错误。
解决方案:
docker login
# 重新登录Docker Hub
docker logout
docker login
# 检查当前登录信息
cat ~/.docker/config.json
# 使用访问令牌而不是密码(GitHub Packages等)
echo $TOKEN | docker login docker.pkg.github.com -u USERNAME --password-stdin
问题描述: 从Docker Hub拉取镜像速度很慢。
解决方案:
# 配置镜像加速器(Linux)
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
# 使用代理
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
问题描述: 镜像标签过多,难以管理和追踪。
解决方案:
# 清理旧的镜像标签
docker images --filter "dangling=true" -q | xargs docker rmi
# 按时间过滤并删除旧镜像
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.CreatedSince}}" | grep "months ago"
# 使用第三方工具清理
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock spotify/docker-gc
恭喜!您已经掌握了Docker仓库与镜像分发的核心知识。现在可以高效管理镜像生命周期,确保应用的安全分发和部署。