目录

前言:为什么需要容器镜像?

什么是容器镜像?

镜像的本质:应用的"完美快照"

镜像的分层结构:像洋葱一样层层叠加

镜像的不可变性:一次构建,到处运行

容器注册表:镜像的"应用商店"

注册表是什么?

注册表的核心功能

镜像地址的完整格式

镜像、容器、注册表的关系

完整的工作流程

生动的比喻

实际操作:从构建到部署

构建自定义镜像

使用注册表

镜像的最佳实践

1. 保持镜像小巧

2. 安全考虑

3. 标签管理

常见注册表服务

公共注册表

私有注册表

总结


前言:为什么需要容器镜像?

在传统软件开发中,部署应用就像搬家一样麻烦——你得确保新家里有所有必需的家具(依赖库)、合适的装修(配置文件)、甚至相似户型(操作系统)。而容器镜像的出现,就像把整个家打包成一个"标准化集装箱",无论搬到哪个小区(服务器),都能立即入住!


什么是容器镜像?

镜像的本质:应用的"完美快照"

想象一下,你要给朋友分享一个能100%正常运行的软件环境。容器镜像就是这个环境的完整快照,它包含:

  • 应用代码:你的程序文件

  • 运行时环境:Python、Node.js、Java等解释器或运行时

  • 系统工具:bash、curl等必要的命令行工具

  • 依赖库:所有需要的系统库和第三方库

  • 配置文件:应用所需的各种配置

  • 环境变量:预设的运行参数

镜像的分层结构:像洋葱一样层层叠加

容器镜像采用分层存储的设计,这是理解镜像的关键:

# 以简单的Dockerfile为例
FROM ubuntu:20.04          # 基础层:操作系统层
RUN apt-get update         # 工具层:安装系统工具
COPY . /app                # 代码层:复制应用代码
RUN pip install -r requirements.txt  # 依赖层:安装Python包
CMD ["python", "/app/main.py"]       # 启动层:设置启动命令

每一层都是只读的,当多个镜像共享相同的基础层时,它们可以复用这些层,大大节省存储空间和下载时间。

镜像的不可变性:一次构建,到处运行

一旦镜像构建完成,它就变成不可变的。这意味着:

  • 一致性保证:无论在哪里运行,镜像内容完全相同

  • 版本控制:可以通过标签管理不同版本(v1.0、v1.1、latest等)

  • 回滚安全:如果新版本有问题,可以立即回退到旧版本镜像


容器注册表:镜像的"应用商店"

注册表是什么?

如果容器镜像是打包好的软件,那么注册表就是存储和分发这些软件的中心仓库。它就像:

  • Docker Hub:类似手机的应用商店,拥有大量公共镜像

  • 私有注册表:类似企业内网的文件服务器,存储私有镜像

  • 云厂商注册表:AWS ECR、Google Container Registry等,提供托管服务

注册表的核心功能

镜像存储

  • 持久化保存镜像的所有版本

  • 管理镜像的元数据(作者、描述、标签等)

镜像分发

  • 支持镜像的上传(push)和下载(pull)

  • 提供版本管理和访问控制

安全扫描

  • 检查镜像中的安全漏洞

  • 签名验证确保镜像完整性

镜像地址的完整格式

理解镜像地址格式很重要:

registry-domain/username/image-name:tag

例子:

  • docker.io/library/nginx:latest - Docker Hub官方nginx镜像

  • mycompany.com/devteam/webapp:v1.2.3 - 私有注册表中的镜像

  • ghcr.io/myproject/api:stable - GitHub容器注册表


镜像、容器、注册表的关系

完整的工作流程

让我们通过一个实际例子理解三者关系:

# 1. 从注册表下载镜像
docker pull docker.io/nginx:latest

# 2. 基于镜像创建容器
docker run -d -p 80:80 nginx:latest

# 3. 修改容器后创建新镜像
docker commit container_id my-nginx:v2

# 4. 将新镜像推送到注册表
docker push mycompany.com/my-nginx:v2

生动的比喻

  • 镜像 = 菜谱 + 所有食材(应用代码+环境)

  • 容器 = 按照菜谱做出来的菜(运行中的实例)

  • 注册表 = 共享菜谱的烹饪网站(镜像仓库)


实际操作:从构建到部署

构建自定义镜像

创建Dockerfile

dockerfile

FROM python:3.9-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]

构建镜像:

docker build -t my-python-app:v1.0 .

使用注册表

推送到Docker Hub:

# 登录注册表
docker login

# 标记镜像(添加注册表地址)
docker tag my-python-app:v1.0 username/my-python-app:v1.0

# 推送镜像
docker push username/my-python-app:v1.0

从注册表拉取:

# 其他机器上拉取运行
docker pull username/my-python-app:v1.0
docker run -d username/my-python-app:v1.0

镜像的最佳实践

1. 保持镜像小巧

  • 使用Alpine Linux等轻量基础镜像

  • 多阶段构建,只保留运行时必要的文件

  • 清理缓存和临时文件

2. 安全考虑

  • 定期更新基础镜像,修复安全漏洞

  • 使用非root用户运行应用

  • 扫描镜像中的安全漏洞

3. 标签管理

  • 为每个版本使用明确的标签(v1.2.3)

  • 避免过度依赖latest标签

  • 使用语义化版本控制


常见注册表服务

公共注册表

  • Docker Hub:最流行的公共注册表

  • GitHub Container Registry:与GitHub深度集成

  • Quay.io:Red Hat提供的注册表服务

私有注册表

  • Harbor:企业级私有注册表,功能丰富

  • Nexus Repository:支持多种包格式

  • 云服务:AWS ECR、Azure Container Registry等


总结

容器镜像和注册表是现代应用部署的基石:

  • 容器镜像是应用的标准化打包格式,确保环境一致性

  • 分层存储让镜像更高效,支持快速部署和更新

  • 注册表是镜像的集中管理和分发中心

  • 完整的镜像地址包含注册表域名、用户名、镜像名和标签

更多推荐