Docker(3)Docker 镜像 & Dockerfile

Docker 镜像 & Dockerfile

一、整体认知:镜像是如何诞生的?

Dockerfile → docker build → 镜像(多层只读)→ docker run → 容器(可写层)

核心结论

  • Dockerfile 是"源代码"

  • 镜像是"构建产物"

  • 容器是"运行实例"

  • 分层结构是 Docker 的灵魂


二、镜像分层结构(结合你发的图)

复制代码

纯文本

纯文本

复制代码
┌───────────────┐  ← 容器层(可写,临时)
│  Container    │
├───────────────┤
│  CMD / ENTRY  │  ← 镜像层4(不新增体积)
├───────────────┤
│  Nginx Install│  ← 镜像层3(RUN)
├───────────────┤
│  ADD Source   │  ← 镜像层2(ADD)
├───────────────┤
│  Yum Install  │  ← 镜像层1(RUN)
├───────────────┤
│  CentOS 7     │  ← 基础镜像层(FROM)
└───────────────┘

关键点

特性 说明
每层只读 镜像一旦构建不可更改
层可复用 不同镜像可共享同一层
写时复制 修改才复制到容器层
缓存命中 上层不变,下层直接复用

三、Dockerfile 如何驱动分层构建(逐条对照)

1️⃣ FROM(基础层)

复制代码

dockerfile

dockerfile

复制代码
FROM centos:7

✅ 对应:

  • 镜像最底层

  • 所有后续层的基础

📌 原则:

  • 越小越好

  • 越稳定越好


2️⃣ RUN(构建层,核心)

复制代码

dockerfile

dockerfile

复制代码
RUN yum install -y gcc gcc-c++ make

✅ 对应:

  • 镜像层 1

  • 每一条 RUN = 一个新层

📌 优化写法:

复制代码

dockerfile

dockerfile

复制代码
RUN yum install -y gcc make && \
    yum clean all && \
    rm -rf /var/cache/yum

3️⃣ ADD / COPY(文件层)

复制代码

dockerfile

dockerfile

复制代码
ADD nginx-1.20.tar.gz /usr/local/

✅ 对应:

  • 镜像层 2

  • 引入外部代码或源码

📌 规则:

  • ADD:自动解压(慎用)

  • COPY:语义清晰(推荐)


4️⃣ RUN(编译安装层)

复制代码

dockerfile

dockerfile

复制代码
RUN cd /usr/local/nginx && ./configure && make && make install

✅ 对应:

  • 镜像层 3

  • 构建期执行,不占容器运行时


5️⃣ CMD / ENTRYPOINT(运行定义层)

复制代码

dockerfile

dockerfile

复制代码
CMD ["nginx", "-g", "daemon off;"]

✅ 对应:

  • 不生成新镜像层

  • 决定容器启动行为

指令 是否可覆盖 场景
CMD 默认参数
ENTRYPOINT 固定主程序

四、容器运行时发生了什么?

  1. Docker 从镜像复制所有只读层

  2. 在最上层挂载 可写容器层

  3. 执行 CMD / ENTRYPOINT

  4. 容器停止 → 可写层销毁

  5. 镜像始终不变 ✅

📌 这就是 环境一致性​ 的根本原因


五、Dockerfile 核心指令速查表(考试级)

指令 是否建层 作用 建议
FROM 基础镜像 必写
RUN 构建命令 合并写
COPY 拷文件 首选
ADD 拷+解压 少用
CMD 启动命令 可覆盖
ENTRYPOINT 固定入口 生产推荐
ENV 环境变量 必用
WORKDIR 工作目录 代替 cd
EXPOSE 声明端口 仅说明
USER 运行身份 非 root
VOLUME 数据卷 存数据

六、镜像构建三大核心机制(图中红字)

✅ 1. 分层构建

  • 每层对应 Dockerfile 指令

  • 独立、可复用、可缓存

✅ 2. 缓存复用

  • 指令不变 → 层不变 → 秒级构建

  • 改一行代码 → 只重跑该行及之后

✅ 3. 写时复制(CoW)

  • 镜像层共享

  • 修改才复制

  • 节省磁盘 & 内存


七、Dockerfile 最佳实践(实战级)

✅ 使用 .dockerignore

✅ 合并 RUN,清理缓存

✅ 变量抽成 ENV

✅ 代码放最后(利用缓存)

✅ 多阶段构建减小体积

✅ 非 root 用户运行

✅ 明确 tag,不用 latest


八、多阶段构建(进阶,但非常值得)

复制代码

dockerfile

dockerfile

复制代码
FROM gcc AS builder
RUN gcc main.c -o app

FROM alpine
COPY --from=builder /app /app
CMD ["/app"]
相关推荐
Cx330❀5 小时前
【Linux网络】网络层协议 IP :从网络层原理到 Linux 内核源码
linux·运维·服务器·网络·tcp/ip·ai·ai编程
志栋智能5 小时前
运维超自动化的变更管理实践
运维·自动化
全栈攻略5 小时前
Docker 中 ROS2 工作流 Topic 验证与常用命令指南
运维·docker·容器
Gl�ria6 小时前
Linux 清理日志常用命令
linux·运维·服务器
j7~8 小时前
【Linux网络加餐(二)】《进程组,会话,控制终端,作业控制和守护进程》---详解
linux·运维·服务器·守护进程·会话·进程组·控制终端
名字还没想好☜8 小时前
Docker 数据卷实战:volume、bind mount、tmpfs 到底怎么选,数据持久化与权限坑
运维·docker·容器·kubernetes
天道jimmy8 小时前
VulnHub 系列:Prime,1
linux·运维·服务器
Lumistory8 小时前
从OPPO长安研发中心看头部科技企业的照明运维选择
大数据·运维·人工智能·光照贴图
唐青枫8 小时前
Docker diff 详解:看清容器里到底改了什么
docker
好评1248 小时前
【Linux】数据链路层
linux·运维·网络