【Docker】Docker的初步认识以及Ubuntu下的Docker环境安装、配置
前言
在当今快速迭代的软件开发与部署领域,容器化技术已成为不可或缺的核心力量,而 Docker 作为容器化技术的杰出代表,正以其轻量、高效、可移植的特性深刻改变着开发与运维的模式。它有效解决了 “在我机器上能运行,在你那里却不行” 的环境一致性难题,极大简化了应用的打包、分发与部署流程,让开发者能够更专注于业务逻辑的实现,而非环境配置的琐碎细节。
一、Docker的初步认识
1.什么是Docker?
Docker官网
DockerHub官网
Docker 是一个用于开发、部署和运行应用程序的开源平台,它采用容器化技术,将应用及其依赖项打包成独立的容器,确保应用在不同环境中无缝运行。以下是对 Docker 的详细解释:
(1). 核心概念
仓库(Registry)
- 镜像存储中心:仓库用于存储和分发镜像,例如 Docker Hub、阿里云容器镜像服务等。
- 公有与私有:公有仓库免费使用,私有仓库适合企业内部管理镜像。
- 注:类比为软件官网,其具有分发软件安装包(镜像)的功能。
镜像(Image)
- 容器的模板:镜像是一个只读的文件,包含创建容器所需的所有内容(代码、依赖、配置等)。
- 分层结构:镜像采用分层存储,复用公共层,减少存储空间和下载时间。
- 注:类比为常见的软件安装包。
容器(Container)
- 轻量级隔离环境:容器是应用运行的独立环境,包含代码、运行时、系统工具和库,与其他容器共享宿主机操作系统内核。
- 隔离性:容器之间相互隔离,不会影响其他容器或宿主机的运行状态。
- 注:类比为软件安装包安装软件后的一个正在运行的软件,在该软件环境(就相当于容器)下进行相应的工作。
(2). Docker 与传统虚拟机的区别
Docker 与虚拟化技术:本质差异与演进逻辑
Docker 与传统虚拟化技术(如 VMware、Hypervisor)均属于环境隔离技术,但在架构设计、资源利用和应用场景上存在本质差异。Docker 通过容器化技术对操作系统层进行深度封装,实现了比虚拟机更轻量、更高效的应用隔离方案。
1). 技术架构对比:从系统级隔离到应用级隔离
维度 | Docker 容器 | 传统虚拟机 |
---|---|---|
隔离层级 | 操作系统层(共享内核,隔离用户空间) | 硬件层(通过 Hypervisor 虚拟完整硬件) |
资源抽象 | 应用进程 + 依赖库 | 完整操作系统 + 硬件驱动 |
启动机制 | 直接启动应用进程(无需加载内核) | 需要引导整个操作系统 |
镜像体积 | 通常几十 MB 到 GB 级(分层存储) | 通常数 GB 到 TB 级(含完整系统) |
运行密度 | 单主机可运行数百个容器 | 单主机通常运行数十个虚拟机 |
2). Docker 的核心创新:容器深度封装技术
Docker 在容器基础上引入了三大核心封装机制:
-
联合文件系统(UnionFS)
- 通过分层存储技术,将应用依赖、配置和代码分层打包,不同容器可共享基础层,大幅减少存储空间占用和部署时间。
- 示例:多个 Python 应用可共享同一 Python 运行时镜像层。
-
网络命名空间与虚拟网络
- 为每个容器分配独立的网络栈(IP、端口、路由表),支持桥接、overlay 等多种网络模式,实现容器间安全通信。
- 对比虚拟机:无需为每个容器分配虚拟网卡,网络延迟更低。
-
Cgroups 资源隔离
- 通过 Linux Control Groups 精确限制容器的 CPU、内存、IO 等资源,避免单个容器耗尽系统资源。
- 特性:支持动态调整资源配额,适应弹性伸缩场景。
3). 性能对比:轻量与高效的实证数据
测试指标 | Docker 容器 | 虚拟机 | 性能差异 |
---|---|---|---|
启动时间 | 0.1-1 秒 | 30-120 秒 | 快 30-1000 倍 |
内存占用(Nginx) | ~5MB | ~200MB | 节省 97% 内存 |
吞吐量(HTTP 请求) | 约 95% 原生性能 | 约 70% 原生性能 | 提升 35% 吞吐量 |
4). 应用场景的分化与融合
-
Docker 适用场景:
- 微服务架构(如 Netflix、Amazon 的容器化改造)
- CI/CD 流水线(GitLab、Jenkins 的容器化部署)
- 开发环境一致性保障(DevOps 团队协作)
-
虚拟机适用场景:
- 异构操作系统共存(Windows + Linux 混合环境)
- 安全敏感型应用(金融、医疗领域的合规要求)
- 资源密集型单应用(传统数据库、中间件)
-
融合趋势:
- 容器云平台:在虚拟机集群上部署 Docker,兼顾隔离性与弹性(如 AWS EKS、阿里云 ACK)
- 边缘计算:轻量级容器在资源受限设备上替代虚拟机(如 Raspberry Pi + Docker)
5). 技术选型决策矩阵
需求维度 | 优先选择 Docker | 优先选择虚拟机 |
---|---|---|
资源利用率 | 高(密度部署) | 低(冗余系统开销) |
部署速度 | 秒级(适合频繁迭代) | 分钟级(适合长期稳定运行) |
异构环境支持 | 单一内核(Linux/Windows) | 多操作系统(跨平台兼容) |
安全隔离级别 | 进程级隔离(需加固配置) | 系统级隔离(天然安全边界) |
Docker 与传统虚拟机的区别的总结:容器技术的演进价值
Docker 通过操作系统级虚拟化,在保留虚拟机隔离优势的同时,消除了传统虚拟化的性能损耗和资源冗余。其核心价值在于:
- 开发效率提升:一次构建,随处运行,彻底解决 “环境不一致” 问题
- 运维成本降低:资源利用率提升 3-5 倍,部署速度提升 10-100 倍
- 架构创新:推动微服务、Serverless 等新型架构落地
对比项 | Docker 容器 | 传统虚拟机 |
---|---|---|
隔离级别 | 共享内核,进程级隔离 | 完全隔离,包含独立操作系统 |
启动速度 | 秒级启动 | 分钟级启动 |
资源占用 | 轻量,仅需必要依赖 | 重量级,需完整操作系统 |
性能 | 接近原生性能 | 性能损耗较大 |
部署效率 | 高(镜像复用、快速部署) | 低(需安装完整操作系统) |
虚拟机的架构图:
Docker的架构图:
简化的虚拟机和Docker的架构对比图:
(3). Docker 的优势
- 环境一致性:确保开发、测试、生产环境一致,避免 “环境差异” 导致的问题。
- 快速部署与扩展:容器秒级启动,支持快速复制和扩展,适应微服务架构。
- 资源利用率高:多个容器共享内核,资源占用少,提升硬件利用率。
- 可移植性强:一次构建,随处运行(支持 Linux、Windows、macOS 等)。
- 版本控制:镜像支持版本管理,方便回滚和追踪变更。
(4). 典型应用场景
- 微服务架构:将应用拆分为多个独立容器,实现松耦合、高可用。
- 持续集成与部署(CI/CD):自动化构建、测试和部署容器化应用。
- 开发环境管理:为团队提供一致的开发环境,避免依赖冲突。
- 资源密集型应用:通过容器隔离和资源限制,优化资源分配。
(5). 基本工作流程
- 编写 Dockerfile:定义应用的环境和依赖。
- 构建镜像:使用
docker build
命令创建镜像。 - 运行容器:使用
docker run
命令启动容器。 - 推送 / 拉取镜像:将镜像上传至仓库或从仓库下载。
(6). 核心组件
- Docker 引擎:运行在宿主机上的服务,负责创建和管理容器。
- Docker CLI:命令行工具,用于与 Docker 引擎交互。
- Docker Compose:定义和运行多容器应用的工具(通过 YAML 文件配置)。
- Docker Swarm/Kubernetes:容器编排工具,用于集群管理和自动化部署。
Docker-总结
Docker 通过容器化技术,将应用与环境解耦,实现了高效、一致的应用交付。它已成为云计算、DevOps 和微服务领域的基石技术,帮助开发者和运维团队降低成本、提升效率。在后续内容中,我们将详细介绍如何在 Ubuntu 系统上安装和配置 Docker 环境。
2.为什么使用Docker?
使用 Docker 的核心价值,在于它从根本上解决了软件开发、部署和运维中的一系列经典痛点,尤其在云原生、微服务和 DevOps 兴起的背景下,其优势被进一步放大。具体可从以下 6 个核心场景和技术价值展开:
1). 彻底解决 “环境不一致” 问题:一次构建,随处运行
开发中最常见的矛盾是:“在我电脑上能跑,到你这怎么就报错了?” 根源在于开发、测试、生产环境的依赖(如系统版本、库版本、配置文件)存在差异。
Docker 通过容器镜像将应用及其所有依赖(代码、运行时、库、环境变量、配置文件)打包成一个不可变的 “标准化交付单元”。无论在开发者的笔记本(Ubuntu/macOS)、测试服务器(CentOS)还是生产集群(云服务器),只要安装了 Docker,容器就能以完全一致的方式运行,消除了 “环境适配” 的重复劳动。
2). 资源效率碾压传统虚拟化:轻量、高密度、低成本
相比虚拟机(VM),Docker 容器的 “轻量性” 带来了显著的资源优势:
- 启动速度:容器直接复用宿主机内核,无需加载完整操作系统,启动时间从虚拟机的 “分钟级” 缩短到 “秒级甚至毫秒级”(如 Nginx 容器启动仅需 0.1 秒)。
- 资源占用:容器仅包含应用及必要依赖,镜像体积通常是虚拟机镜像的 1/10 到 1/100(例如一个 Python 应用容器约 50MB,而同等功能的虚拟机镜像可能达 5GB)。
- 运行密度:单台服务器可运行数百个容器(而虚拟机通常只能运行几十个),大幅提升硬件利用率,降低服务器采购和运维成本(尤其对云服务器按资源计费场景)。
3). 简化部署与运维:从 “手动配置” 到 “自动化交付”
传统部署流程(如手动安装依赖、改配置、启停服务)不仅繁琐,还容易因人为操作出错。Docker 通过镜像版本管理和容器编排,将部署流程 “代码化”:
- 版本可控:镜像支持版本标签(如
app:v1.0
、app:v2.0
),部署时指定版本即可,回滚时只需切换标签,比手动卸载 / 重装高效 10 倍以上。 - 自动化集成:无缝对接 CI/CD 工具(如 GitLab CI、Jenkins),代码提交后自动构建镜像、运行测试、部署到目标环境,实现 “提交即部署” 的 DevOps 闭环。
- 批量操作:通过 Docker Compose 或 Kubernetes,可一键启动 / 停止 / 扩容多个关联容器(如 “前端 + 后端 + 数据库” 的微服务组合),替代复杂的手动脚本。
4). 微服务架构的 “最佳搭档”:解耦与弹性伸缩
在微服务架构中,一个系统被拆分为多个独立服务(如用户服务、订单服务、支付服务),每个服务需要独立部署、扩展和维护。Docker 的特性完美适配这一需求:
- 服务隔离:每个微服务运行在独立容器中,通过虚拟网络通信,单个服务崩溃不会影响其他服务,且资源(CPU / 内存)可单独限制,避免 “一个服务耗尽整机资源”。
- 弹性伸缩:当某个服务压力增大时,可通过容器编排工具(如 K8s)快速复制多个容器实例分担负载,压力减小时自动销毁冗余实例,实现 “按需分配资源”。
- 技术栈灵活:不同微服务可使用不同技术栈(如 A 服务用 Python,B 服务用 Java),容器化后无需担心依赖冲突,降低跨团队协作的技术门槛。
5). 开发效率提升:快速搭建 “干净环境”
开发者常需要在本地测试不同版本的依赖(如 “测试 Python 3.8 和 3.9 对应用的影响”),或临时启动辅助服务(如 Redis、MySQL)。传统方式需手动安装、配置,结束后还得清理残留文件,耗时且易污染系统。
Docker 可通过临时容器快速解决:
- 启动一个
redis:6.2
容器,用完直接删除(docker rm
),无需担心系统残留配置; - 为不同依赖版本创建独立镜像(如
app:py38
、app:py39
),切换环境只需切换容器,避免本地环境 “越用越乱”。
6). 跨平台兼容性:从本地到云,无缝迁移
无论是个人电脑(Windows/macOS/Linux)、物理服务器,还是公有云(AWS/Azure/ 阿里云)、私有云,只要支持 Docker,容器就能一致运行。这打破了 “云厂商锁定”:
- 开发者在本地用 Ubuntu 开发的容器,可直接部署到阿里云 ECS(CentOS 系统),无需修改任何配置;
- 未来若需从 AWS 迁移到自建数据中心,只需迁移镜像和容器配置,避免因平台差异导致的 “重写适配代码”。
总结:Docker 的核心价值公式
Docker = 环境一致性 + 资源效率 + 部署自动化 + 架构灵活性
它不是 “银弹”,但在大多数场景下(尤其是分布式系统、频繁迭代、多环境协作),能将团队的 “无效劳动”(环境调试、手动部署、跨平台适配)转化为 “有效创新”,这也是它从 2013 年诞生至今,成为云原生时代基础设施的核心原因。
3.概念详解
1)镜像
操作系统一般分为内核和用户空间,而对于 Linux 而言,内核启动后,会挂载 root 文件系统(rootfs)为其提供用户空间支持。而 Docker 镜像(Image)就相当于是一个 root 文件系统。比如:官方镜像 ubuntu:22.04 就包含了完整的一套 Ubuntu 22.04 最小系统的 root 文件系统。同时,Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含 任何动态数据,其内容在构建之后也不会被改变。
镜像的分层存储:
因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。、
2)容器
镜像和容器的关系,就像面向对象编程里的类和实例:镜像是静态的模板,容器是镜像运行起来的实体,能被创建、启动、停止、删除等。
容器本质是进程,但它运行在独立的命名空间中,有自己的 root 文件系统、网络配置、进程空间等,就像在独立系统中操作,比直接在宿主运行更安全,这也让初学者易与虚拟机混淆。
容器和镜像一样采用分层存储,运行时以镜像为基础层,再创建一个容器存储层供读写。容器存储层随容器消亡而消失,所以里面的信息会跟着容器删除而丢失。
按 Docker 最佳实践,容器存储层要保持无状态,不写入数据。文件写入应使用数据卷或绑定宿主目录,这样能跳过容器存储层,直接操作宿主或网络存储,性能和稳定性更好。而且数据卷生命周期独立于容器,容器没了,数据卷里的数据也不会丢失。
3)仓库
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);而每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
以 Ubuntu 镜像为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如:16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest。
仓库名经常以两段式路径形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。
参考链接(如有侵权,请联系删除):
一文说清 Docker 是什么(非常详细),零基础入门到精通,看这一篇就够了-CSDN博客
二、基于Ubuntu下的Docker安装步骤
1.查看是否已经安装了Docker,如果安装则删除旧版本
#查看Docker版本
docker --version#删除旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
2.安装下载Docker时需要的依赖
#更新 apt 包索引
sudo apt-get update#安装相关软件包以允许 apt 通过 HTTPS 使用 docker 存储库
sudo apt-get install ca-certificates curl gnupg lsb-release
3.使用存储库安装 Docker
为什么使用存储库安装 Docker?
- 自动解决依赖:Docker 依赖于多个系统组件(如
containerd
、runc
),存储库安装会自动处理这些依赖关系。 - 版本管理:通过存储库可以轻松安装、升级或降级软件版本,且支持自动更新。
- 安全性:官方存储库的软件包经过签名验证,确保来源可信。
- 标准化流程:所有 Linux 发行版都支持通过存储库安装软件,操作统一。
(1)添加 Docker 的官方 GPG 密钥
# 1. 创建存放GPG密钥的目录
sudo mkdir -p /etc/apt/keyrings# 2. 下载Docker官方GPG密钥并保存
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
第一条命令:创建存放 GPG 密钥的目录
参数解析
-
sudo
以超级用户(root)权限执行命令,因为/etc
目录通常只有 root 用户可写。 -
mkdir
创建目录的命令(Make Directory)。 -
-p
递归创建父目录。如果/etc/apt/keyrings
的上级目录(如/etc/apt
)不存在,会自动创建它们。
例如:若/etc/apt
不存在,会先创建/etc/apt
,再创建/etc/apt/keyrings
。 -
/etc/apt/keyrings
目标目录路径。/etc/apt
:Debian 系 Linux 存放软件源配置的目录。keyrings
:专门用于存放 GPG 密钥环的子目录(从 APT 2.4 版本开始推荐)。
第二条命令:下载并保存 Docker 官方 GPG 密钥
管道前半部分:curl -fsSL [...]
-
curl
用于发送 HTTP 请求、下载文件的命令行工具。 -
-f
(--fail
)
若 HTTP 请求返回错误状态码(如 404、500),立即终止并返回错误,避免输出错误页面内容。 -
-s
(--silent
)
静默模式,不显示进度条和错误信息(但-S
会覆盖此选项,显示错误)。 -
-S
(--show-error
)
与-s
配合使用,即使静默模式也显示错误信息。 -
-L
(--location
)
若服务器返回重定向(如 301、302),自动跟随重定向到新 URL。 -
https://download.docker.com/linux/ubuntu/gpg
Docker 官方提供的 GPG 公钥下载地址,用于验证软件包的签名。
管道后半部分:sudo gpg --dearmor -o [...]
-
gpg
GNU Privacy Guard,用于加密、签名和验证的工具。 -
--dearmor
将 ASCII 格式的 GPG 密钥(文本形式)转换为二进制格式(.gpg
文件)。
例如,下载的原始密钥是:
plaintext
-----BEGIN PGP PUBLIC KEY BLOCK-----
...(长文本)...
-----END PGP PUBLIC KEY BLOCK-----
-
转换后变为二进制格式,便于 APT 系统读取。
-
-o /etc/apt/keyrings/docker.gpg
-o
(--output
):指定输出文件路径。
将转换后的二进制密钥保存为/etc/apt/keyrings/docker.gpg
。
为什么需要这两步?
-
安全性
GPG 密钥用于验证软件包是否由 Docker 官方发布,防止中间人攻击或篡改。 -
兼容性
从 APT 2.4 版本开始,推荐将密钥存放在/etc/apt/keyrings/
目录,并在软件源配置中用signed-by
指定密钥路径。 -
自动化
通过命令自动下载和配置密钥,避免手动操作可能的错误。
验证配置结果
bash
# 检查目录是否创建成功
ls -ld /etc/apt/keyrings# 检查密钥文件是否存在且正确
ls -l /etc/apt/keyrings/docker.gpg
gpg --show-keys /etc/apt/keyrings/docker.gpg
正常情况下,密钥文件权限应为 -rw-r--r--
(644),且能显示密钥的指纹信息(如 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
)。
(2)设置存储库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list.d/docker.list > /dev/null
逐段解析:
1. echo "deb [...]"
echo
:输出字符串到标准输出deb [...]
:这是 APT 软件源配置的格式,告诉系统从哪里下载软件包
2. [arch=$(dpkg --print-architecture)]
arch=
:指定软件包的架构(如 amd64、arm64)dpkg --print-architecture
:自动获取当前系统的架构- 例如在 x86_64 系统上会输出
amd64
- 在 ARM64 系统上会输出
arm64
- 例如在 x86_64 系统上会输出
- 作用:确保只下载与当前系统架构匹配的软件包
3. signed-by=/etc/apt/keyrings/docker.gpg
signed-by
:指定用于验证软件包签名的 GPG 密钥/etc/apt/keyrings/docker.gpg
:Docker 官方 GPG 密钥的路径- 作用:防止软件包被篡改,确保来源可信
4. https://download.docker.com/linux/ubuntu
- Docker 官方软件源的基础 URL
- Ubuntu 系统的 Docker 软件包都存放在这个服务器上
5. $(lsb_release -cs)
lsb_release -cs
:获取当前 Ubuntu 系统的版本代号(Codename)- 例如 Ubuntu 22.04 的代号是
jammy
- Ubuntu 20.04 的代号是
focal
- 例如 Ubuntu 22.04 的代号是
- 作用:自动适配不同版本的 Ubuntu,确保下载的软件包兼容
6. stable
- Docker 软件源的通道(channel)
stable
:稳定版(推荐生产环境使用)- 其他可选通道:
edge
(测试版)、nightly
(开发版)
7. | sudo tee -a /etc/apt/sources.list.d/docker.list
|
:管道符号,将前面的输出作为后面命令的输入sudo tee -a
:tee
:将输出同时写入文件和屏幕-a
:追加模式(append),不覆盖原有内容sudo
:以管理员权限执行
/etc/apt/sources.list.d/docker.list
:APT 软件源配置文件- APT 会自动读取这个目录下的所有
.list
文件
- APT 会自动读取这个目录下的所有
8. > /dev/null
>
:重定向符号/dev/null
:Linux 的黑洞设备,所有写入的数据都会被丢弃- 作用:隐藏命令的输出(不显示在终端)
总结
这个命令的核心作用是:
- 自动生成 Docker 官方软件源的配置
- 将配置写入
/etc/apt/sources.list.d/docker.list
文件 - 配置会根据当前系统架构和版本自动适配
- 使用 Docker 官方 GPG 密钥确保软件包安全
4.安装 Docker engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
5.验证安装是否完成
sudo docker -v
注:拉取镜像除了使用VPN,还可以配置到国内的镜像源进行拉取;Docker桌面版没怎么用,暂不介绍。