镜像定义:一个只读的模板,包含创建Docker容器的指令。
东巴文理解:
镜像 = 蛋糕配方 + 模具
就像:做蛋糕的配方和模具
配方记录了:
├─ 需要什么材料(基础镜像)
├─ 怎么加工(RUN命令)
├─ 暴露什么(EXPOSE端口)
└─ 怎么食用(CMD命令)
用配方和模具可以做出无数个相同的蛋糕(容器)
镜像组成:
┌─────────────────────────────┐
│ 应用层(Application) │ ← 应用代码
├─────────────────────────────┤
│ 依赖层(Dependencies) │ ← 依赖库
├─────────────────────────────┤
│ 运行时层(Runtime) │ ← Python/Java/Node.js
├─────────────────────────────┤
│ 基础系统层(Base OS) │ ← Ubuntu/Alpine/Debian
└─────────────────────────────┘
每一层都是只读的,层层叠加
只读性:
镜像 = 只读模板
├─ 创建后不可修改
├─ 只能通过构建新镜像来"修改"
└─ 多个容器可以共享同一个镜像
分层存储:
镜像分层示例:
镜像A:
├─ Ubuntu基础层(100MB)
├─ Python运行时层(50MB)
└─ 应用代码层(10MB)
总大小:160MB
镜像B:
├─ Ubuntu基础层(100MB)← 与镜像A共享
├─ Node.js运行时层(40MB)
└─ 应用代码层(15MB)
总大小:155MB
实际占用:100MB + 50MB + 10MB + 40MB + 15MB = 215MB
节省:160MB + 155MB - 215MB = 100MB
唯一标识:
镜像ID:64位十六进制字符串
├─ 完整ID:sha256:7a86f8a2e...
├─ 短ID:7a86f8a2e(前12位)
└─ 用于唯一标识镜像
镜像标签:
├─ 格式:仓库名:标签
├─ 示例:nginx:latest、nginx:1.21
└─ 标签默认为latest
完整格式:
[仓库地址/]镜像名[:标签]
示例:
nginx:latest # 官方镜像,默认latest
nginx:1.21 # 官方镜像,指定版本
library/nginx:latest # 完整写法
docker.io/library/nginx:latest # 最完整写法
私有仓库:
registry.example.com/myapp:v1.0
├─ registry.example.com:仓库地址
├─ myapp:镜像名
└─ v1.0:标签
用户镜像:
username/myapp:latest
├─ username:用户名
├─ myapp:镜像名
└─ latest:标签
版本标签:
推荐格式:
├─ v1.0.0:语义化版本
├─ 1.21.0:纯数字版本
├─ 20240115:日期版本
└─ dev/test/prod:环境标签
示例:
myapp:v1.0.0
myapp:1.21.0
myapp:20240115
myapp:dev
myapp:prod
官方镜像:
特点:
├─ Docker官方维护
├─ 质量有保证
├─ 安全性高
├─ 更新及时
└─ 无前缀
示例:
├─ nginx
├─ mysql
├─ redis
├─ python
├─ node
└─ ubuntu
认证镜像:
特点:
├─ 第三方公司认证
├─ 质量较高
├─ 有官方前缀
└─ Docker Hub认证
示例:
├─ bitnami/nginx
├─ percona/mysql
└─ circleci/python
用户镜像:
特点:
├─ 个人用户上传
├─ 质量参差不齐
├─ 有用户名前缀
└─ 需谨慎使用
示例:
├─ username/myapp
└─ company/project
基础镜像:
操作系统镜像:
├─ ubuntu:22.04
├─ debian:bullseye
├─ alpine:3.18
├─ centos:7
└─ busybox:latest
特点:
├─ 体积小
├─ 提供基础环境
└─ 用于构建其他镜像
运行时镜像:
语言运行时:
├─ python:3.11
├─ node:18
├─ java:17
├─ golang:1.21
└─ ruby:3.2
特点:
├─ 包含语言环境
├─ 预装常用工具
└─ 用于运行应用
应用镜像:
应用服务:
├─ nginx:latest
├─ mysql:8.0
├─ redis:7
├─ postgresql:15
└─ mongodb:7
特点:
├─ 开箱即用
├─ 预配置环境
└─ 直接部署运行
容器定义:镜像的运行实例,一个轻量级的独立可执行软件包。
东巴文理解:
容器 = 正在运行的程序
就像:用配方做出的蛋糕
镜像(配方):
├─ 静态的
├─ 只读的
└─ 可以创建多个容器
容器(蛋糕):
├─ 动态的
├─ 可读写的
├─ 有生命周期
└─ 相互隔离
容器特点:
隔离性:
├─ 进程隔离
├─ 网络隔离
├─ 文件系统隔离
└─ 资源隔离
轻量级:
├─ 共享主机内核
├─ 秒级启动
├─ MB级内存占用
└─ 高密度部署
可移植:
├─ 环境一致
├─ 跨平台运行
└─ 一次构建到处运行
关系图:
┌─────────────────────────────┐
│ 镜像(Image) │
│ (只读模板) │
└──────────┬──────────────────┘
│ docker run
↓
┌─────────────────────────────┐
│ 容器(Container) │
│ (镜像 + 可写层) │
├─────────────────────────────┤
│ ┌───────────────────────┐ │
│ │ 可写容器层 │ │ ← 容器独有
│ ├───────────────────────┤ │
│ │ 镜像层(只读) │ │ ← 共享镜像
│ └───────────────────────┘ │
└─────────────────────────────┘
对比:
镜像:
├─ 静态概念
├─ 只读
├─ 存储在磁盘
├─ 不可变
└─ 类比:类(Class)
容器:
├─ 动态概念
├─ 可读写
├─ 运行在内存
├─ 有生命周期
└─ 类比:实例(Instance)
状态转换图:
docker create
↓
┌──────────┐
│ Created │ 创建状态
└────┬─────┘
│ docker start
↓
┌──────────┐
┌───→│ Running │←───┐ 运行状态
│ └────┬─────┘ │
│ │ │
│ docker │ docker │ docker
│ pause │ unpause │ restart
│ ↓ │
│ ┌──────────┐ │
│ │ Paused │────┘ 暂停状态
│ └──────────┘
│ │ docker stop/kill
│ ↓
│ ┌──────────┐
│ │ Stopped │ 停止状态
│ └────┬─────┘
│ │ docker rm
│ ↓
│ ┌──────────┐
└────│ Deleted │ 删除状态
└──────────┘
状态说明:
Created(已创建):
├─ 容器已创建但未启动
├─ 文件系统已准备
└─ 资源已分配
Running(运行中):
├─ 容器正在运行
├─ 进程活跃
└─ 资源正在使用
Paused(已暂停):
├─ 容器进程被挂起
├─ 内存状态保留
└─ 可恢复运行
Stopped(已停止):
├─ 容器进程已终止
├─ 资源已释放
└─ 可重新启动
Deleted(已删除):
├─ 容器已删除
├─ 文件系统已清理
└─ 不可恢复
创建和启动:
# 创建容器(不启动)
docker create --name mynginx nginx:latest
# 启动已创建的容器
docker start mynginx
# 创建并启动容器(常用)
docker run --name mynginx -d nginx:latest
# 交互式运行
docker run -it ubuntu bash
# 前台运行
docker run nginx:latest
暂停和恢复:
# 暂停容器
docker pause mynginx
# 查看状态
docker ps -a | grep mynginx
# STATUS: Up 5 minutes (Paused)
# 恢复容器
docker unpause mynginx
停止和重启:
# 优雅停止(发送SIGTERM)
docker stop mynginx
# 强制停止(发送SIGKILL)
docker kill mynginx
# 重启容器
docker restart mynginx
# 查看停止的容器
docker ps -a --filter "status=exited"
删除容器:
# 删除已停止的容器
docker rm mynginx
# 强制删除运行中的容器
docker rm -f mynginx
# 删除所有停止的容器
docker container prune
# 删除所有容器
docker rm -f $(docker ps -aq)
ID生成:
容器ID:64位十六进制字符串
├─ 完整ID:a1b2c3d4e5f6...
├─ 短ID:a1b2c3d4e5f6(前12位)
└─ 系统自动生成
示例:
CONTAINER ID IMAGE COMMAND
a1b2c3d4e5f6 nginx:latest "/docker-entrypoint.…"
使用短ID操作:
docker stop a1b2c3d4e5f6
docker logs a1b2c3d4
docker exec -it a1b2c3 bash
命名规则:
# 自动命名(随机生成)
docker run -d nginx
# NAME: mystifying_hoover
# 手动命名(推荐)
docker run -d --name mynginx nginx
# NAME: mynginx
# 命名规则
├─ 字母、数字、下划线、点、连字符
├─ 必须以字母或数字开头
├─ 最长64个字符
└─ 全局唯一
使用名称操作:
# 使用名称更直观
docker start mynginx
docker stop mynginx
docker logs mynginx
docker exec -it mynginx bash
# 重命名容器
docker rename mynginx nginx-prod
仓库定义:集中存储和分发镜像的地方。
东巴文理解:
仓库 = 镜像超市
就像:存放商品的仓库或超市
Docker Hub = 大型超市
├─ 商品丰富(镜像多)
├─ 免费开放(公开镜像)
├─ 会员服务(私有镜像)
└─ 品牌专柜(官方镜像)
私有仓库 = 私人仓库
├─ 企业内部使用
├─ 安全可控
└─ 访问速度快
仓库组成:
Registry(注册服务器)
├─ Repository(仓库)
│ ├─ Image(镜像)
│ │ ├─ Tag: latest
│ │ ├─ Tag: 1.21
│ │ └─ Tag: 1.20
│ └─ Manifest(清单)
└─ Index(索引)
示例:
Registry: docker.io
Repository: library/nginx
Images: nginx:latest, nginx:1.21, nginx:1.20
公有仓库:
Docker Hub:
├─ 官方仓库
├─ 地址:https://hub.docker.com
├─ 免费公开镜像
├─ 付费私有镜像
└─ 自动构建功能
其他公有仓库:
├─ GitHub Container Registry
├─ Google Container Registry
├─ Amazon ECR Public
└─ 阿里云容器镜像服务
私有仓库:
Docker Registry:
├─ 官方开源
├─ 轻量级
├─ 基础功能
└─ 适合小团队
Harbor:
├─ 企业级
├─ 功能丰富
├─ 权限管理
├─ 镜像扫描
└─ 适合企业
Nexus:
├─ 多种制品管理
├─ Maven、Docker等
└─ 统一管理
注册账号:
1. 访问 https://hub.docker.com
2. 点击 Sign Up
3. 填写用户名、邮箱、密码
4. 验证邮箱
5. 登录账号
命令行登录:
# 登录Docker Hub
docker login
# 输入用户名和密码
Username: yourusername
Password: ********
Login Succeeded
# 登录私有仓库
docker login registry.example.com
# 退出登录
docker logout
网页搜索:
1. 登录Docker Hub
2. 在搜索框输入镜像名
3. 筛选条件:
├─ 官方镜像(Official Images)
├─ 认证发布者(Verified Publisher)
└─ 开源项目(Open Source)
命令行搜索:
# 搜索镜像
docker search nginx
# 输出示例
NAME DESCRIPTION STARS OFFICIAL
nginx Official build of Nginx. 18000 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy... 2100
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM... 800
# 过滤官方镜像
docker search --filter is-official=true nginx
# 限制结果数量
docker search --limit 5 nginx
# 过滤星数
docker search --filter stars=1000 nginx
基本拉取:
# 拉取最新版本
docker pull nginx
# 拉取指定版本
docker pull nginx:1.21
# 拉取指定平台
docker pull --platform linux/arm64 nginx
# 拉取所有标签
docker pull -a nginx
拉取过程:
docker pull nginx:latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete # 分层下载
aeb1c7d5e8d2: Pull complete
ad7f5c8ed6b1: Pull complete
4d67e1fc5d6a: Pull complete
8e4d8e5c4b8a: Pull complete
Digest: sha256:7a86f8a2e... # 镜像摘要
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
推送步骤:
# 1. 登录Docker Hub
docker login
# 2. 给镜像打标签
docker tag myapp:latest username/myapp:latest
docker tag myapp:latest username/myapp:v1.0
# 3. 推送镜像
docker push username/myapp:latest
docker push username/myapp:v1.0
# 推送所有标签
docker push -a username/myapp
快速搭建:
# 拉取Registry镜像
docker pull registry:2
# 运行Registry容器
docker run -d \
--name registry \
-p 5000:5000 \
-v /data/registry:/var/lib/registry \
--restart=always \
registry:2
# 查看运行状态
docker ps | grep registry
使用私有仓库:
# 标记镜像
docker tag myapp:latest localhost:5000/myapp:latest
# 推送镜像
docker push localhost:5000/myapp:latest
# 拉取镜像
docker pull localhost:5000/myapp:latest
# 查看仓库中的镜像
curl http://localhost:5000/v2/_catalog
# 查看镜像标签
curl http://localhost:5000/v2/myapp/tags/list
配置HTTPS:
# 生成自签名证书
mkdir -p /data/registry/certs
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout /data/registry/certs/domain.key \
-x509 -days 365 \
-out /data/registry/certs/domain.crt
# 运行带HTTPS的Registry
docker run -d \
--name registry \
-p 5000:5000 \
-v /data/registry:/var/lib/registry \
-v /data/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
Harbor特点:
功能:
├─ 基于角色的访问控制
├─ 镜像漏洞扫描
├─ 镜像签名
├─ 垃圾回收
├─ 图形化管理界面
└─ 审计日志
适用场景:
├─ 企业级部署
├─ 多团队协作
├─ 安全合规要求
└─ 大规模镜像管理
安装Harbor:
# 下载Harbor
wget https://github.com/goharbor/harbor/releases/download/v2.8.0/harbor-offline-installer-v2.8.0.tgz
# 解压
tar xvf harbor-offline-installer-v2.8.0.tgz
# 修改配置
cd harbor
vim harbor.yml
# 安装
./install.sh
# 访问Web界面
http://your-server-ip
默认账号:admin / Harbor12345
完整工作流程:
┌─────────────────────────────────────────────┐
│ 开发者工作站 │
├─────────────────────────────────────────────┤
│ 1. 编写Dockerfile │
│ 2. 构建镜像:docker build -t myapp . │
│ 3. 测试容器:docker run myapp │
└──────────────┬──────────────────────────────┘
│ docker push
↓
┌─────────────────────────────────────────────┐
│ 镜像仓库(Registry) │
├─────────────────────────────────────────────┤
│ 存储镜像: │
│ ├─ myapp:latest │
│ ├─ myapp:v1.0 │
│ └─ myapp:v2.0 │
└──────────────┬──────────────────────────────┘
│ docker pull
↓
┌─────────────────────────────────────────────┐
│ 生产服务器 │
├─────────────────────────────────────────────┤
│ 1. 拉取镜像:docker pull myapp:latest │
│ 2. 运行容器:docker run -d myapp │
│ 3. 管理容器:docker ps, logs, exec │
└─────────────────────────────────────────────┘
场景:部署Web应用:
# === 开发环境 ===
# 1. 编写Dockerfile
cat > Dockerfile <<EOF
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
EOF
# 2. 构建镜像
docker build -t mywebapp:v1.0 .
# 3. 本地测试
docker run -d -p 3000:3000 --name myweb mywebapp:v1.0
# 4. 推送到仓库
docker tag mywebapp:v1.0 registry.company.com/mywebapp:v1.0
docker push registry.company.com/mywebapp:v1.0
# === 生产环境 ===
# 5. 拉取镜像
docker pull registry.company.com/mywebapp:v1.0
# 6. 运行容器
docker run -d \
--name webapp-prod \
-p 80:3000 \
--restart=always \
registry.company.com/mywebapp:v1.0
# 7. 监控容器
docker logs -f webapp-prod
docker stats webapp-prod
镜像构建:
✅ 使用明确的基础镜像版本
FROM node:18-alpine # 好
FROM node # 不好(latest不确定)
✅ 最小化镜像层数
RUN apt-get update && apt-get install -y package1 package2
✅ 使用多阶段构建
构建阶段 → 运行阶段,减小镜像体积
✅ 不存储敏感信息
使用环境变量或配置文件
✅ 添加元数据
LABEL maintainer="admin@example.com"
LABEL version="1.0"
镜像标签:
✅ 使用语义化版本
myapp:v1.0.0
myapp:v1.1.0
✅ 标记环境
myapp:dev
myapp:test
myapp:prod
✅ 标记构建信息
myapp:v1.0.0-20240115
myapp:v1.0.0-github-actions-123
❌ 避免在生产使用latest标签
latest可能指向不同版本,不可预测
容器运行:
✅ 给容器命名
docker run --name webapp-prod myapp
✅ 设置重启策略
docker run --restart=always myapp
✅ 限制资源
docker run --memory=512m --cpus=1 myapp
✅ 挂载数据卷
docker run -v /data:/app/data myapp
✅ 健康检查
docker run --health-cmd="curl -f http://localhost/health" myapp
容器监控:
# 查看容器状态
docker ps
# 查看资源使用
docker stats
# 查看日志
docker logs -f 容器名
# 查看详细信息
docker inspect 容器名
# 进入容器
docker exec -it 容器名 bash
仓库安全:
✅ 使用HTTPS
✅ 启用认证
✅ 定期扫描镜像漏洞
✅ 清理无用镜像
✅ 备份重要镜像
访问控制:
✅ 最小权限原则
✅ 使用访问令牌
✅ 定期更换密码
✅ 审计日志
镜像(Image):
├─ 只读模板
├─ 分层存储
├─ 唯一标识
└─ 用于创建容器
容器(Container):
├─ 镜像的运行实例
├─ 可读写
├─ 有生命周期
└─ 相互隔离
仓库(Repository):
├─ 存储和分发镜像
├─ 公有/私有
├─ 版本管理
└─ 协作共享
镜像 → 容器:docker run(创建运行)
容器 → 镜像:docker commit(提交变更)
镜像 → 仓库:docker push(推送)
仓库 → 镜像:docker pull(拉取)
容器 → 镜像:docker export(导出)
镜像 → 容器:docker import(导入)
必须掌握:
✅ 镜像的分层概念
✅ 容器的生命周期
✅ 仓库的使用方法
✅ 三者的协作关系
理解即可:
⚠️ 镜像底层存储原理
⚠️ 容器隔离技术细节
⚠️ 仓库网络协议
动手尝试:
1. 搜索并拉取常用镜像
2. 运行容器并管理生命周期
3. 注册Docker Hub账号
4. 推送自己的镜像
推荐命令:
docker images # 查看镜像
docker ps -a # 查看容器
docker search nginx # 搜索镜像
docker pull nginx # 拉取镜像
docker run nginx # 运行容器
下一章:Docker镜像基础
将学习:
概念理解:用自己的话解释镜像、容器、仓库三者的区别和联系。
生命周期:画出容器的生命周期状态转换图,并说明每个状态的含义。
命名规范:以下镜像名称是否合法?如果不合法,请说明原因。
myapp:latestmy-app:v1.0
my app:v1.0registry.com/myapp:1.0实践操作:从Docker Hub搜索并拉取nginx镜像,运行一个容器,然后在浏览器中访问。
仓库使用:注册Docker Hub账号,创建一个仓库,推送自己的镜像。
容器管理:创建一个容器,练习暂停、恢复、停止、重启、删除等操作。
完整流程:编写一个简单的Dockerfile,构建镜像,推送到仓库,然后在另一台机器上拉取并运行。
故障排查:模拟容器无法启动的情况,尝试排查并解决问题。