云原生学习笔记(五) 构建 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 配置

相关推荐
SilentSamsara2 小时前
存储卷体系:EmptyDir/HostPath/PV/PVC/StorageClass 的选型决策树
服务器·微服务·云原生·容器·架构·kubernetes·k8s
王的宝库3 小时前
【K8s】集群安全机制(二):授权(Authorization)详解与实战
学习·云原生·容器·kubernetes
东北甜妹5 小时前
Docker 容器故障排查
云原生·eureka
Shining05966 小时前
QEMU 编译开发环境搭建
人工智能·语言模型·自然语言处理·云原生·qemu·vllm·华为昇腾
匀泪1 天前
云原生(Kubernetes service微服务)
微服务·云原生·kubernetes
倔强的胖蚂蚁1 天前
Ollama Modelfile 配置文件 全指南
云原生·开源
AutoMQ1 天前
AWS 新发布的 S3 Files 适合作为 Kafka 的存储吗?
云原生·消息队列·云计算
MY_TEUCK1 天前
从零开始:使用Sealos Devbox快速搭建云原生开发环境
人工智能·spring boot·ai·云原生·aigc
没有口袋啦2 天前
《基于 GitOps 理念的企业级自动化 CI/CD 流水线》
阿里云·ci/cd·云原生·自动化·k8s
柯西劝我别收敛2 天前
Koordinator-Scheduler 调度器源码解析
后端·云原生