Docker核心概念

一、镜像(Image)

1.1 镜像概念

1.1.1 什么是镜像

镜像定义:一个只读的模板,包含创建Docker容器的指令。

东巴文理解

镜像 = 蛋糕配方 + 模具
就像:做蛋糕的配方和模具

配方记录了:
├─ 需要什么材料(基础镜像)
├─ 怎么加工(RUN命令)
├─ 暴露什么(EXPOSE端口)
└─ 怎么食用(CMD命令)

用配方和模具可以做出无数个相同的蛋糕(容器)

镜像组成

┌─────────────────────────────┐
│   应用层(Application)      │  ← 应用代码
├─────────────────────────────┤
│   依赖层(Dependencies)     │  ← 依赖库
├─────────────────────────────┤
│   运行时层(Runtime)        │  ← Python/Java/Node.js
├─────────────────────────────┤
│   基础系统层(Base OS)      │  ← Ubuntu/Alpine/Debian
└─────────────────────────────┘

每一层都是只读的,层层叠加

1.1.2 镜像特点

只读性

镜像 = 只读模板
├─ 创建后不可修改
├─ 只能通过构建新镜像来"修改"
└─ 多个容器可以共享同一个镜像

分层存储

镜像分层示例:

镜像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

1.2 镜像命名规范

1.2.1 镜像名称格式

完整格式

[仓库地址/]镜像名[:标签]

示例:
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:标签

1.2.2 标签命名建议

版本标签

推荐格式:
├─ v1.0.0:语义化版本
├─ 1.21.0:纯数字版本
├─ 20240115:日期版本
└─ dev/test/prod:环境标签

示例:
myapp:v1.0.0
myapp:1.21.0
myapp:20240115
myapp:dev
myapp:prod

1.3 镜像分类

1.3.1 按来源分类

官方镜像

特点:
├─ Docker官方维护
├─ 质量有保证
├─ 安全性高
├─ 更新及时
└─ 无前缀

示例:
├─ nginx
├─ mysql
├─ redis
├─ python
├─ node
└─ ubuntu

认证镜像

特点:
├─ 第三方公司认证
├─ 质量较高
├─ 有官方前缀
└─ Docker Hub认证

示例:
├─ bitnami/nginx
├─ percona/mysql
└─ circleci/python

用户镜像

特点:
├─ 个人用户上传
├─ 质量参差不齐
├─ 有用户名前缀
└─ 需谨慎使用

示例:
├─ username/myapp
└─ company/project

1.3.2 按用途分类

基础镜像

操作系统镜像:
├─ 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

特点:
├─ 开箱即用
├─ 预配置环境
└─ 直接部署运行

二、容器(Container)

2.1 容器概念

2.1.1 什么是容器

容器定义:镜像的运行实例,一个轻量级的独立可执行软件包。

东巴文理解

容器 = 正在运行的程序
就像:用配方做出的蛋糕

镜像(配方):
├─ 静态的
├─ 只读的
└─ 可以创建多个容器

容器(蛋糕):
├─ 动态的
├─ 可读写的
├─ 有生命周期
└─ 相互隔离

容器特点

隔离性:
├─ 进程隔离
├─ 网络隔离
├─ 文件系统隔离
└─ 资源隔离

轻量级:
├─ 共享主机内核
├─ 秒级启动
├─ MB级内存占用
└─ 高密度部署

可移植:
├─ 环境一致
├─ 跨平台运行
└─ 一次构建到处运行

2.1.2 容器与镜像的关系

关系图

┌─────────────────────────────┐
│         镜像(Image)        │
│      (只读模板)            │
└──────────┬──────────────────┘
           │ docker run
           ↓
┌─────────────────────────────┐
│       容器(Container)      │
│    (镜像 + 可写层)         │
├─────────────────────────────┤
│  ┌───────────────────────┐  │
│  │   可写容器层           │  │ ← 容器独有
│  ├───────────────────────┤  │
│  │   镜像层(只读)       │  │ ← 共享镜像
│  └───────────────────────┘  │
└─────────────────────────────┘

对比

镜像:
├─ 静态概念
├─ 只读
├─ 存储在磁盘
├─ 不可变
└─ 类比:类(Class)

容器:
├─ 动态概念
├─ 可读写
├─ 运行在内存
├─ 有生命周期
└─ 类比:实例(Instance)

2.2 容器生命周期

2.2.1 生命周期状态

状态转换图

         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(已删除):
├─ 容器已删除
├─ 文件系统已清理
└─ 不可恢复

2.2.2 生命周期管理命令

创建和启动

# 创建容器(不启动)
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)

2.3 容器标识

2.3.1 容器ID

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

2.3.2 容器名称

命名规则

# 自动命名(随机生成)
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

三、仓库(Repository)

3.1 仓库概念

3.1.1 什么是仓库

