当前位置: 首页 > news >正文

Docker 镜像与容器核心概念详解

1. Docker 镜像是什么?

Docker 镜像是一个轻量级、可执行的独立软件包,包含运行某个软件所需的所有内容:代码、运行时环境、系统工具、系统库和设置。镜像采用分层存储结构,每一层都是只读的,这种设计带来了两大核心优势:

  • 节约存储空间:多个镜像可以共享相同的基础层,避免重复存储。
  • 高效分发与构建:镜像层可以被缓存和复用,加速构建和拉取过程。

简单来说,镜像 = 应用程序代码 + 微型操作系统环境 + 配置,是一个静态的、分层的文件系统快照。

2. Dockerfile 指令详解

2.1 COPY 与 ADD 的区别

COPY:主要用于将宿主机(构建上下文)的文件或目录复制到镜像中。

COPY app.py /app/

ADD:除了具备 COPY 的功能外,还额外支持:

  • 自动解压 tar、gzip、bzip2、xz 等压缩包
  • 支持从 URL 下载文件(但不推荐,因为无法保证下载文件的完整性)
ADD app.tar.gz /app/ # 会自动解压到 /app/ 目录

最佳实践:除非需要解压功能,否则优先使用 COPY,因为它更透明、更可预测。

2.2 VOLUME 指令

VOLUME 指令在镜像中声明一个挂载点,用于持久化数据和共享数据:

VOLUME /var/lib/mysql

当容器启动时:

  • Docker 会自动创建一个匿名卷(随机名称)挂载到容器的 /var/lib/mysql 目录
  • 即使容器被删除,卷中的数据仍然保留
  • 也可以通过docker run -v指定具名卷或宿主机目录覆盖此声明

2.3 CMD 与 ENTRYPOINT 的区别

ENTRYPOINT:定义容器启动时必须执行的核心命令,通常是一个脚本或可执行文件。

CMD:定义容器启动时的默认参数。如果启动容器时指定了其他命令,CMD 中的内容会被覆盖。

组合使用示例

ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["nginx", "-g", "daemon off;"]

等价于容器启动时执行:

/docker-entrypoint.sh nginx -g "daemon off;"

关键点

  • CMD 中的参数会作为位置变量传递给 ENTRYPOINT 对应的脚本
  • daemon off强制 Nginx 以前台进程模式运行(容器中运行的程序必须前台运行)
  • 容器生命周期 = 容器中运行的主进程生命周期

2.4 Shell 调试模式

在 Dockerfile 或启动脚本中常用的 Shell 选项:

set -eux # -e (errexit):上条命令执行失败时立即退出脚本 # -u (nounset):引用未定义变量时报错退出 # -x (xtrace):打开调试模式,显示执行的每一条命令 set +x # 关闭调试模式

3. 如何制作更小的镜像?

