详细解读Docker

1.概述

Docker是一种优秀的开源的容器化平台。用于部署、运行应用程序,它通过将应用及其依赖打包成轻量级、可移植的容器,实现高效一致的运行效果,简单来说,Docker就是一种轻量级的虚拟技术。

2.核心概念

2.1.容器(Container)

容器是独立运行的进程单元,包含应用程序代码、运行时环境、系统工具和依赖库。

1.每个容器相互隔离,共享主机操作系统内核

2.启动速度快,资源占用低

2.2.镜像(Image)

镜像是容器启动的静态模板,包含创建容器所需的分层文件系统

1.通过Dockerfile定义构建步骤(例如指定基础镜像,安装依赖)

2.支持版本管理和共享(如Docker hub共享仓库)

2.3.仓库(Registry)

用于仓储和分发镜像的平台(如Docker Hub、私有仓库)

3.核心功能

3.1.容器化技术

  • 应用隔离:将应用及其依赖打包到独立的容器中
  • 环境一致性:保证开发、测试、生产环境的一致性
  • 快速部署:秒级启动和停止容器

3.2.镜像管理

  • 分层存储:镜像采用分层结构,共享基础层,节省存储空间
  • 版本控制:支持镜像的版本管理和回滚
  • 镜像仓库:Docker Hub等平台提供镜像共享和分发

3.3.资源管理

  • 资源限制:可以限制容器的CPU、内存、磁盘IO等资源
  • 网络管理:提供多种网络模式(bridge、host等)
  • 存储管理:支持数据卷,绑定挂载等持久化存储方案

4.容器化&虚拟化

  • Infrastructure:基础设施,可以是个人电脑、主机服务器
  • Host Operating system:运行的主操作系统,例如windows、mac、Linux
  • Hypervisor:虚拟机管理器,可以虚拟出多个硬件,然后再安装操作系统,再部署应用
  • Guest OS:从操作系统,有Hypervisor虚拟出来
  • BINS/LIBS:二进制文件(Binaries)/库文件(Libraries),例如应用程序相关的编译后的可以执行的二进制文件,提供给应用程序调用的同样功能的库文件
  • Docker Daemon:Docker守护进程,代替了虚拟机的Hypervisor,docker守护进程本质是运行在主操作系统上的一个进程,直接与操作系统进行交互,这也是Docker 容器比较快的原因。

虽然虚拟机比较笨重但是也不是没有优势,可以讲服务器比作一个码头,拥有各种设备和场地(服务器硬件资源),服务器虚拟化类似在码头上有好多个仓库,仓库可以完全独立,每个仓库有各自的管理人员,Docker容器类似仓库里面的集装箱,每个集装箱各自独立,灵巧,方便迁移,但是隔离性比较差,多个集装箱统一由一个管理者进行管理,所有集装箱信息就暴露给一个管理人员,而仓库则可以有各自的用户,例如云服务提供者,通过虚拟出一个独立的虚拟机,有自己的用户,即租户管理自己的虚拟机。

复制代码
# Docker 架构
+-------------------------------------------------------+
|                   Application A                       |
|                   Application B                       |
|                   Application C                       |
+-------------------------------------------------------+
|                 Docker Engine                         |
+-------------------------------------------------------+
|                 Host Operating System                 |
+-------------------------------------------------------+
|                 Physical Hardware                     |
+-------------------------------------------------------+

# 虚拟机架构
+-----------+ +-----------+ +-----------+
|   App A   | |   App B   | |   App C   |
+-----------+ +-----------+ +-----------+
| Guest OS  | | Guest OS  | | Guest OS  |
+-----------+ +-----------+ +-----------+
|                Hypervisor                            |
+-------------------------------------------------------+
|                Host Operating System                 |
+-------------------------------------------------------+
|                Physical Hardware                     |
+-------------------------------------------------------+

4.1.详细对比

特性 Docker (容器) 虚拟机 (VM)
启动速度 秒级启动 分钟级启动
性能 接近原生性能 有性能损耗(5-15%)
资源占用 轻量(MB级别) 重量(GB级别)
隔离性 进程级别隔离 完整的系统级别隔离
安全性 相对较低(共享内核) 较高(完全隔离)
镜像大小 通常为 MB 级别 通常为 GB 级别
部署密度 高(单机可运行数百容器) 低(单机通常10-20个VM)
兼容性 依赖宿主机内核 任何支持虚拟化的系统
迁移性 跨平台有限制 跨平台性好
系统开销 低(无额外OS开销) 高(每个VM需要完整OS)

4.1.技术实现对比

技术层面 Docker 虚拟机
虚拟化类型 操作系统级虚拟化 硬件级虚拟化
虚拟化技术 Namespaces, Cgroups Hypervisor (KVM, VMware, Hyper-V)
Guest OS 不需要,共享主机内核 每个VM需要完整的Guest OS
资源分配 动态分配,按需使用 预先分配固定资源
镜像构建 Dockerfile,分层构建 模板或快照,整体构建

5.Docker使用场景