仓库定义:集中存储和分发镜像的地方。

东巴文理解

仓库 = 镜像超市
就像:存放商品的仓库或超市

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

3.1.2 仓库分类

公有仓库

Docker Hub:
├─ 官方仓库
├─ 地址:https://hub.docker.com
├─ 免费公开镜像
├─ 付费私有镜像
└─ 自动构建功能

其他公有仓库:
├─ GitHub Container Registry
├─ Google Container Registry
├─ Amazon ECR Public
└─ 阿里云容器镜像服务

私有仓库

Docker Registry:
├─ 官方开源
├─ 轻量级
├─ 基础功能
└─ 适合小团队

Harbor:
├─ 企业级
├─ 功能丰富
├─ 权限管理
├─ 镜像扫描
└─ 适合企业

Nexus:
├─ 多种制品管理
├─ Maven、Docker等
└─ 统一管理

3.2 Docker Hub使用

3.2.1 注册和登录

注册账号

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

3.2.2 搜索镜像

网页搜索

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

3.2.3 拉取镜像

基本拉取

# 拉取最新版本
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

3.2.4 推送镜像

推送步骤

# 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

3.3 私有仓库搭建

3.3.1 Docker Registry

快速搭建

# 拉取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

3.3.2 Harbor(企业级)

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

四、三者关系与应用

4.1 协作关系

4.1.1 工作流程

完整工作流程

┌─────────────────────────────────────────────┐
│              开发者工作站                    │
├─────────────────────────────────────────────┤
│  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         │
└─────────────────────────────────────────────┘

4.1.2 实际应用示例

场景:部署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

4.2 最佳实践

4.2.1 镜像管理实践

镜像构建

✅ 使用明确的基础镜像版本
   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可能指向不同版本,不可预测

4.2.2 容器管理实践

容器运行

✅ 给容器命名
   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

4.2.3 仓库管理实践

仓库安全

✅ 使用HTTPS
✅ 启用认证
✅ 定期扫描镜像漏洞
✅ 清理无用镜像
✅ 备份重要镜像

访问控制

✅ 最小权限原则
✅ 使用访问令牌
✅ 定期更换密码
✅ 审计日志

五、本章小结

5.1 核心要点

5.1.1 三大概念总结

镜像(Image):
├─ 只读模板
├─ 分层存储
├─ 唯一标识
└─ 用于创建容器

容器(Container):
├─ 镜像的运行实例
├─ 可读写
├─ 有生命周期
└─ 相互隔离

仓库(Repository):
├─ 存储和分发镜像
├─ 公有/私有
├─ 版本管理
└─ 协作共享

5.1.2 关系总结

镜像 → 容器:docker run(创建运行)
容器 → 镜像:docker commit(提交变更)

镜像 → 仓库:docker push(推送)
仓库 → 镜像:docker pull(拉取)

容器 → 镜像:docker export(导出)
镜像 → 容器:docker import(导入)

5.2 学习建议

5.2.1 理解重点

必须掌握:
✅ 镜像的分层概念
✅ 容器的生命周期
✅ 仓库的使用方法
✅ 三者的协作关系

理解即可:
⚠️ 镜像底层存储原理
⚠️ 容器隔离技术细节
⚠️ 仓库网络协议

5.2.2 实践建议

动手尝试:
1. 搜索并拉取常用镜像
2. 运行容器并管理生命周期
3. 注册Docker Hub账号
4. 推送自己的镜像

推荐命令:
docker images          # 查看镜像
docker ps -a           # 查看容器
docker search nginx    # 搜索镜像
docker pull nginx      # 拉取镜像
docker run nginx       # 运行容器

5.3 下一章预告

下一章:Docker镜像基础

将学习:

  • 🖼️ 镜像详细操作命令
  • 🔍 查看镜像详细信息
  • 🗑️ 删除和清理镜像
  • 📦 镜像的导入导出

📝 练习题

基础题

  1. 概念理解:用自己的话解释镜像、容器、仓库三者的区别和联系。

  2. 生命周期:画出容器的生命周期状态转换图,并说明每个状态的含义。

  3. 命名规范:以下镜像名称是否合法?如果不合法,请说明原因。

    • myapp:latest
    • my-app:v1.0 my app:v1.0
    • registry.com/myapp:1.0

进阶题

  1. 实践操作:从Docker Hub搜索并拉取nginx镜像,运行一个容器,然后在浏览器中访问。

  2. 仓库使用:注册Docker Hub账号,创建一个仓库,推送自己的镜像。

  3. 容器管理:创建一个容器,练习暂停、恢复、停止、重启、删除等操作。

实践题

  1. 完整流程:编写一个简单的Dockerfile,构建镜像,推送到仓库,然后在另一台机器上拉取并运行。

  2. 故障排查:模拟容器无法启动的情况,尝试排查并解决问题。