镜像大小直接影响构建速度、存储成本和网络传输效率。优化策略:

  1. 减少镜像层数:每个 RUN、COPY、ADD、WORKDIR、ENV 等指令都会创建新层
    • 合并多个 RUN 命令:RUN apt-get update && apt-get install -y package && rm -rf /var/lib/apt/lists/*
    • 减少不必要的文件复制
  2. 使用最小的基础镜像
    • Alpine Linux:仅 5MB 左右
    • Distroless:只包含应用程序及其运行时依赖,没有 Shell 和包管理器
    • Scratch:空镜像,适合静态编译的程序
  3. 合理使用多阶段构建:在构建阶段安装编译工具,最终镜像只包含运行所需文件
  4. 使用 .dockerignore 文件:排除不必要的构建上下文文件
  5. 数据与镜像分离:使用卷(Volume)挂载配置文件、日志、数据库文件等可变数据

4. 实战案例:Python Flask 微服务镜像制作

4.1 项目结构

/myapp/python2/ ├── app.py # Flask 应用程序 ├── requirements.txt # Python 依赖 └── Dockerfile # 镜像构建文件

4.2 核心应用程序 (app.py)

from flask import Flask from redis import Redis, RedisError import os import socket 连接 Redis redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) app = Flask(name) @app.route("/") def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "&lt;h3&gt;Hello {name}!&lt;/h3&gt;" \ "&lt;b&gt;Hostname:&lt;/b&gt; {hostname}&lt;br/&gt;" \ "&lt;b&gt;Visits:&lt;/b&gt; {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if name == "main": app.run(host='0.0.0.0', port=80)

4.3 依赖文件 (requirements.txt)

flask redis

4.4 Dockerfile 配置

# 使用 Python 2.7 精简版作为基础镜像 FROM python:2.7-slim 设置工作目录 WORKDIR /app 复制当前目录所有文件到容器的 /app 目录 ADD . /app 安装 Python 依赖(使用国内镜像加速) RUN pip install --trusted-host https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt 暴露端口 EXPOSE 80 设置环境变量 ENV NAME World ENV AUTHOR cali 容器启动命令 CMD ["python", "app.py"]

4.5 构建与运行

# 构建镜像 docker build -t sweb:1.0 . 查看镜像 docker images 运行容器(映射宿主机 8050 端口到容器 80 端口) docker run -d --name sweb-1 -p 8050:80 sweb:1.0 查看运行状态 docker ps 访问应用 浏览器打开:http://宿主机IP:8050

4.6 网络配置与容器互联

微服务架构中,多个容器需要通信:

# 创建自定义网络(指定子网和网关) docker network create --driver bridge \ --subnet 172.20.0.0/16 \ --gateway 172.20.0.1 \ my-custom-network 启动容器并指定固定 IP docker run -d --name nginx-fixed-ip -p 8051:80 --network my-custom-network --ip 172.20.0.10 nginx 启动 Redis 容器(供 Flask 应用连接) docker run -d --name redis --network my-custom-network redis:alpine 修改 app.py 中的 Redis 连接主机名为 "redis"(容器名)
http://www.jsqmd.com/news/1289560/

相关文章:

  • TypeScript Workshop集成指南:如何将TypeScript与现有项目无缝整合
  • Docup部署指南:3种简单方法将文档发布到Web
  • 如何从零开始学习Docker安全?awesome-docker-security资源精选
  • Gscript核心功能全解析:从多平台编译到高级反检测技术
  • 杭州老铺黄金以旧换新对比直接回收,哪种变现方式收益更高? - 日常比对手册
  • 2026实测可用的免费导入题库刷题小程序有哪些 - 软件测评小帮手
  • 10个实用示例:React Native Modern Datepicker在真实项目中的应用技巧
  • 山东潍坊明驰环境|玻璃钢管道 + 玻璃钢罐成套解决方案厂家,适配化工、冶金、市政全场景 - 速递信息
  • 第 17 篇:Token 成本太高?教你把大模型调用成本降 70% > Java+AI 落地实战系列 | 精细化成本管控 | 不影响用户体验,综合降本 70%
  • AI写作辅助网站的合规秘籍:从文献整理到成稿的合规流程解析? - 掌桥科研-AI论文写作
  • TEL E208-000032-11 接口模块
  • Go-mtpfs开发者必备:核心代码实现原理与架构详解
  • STM32 采集效率翻倍!ADC+DMA 乒乓缓冲 + FreeRTOS 并行架构全拆解
  • Buzz:免费离线语音转文字的终极解决方案
  • 广州增值电信EDI许可证公司口碑好哪家更靠谱?创业者机构测评与选择建议 - GrowthUME
  • 低成本精准拓客,长沙中医馆 AI 运营服务商优选 - GrowthUME
  • Get It.高级技巧:利用Feynman技巧和测验功能深化概念理解
  • 三款游戏自动打金指南,简单操作新手轻松掌握
  • 从纸质家政合同到电子签,家政公司远程签完服务协议
  • React Native Modern Datepicker完全指南:打造高颜值跨平台日期选择器
  • 终极微信数据备份指南:3步掌握安全解密与完整数据保护方案
  • 从零开始:5分钟学会用Python构建你的缠论量化交易系统
  • 数字化转型:制造业AI智能体的专属方案与应用场景
  • 南昌老同学聚会火锅店推荐|多场景适配本地觅食实用指南 - 品牌2026推荐
  • Seedance2.0电影AI课:多镜头、一致角色、音频叙事一键成片
  • 2026年探秘佛山门窗源头厂家,哪家才是真正靠谱之选? - GrowthUME
  • 从入门到精通:React Native Modern Datepicker开发实战指南
  • Git 分支合并实战指南
  • Joker AIX 3D 导演台全解析:一站式影视分镜预演工作流
  • 深耕真空搅拌设备|东莞瑞景智造:技术破局,赋能全球新材料产业 - GrowthUME