使用Docker容器开发、测试、部署服务:因为Docker本身非常轻量化,所以本地开发人员可以构建、运行并分享Docker容器。容器可以在开发环境中创建,然后再提交到测试,最终进入生产环境。

创建隔离的运行环境:在很多企业应用中,同一服务的不同版本可能服务于不同的用户,那么使用Docker非常容易创建不同的生成环境来运行不同的服务。

搭建测试环境:由于Docker的轻量化,所以开发者很容易利用Docker在本地搭建测试环境,用来测试程序在不用系统下的兼容性;甚至搭建集群的部署测试。

构建多用户的平台即服务(PaaS)基础设施。

提供软件即服务(SaaS)应用程序。

高性能、超大规模的宿主机部署。

5.1.Docker组成

5.2.Docker 客户端 / 守护进程

Docker是C/S架构的程序:Docker客户端向Docker服务器端,也就是Docker的守护进程发出请求,守护进程处理完所有的请求工作并返回结果。Docker 客户端对服务器端的访问既可以是本地也可以通过远程来访问。

5.3.Docker Image 镜像

镜像是Docker容器的基石,容器基于镜像启动和运行。镜像就好比容器的源代码,保存了用于启动容器的各种条件。

Docker的镜像是一个层叠的只读文件系统,最低端是一个引导文件系统(即bootfs),第二层是root文件系统(即rootfs),它位于bootfs之上,可以是一种或多种操作系统,比如Ubuntu或者CentOS。在Docker中,root文件系统永远只能是只读状态,并且docker运用联合加载技术又会在root文件系统之上加载更多的只读文件系统,联合加载指的是一次加载多个文件系统,但是在外面看起来只能看到一个文件系统,联合加载会将各层文件系统叠加到一起,这样最终的文件系统会包含所有的底层文件和目录,docker将这样的文件系统称为镜像。

5.4.Docker Container 容器

容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

当一个容器启动时,Docker会在该镜像的最顶层加载一个读写文件系统,也就是一个可写的文件层,我们在Docker运行的程序,就是在这个层中进行执行的,当Docker第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层上,比如像修改一个文件,该文件首先会从读写层下面的只读层复制到该读写层,该文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏,这就是Docker的一个重要技术:写时复制(copy on write)。每个只读镜像层都是只读的,永远不会变化,当创建一个新容器时,Docker会构建出一个镜像栈,

5.5.Docker Registry 仓库

Registry仓库是集中存放Docker镜像文件的场所。人们有时候会把Repository仓库和Registry仓库混为一谈,并不严格区分。实际上,Registry仓库上往往存放着多个Repository仓库,每个Repository仓库中又包含了多个Docker镜像,每个Docker镜像有不同的标签(tag)。

Registry仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool 等,可以提供大陆用户更稳定快速的访问。

6.Dockerfile

Dockerfile 是用于构建 Docker 镜像的文本文件,包含一系列指令。每个指令在镜像中创建一个新层,最终形成可运行的容器环境。

6.1.Dockerfile 是什么

  • 文本文件: 纯文本文件,通常命名为 Dockerfile (首字母大写,无扩展名是惯例)。
  • 指令集合: 包含一系列按顺序执行的指令 (INSTRUCTION arguments)。
  • 构建蓝图: 描述了如何从基础组件(通常是基础镜像)一步步组装成一个新的、可运行的镜像。
  • 自动化构建: 执行 docker build 命令时,Docker 引擎读取 Dockerfile 并执行其中的指令,最终生成一个镜像。
  • 可重复性 & 版本控制: Dockerfile 本身可以被版本控制(如 Git),确保镜像构建过程透明、可审计、可重复。

6.2.Dockerfile 的核心组成部分

