云原生学习笔记(五) 构建 Docker 镜像与运行容器

第八篇:构建 Docker 镜像的艺术:从 Dockerfile 到多阶段构建

参考文档:


一、镜像是由哪些"层"组成的?

Docker 镜像并非单一文件,而是由多层(Layer)组成的只读文件系统叠加而成。

🧱 每一层来源:

  • 镜像层 = Dockerfile 中每条指令(如 RUN, COPY, ADD)创建一层
  • 底层基础镜像层 + 应用构建层 + 配置层

🔁 层的优点:

  • 缓存重用:只变更发生的层重新构建,提高构建速度
  • 共享优化:多个镜像可共享相同层,节省空间
  • 版本控制友好:变更可追踪与回滚

二、编写 Dockerfile 的最佳实践

Dockerfile 是构建镜像的"配方脚本",描述从哪开始、执行什么命令、如何构建运行环境。

🛠 Dockerfile 基本结构:

dockerfile 复制代码
# 指定基础镜像
FROM python:3.12-slim

# 设置工作目录
WORKDIR /app

# 拷贝文件
COPY requirements.txt .

# 安装依赖
RUN pip install -r requirements.txt

# 拷贝源代码
COPY . .

# 定义容器启动命令
CMD ["python", "app.py"]

✅ 常用指令说明:

指令 作用
FROM 基础镜像
RUN 执行命令并创建新镜像层
COPY 拷贝本地文件至镜像内
WORKDIR 设置默认工作目录
CMD 默认启动命令
ENV 设置环境变量
EXPOSE 声明开放的端口(文档提示)

🧼 编写建议:

  • 合并多个 RUN 命令为一条,减少层数
  • 明确 .dockerignore 文件排除无关文件(如 .git/, node_modules/

三、构建、标记和推送镜像的流程

🔧 构建镜像:

bash 复制代码
docker build -t myapp:1.0 .
  • -t:指定镜像名称和标签(tag)
  • .:当前目录为构建上下文

🏷 为镜像打标签:

bash 复制代码
docker tag myapp:1.0 myregistry.example.com/myapp:1.0

☁️ 推送到远程仓库:

bash 复制代码
docker push myregistry.example.com/myapp:1.0

确保已使用 docker login 登录仓库。


四、构建缓存机制的使用

构建缓存能大幅提升镜像构建效率,但也需注意顺序与变更影响。

🚀 缓存命中规则:

  • Docker 会按顺序逐条执行指令
  • 当前指令和其上下文(依赖的文件)没有变化时,则命中缓存

🔥 示例:

dockerfile 复制代码
COPY requirements.txt .
RUN pip install -r requirements.txt  # ✅ 如果 requirements 没变则可用缓存
COPY . .                             # ❌ 若这里提前 COPY,会导致前面的 RUN 缓存失效

✅ 优化建议:

  • 把稳定的文件(如依赖)提到前面
  • 利用 --target 分阶段构建调试
  • 修改频繁的代码层尽量靠后

五、多阶段构建:减小镜像体积的利器

"构建时用大镜像,运行时只带最小必需组件"

🎯 使用场景:

  • 项目依赖大量构建工具(如 Java, Go, C++ 项目)
  • 最终镜像希望精简(无 Node、无 Maven)

🏗 示例:Go 应用的多阶段构建

dockerfile 复制代码
# 第一阶段:构建阶段
FROM golang:1.22 as builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# 第二阶段:运行阶段
FROM alpine:latest
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]

🎉 优点:

  • 最终镜像干净、体积小
  • 减少安全风险面(无编译器、构建工具残留)
  • 更适合生产环境部署

六、总结与建议

概念/操作 说明
镜像层 多层组成,支持缓存与共享
Dockerfile 镜像构建蓝图,合理组织命令可加速构建
镜像标签 有助于版本管理与部署识别
构建缓存 避免重复构建,提高构建效率
多阶段构建 精简镜像,提升安全性与部署效率

第九篇:运行容器的实战技巧:网络、数据卷与多容器协作

参考文档:


一、容器端口映射:让服务暴露给外部访问

容器内部的服务默认无法被主机直接访问,需通过 端口映射 将其公开。