|------------|--------|-----------------------------------------------------------------|----------------------------------------------------------------------------------------|-------------------------------------|
| 指令 | 目的 | 说明 | 示例 | 最佳实践 |
| FROM | 基础镜像 | 必须是第一个指令,指定构建新镜像所属的现有镜像 | FROM ubuntu:22.04 FROM python:3.9-slim-buster | 使用官方、轻量级、具体版本的基础镜像。 |
| RUN | 执行命令 | 在构建期间,在新镜像的文件系统层中执行命令 | RUN apt-get update && apt-get install -y nginx RUN pip install -r requirements.txt | 合并命令减少层数;清理缓存;命令失败时应返回非零。 |
| COPY | 复制文件 | 从构建上下文复制文件或目录到镜像指定路径 | COPY ./app /usr/src/app COPY requirements.txt . | 优先使用 COPY;明确复制目标目录。 |
| ADD | 复制与解压 | 类似COPY,单增加了功能;自动解压本地.tar文件,支持URL源 | ADD ./app.tar.gz /opt/ ADD https://example.com/file /tmp/ | 除非需要解压或 URL 下载,否则优先用 COPY。 |
| CMD | 容器默认命令 | 知道容器启动运行的默认命令及参数每个Dockerfile只能有一个CMD可被docker run覆盖 | CMD ["nginx", "-g", "daemon off;"] CMD ["python", "app.py"] | 使用exec形式避免shell进程;仅指定主进程 |
| ENTRYPOINT | 容器入口点 | 定义容器启动时可执行程序,CMD作为参数传递给ENTRYPOINT,可被 docker run --entrypoint 覆盖 | ENTRYPOINT ["python"] CMD ["app.py"] | 常与CMD配合使用;优先exec形式;用于固定入口 |
| WORKDIR | 设置工作目录 | 设置后续指令(RUN、CMD)的工作目录 | WORKDIR /app RUN pwd # 输出 /app | 为清晰路径设置,替代 RUN cd ...;用绝对路径。 |
| EXPOSE | 申明端口 | 文档性说明容器在运行时监听哪些网络端口,不实际发布端口 | EXPOSE 80 EXPOSE 8000/tcp | 说明服务监听的端口;真实端口映射在 docker run 时指定。 |
| ENV | 设置环境变量 | 设置环境变量,可以在构建和运行期间使用 | ENV PYTHONUNBUFFERED=1 ENV APP_HOME=/app | 配置服务行为;使用变量简化 Dockerfile。 |
| ARG | 构建时变量 | 定义仅在构建过程中有效的变量,可用docker build --build -arg 传入 | ARG VERSION=latest RUN apt-get install package=$VERSION | 用于参数化构建;不同默认值于不同阶段。 |
| VOLUME | 定义匿名卷 | 在镜像中创建一个挂载点,用于关联外部存储 | VOLUME /var/lib/mysql | 声明需要持久化或共享数据的目录。 |
| USER | 切换用户 | 设置后续指令(RUN、CMD)运行时的用户及用户组 | USER www-data USER 1000:1000 | 避免 root 用户运行应用;提高安全性。 |
| LABEL | 添加元数据 | 为镜像添加描述性元数据,如维护者信息,许可证等 | LABEL maintainer="dev@example.com" LABEL version="1.0" | 记录镜像相关信息。 |
| ONBUILD | 延迟指令 | 将指令标记为延迟执行,当该镜像被作为另一个构建的基础时才触发。 | ONBUILD COPY . /app/src | 用于构建基础镜像。 |

7.最佳实践

  • 精简基础镜像: 使用 alpine、slim 等小型基础镜像减少攻击面和最终镜像大小。
  • 合并 RUN 指令: 将多个 RUN 命令(特别是 apt-get update && install && clean)合并为一个,减少层数并清理包管理器缓存。
  • 合理利用缓存: 将更改频率低的指令(如安装核心依赖)放前面,更改频率高的指令(如复制应用代码)放后面。
  • 使用 .dockerignore 文件: 明确忽略构建上下文中的不必要文件。
  • 优先使用 COPY 而非 ADD: 除非明确需要解压缩或从 URL 下载,否则用更简单直接的 COPY。
  • 指定版本标签: FROM 和依赖安装时使用明确版本,避免因 latest 标签更新导致的意外行为。
  • 减少镜像层数: 虽然层本身开销不大,但过多小层不利于管理,合并相关操作有益。
  • 设置非 root 用户: 在 RUN 用户级步骤后使用 USER,避免容器以 root 权限运行应用,提高安全性。
  • 使用多阶段构建: 分离构建环境和运行环境,大幅减小最终生产镜像体积(见示例)。
  • 明确暴露端口: 使用 EXPOSE 声明容器监听的端口。
  • 优先 exec 格式: 对 CMD 和 ENTRYPOINT 使用 JSON 数组格式 ["executable", "param1", "param2"] (exec 格式),避免不必要的 shell 进程并确保信号正确处理。
  • 添加元数据: 使用 LABEL 提供镜像信息。
  • 设置工作目录: 用 WORKDIR 替代 RUN cd ... && ...,使用绝对路径。
  • 考虑安全性: 定期更新基础镜像和依赖包修复漏洞;避免在 Dockerfile 或镜像中存储硬编码的机密信息,使用 ARG 或 secrets(在运行时通过环境变量或卷传入)。
  • 包含健康检查: 对关键服务使用 HEALTHCHECK 帮助编排系统管理容器状态。
相关推荐
回忆是昨天里的海16 小时前
k8s部署dashboard ui管理平台
云原生·容器·kubernetes
chen_note19 小时前
Kubernetes1.23版本搭建(三台机器)
运维·容器·kubernetes·云计算·kubepi
花落已飘19 小时前
openEuler WSL2容器化开发实战:Docker Desktop集成与应用部署
运维·docker·容器
高旭博1 天前
7. kubernetes资源——service服务
云原生·容器·kubernetes
斯普信专业组1 天前
Docker 常用命令与时区配置指南
docker·容器·eureka
天一生水water1 天前
ubuntu使用毫秒镜像方式安装docker mysql
ubuntu·阿里云·docker
Qayrup2 天前
docker 搭建私有仓库,推送并拉取
运维·docker·容器
郭庆汝2 天前
docker拉取英伟达官方cuda11.8镜像
docker·cuda11.8
天下不喵2 天前
Ubuntu24.04安装Docker过程记录
docker