🔌 示例:

bash 复制代码
docker run -d -p 8080:80 nginx
  • -p <宿主端口>:<容器端口>
  • 访问 http://localhost:8080 即可访问容器内 nginx 的 80 端口

🌐 支持多端口、多容器绑定:

bash 复制代码
docker run -p 5000:5000 myapp
docker run -p 3306:3306 mysql

二、自定义容器默认启动命令

镜像中通常会设置默认启动命令(CMD),但可在运行时覆盖。

🛠 使用命令行覆盖:

bash 复制代码
docker run ubuntu echo "Hello from container"

即使镜像默认执行 bash,此处也会覆盖为 echo

🧩 ENTRYPOINT 与 CMD 区别:

指令类型 特点
CMD 可被 docker run 参数覆盖
ENTRYPOINT 固定命令,后接参数不影响本体

三、数据持久化:容器生命周期外保存数据

容器删除时,其内部数据也会丢失。为实现持久化,可使用:

✅ Docker 卷(Volume):

bash 复制代码
docker volume create mydata
docker run -v mydata:/data myapp
  • 卷位于 Docker 管理目录下,不随容器删除
  • 支持多个容器共享

🗂 绑定主机目录:

bash 复制代码
docker run -v /host/path:/container/path myapp
  • 直接映射宿主机文件夹
  • 可用于调试、本地开发

四、共享本地文件与挂载策略

将本地代码、配置等文件共享给容器使用,适用于开发测试场景。

📁 示例:

bash 复制代码
docker run -v $(pwd):/usr/src/app myapp
  • 主机当前目录(代码)映射到容器工作目录
  • 每次本地代码修改容器可实时读取

📎 挂载模式说明:

模式 说明
读写(默认) -v src:dest
只读 -v src:dest:ro
SELinux 支持 :z:Z 标志

五、多容器应用:使用 Docker Compose 编排服务

大型应用常由多个服务组成,如:

  • Web 应用(Node.js / Flask)
  • 数据库(MySQL / PostgreSQL)
  • 缓存(Redis)
  • 消息队列(RabbitMQ)

使用 Docker Compose 编排管理多个容器。

🧾 示例 docker-compose.yml

yaml 复制代码
version: "3"
services:
  web:
    image: myapp
    ports:
      - "8080:80"
  db:
    image: postgres
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:

🚀 启动应用:

bash 复制代码
docker compose up -d
  • 自动创建网络、卷
  • 服务间自动 DNS 发现(web 可通过 db 名称访问 PostgreSQL)

六、实践总结

操作点 命令或说明
映射端口 -p 宿主端口:容器端口
覆盖默认启动命令 docker run 镜像 <新命令>
数据卷持久化 -v 卷名:/路径-v 宿主路径:/路径
文件共享与挂载 本地映射容器目录(开发中常用)
多容器应用编排 使用 docker-compose.yml 配置

相关推荐
木风小助理9 小时前
PostgreSQL 的范式跃迁:从关系型数据库到统一数据平台
服务器·云原生·kubernetes
阿里云云原生9 小时前
ECS 端口不通,丢包诊断看这里!阿里云 SysOM 智能诊断实战!
云原生
阿里云云原生10 小时前
从这张年度技术力量榜单里,看见阿里云从云原生到 AI 原生的进化能力和决心
云原生
阿里云云原生11 小时前
2025 智能体工程现状
云原生·llm
是一个Bug11 小时前
云原生架构
云原生·架构
BUTCHER515 小时前
【漏洞扫描】ZooKeeper 未授权访问
分布式·zookeeper·云原生
企鹅侠客16 小时前
探索Kubernetes的ServiceAccounts
云原生·容器·kubernetes
虫小宝17 小时前
电商返利APP容器编排实践:K8s在多环境部署中的资源调度优化
云原生·容器·kubernetes
Linux云计算+运维开发17 小时前
k8s集群(k8s-v1.35.0)
云原生·容器·kubernetes
Gold Steps.17 小时前
Prometheus+Grafana+Alertmanager:云原生部署的 K8s 集群监控架构方案
云原生·grafana·prometheus