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

02.容器架构

第二章 容器架构:从原理到实操的深度解析

文章目录

  • 第二章 容器架构:从原理到实操的深度解析
    • 容器三问:What、Why、How
      • 容器发展的 "进化史"
      • What:到底什么是容器?
      • 容器 vs 虚拟机:直观对比
      • Why:为什么需要容器?解决 "环境一致性" 痛点
      • Docker 的 "集装箱" 特性对应
    • 007 Docker 架构:核心组件与工作原理
      • Docker 的核心组件
      • Docker 的工作流程:启动一个容器的全过程
      • Docker 版本:CE 与 EE 的区别
    • 008 动手实操:从零开始运行你的第一个容器
      • 步骤 1:安装 Docker CE
      • 步骤 2:拉取第一个镜像
      • 步骤 3:启动第一个容器
      • 步骤 4:验证容器运行状态
      • 步骤 5:操作容器(启动、停止、删除)
      • 步骤 6:删除镜像
    • 小结:容器技术的核心价值

容器三问:What、Why、How

学习任何技术,都可以从最基础的三个问题入手:它是什么(What)?为什么需要它(Why)?它是如何工作的(How)?容器技术也不例外,咱们一步步揭开它的面纱。

容器发展的 “进化史”

容器技术并非一蹴而就,而是经过几十年的迭代才发展到今天的形态。咱们按时间线梳理下关键节点:

  • 1979 年:Chroot Jail(雏形)
    最早出现在 Unix V7 系统中,核心功能是 “改变根目录”(Change Root)。它能把一个进程及其子进程 “囚禁” 在指定目录下,让它们只能看到这个目录内的文件,无法访问系统其他部分。
    举个例子:就像给进程画了个 “圈”,圈外的东西看不见,但 root 用户能轻易 “跳出圈子”,安全性很弱。
  • 1982 年:Chroot 进入 BSD
    被整合到 BSD 系统中,功能上没有大的突破,但开始被更多人使用。
  • 2000 年:FreeBSD Jail(安全升级)
    解决了 Chroot 的安全漏洞,不仅能隔离文件系统,还能给每个 “Jail(监狱)” 分配独立的 IP 地址和用户权限。
    举个例子:相当于把一台服务器分成多个 “迷你服务器”,每个 Jail 里的应用互不干扰,管理员能单独管理。
  • 2001 年:Linux VServer(跨发行版隔离)
    首次实现了在单个 Linux 系统上运行多个不同的 Linux 发行版(比如在 CentOS 上跑 Ubuntu)。它结合了类似 Chroot 的隔离和 “安全上下文” 机制,让不同发行版的应用共存。
  • 2004 年:Solaris Containers(资源控制)
    引入 “区域(Zone)” 概念,不仅隔离进程,还能限制 CPU、内存等资源的使用。比如可以给某个容器分配 20% 的 CPU,避免它占用过多资源。
  • 2006 年:cgroups(资源管理核心)
    谷歌推出 Process Containers,2007 年改名为 cgroups(控制组),并被合并到 Linux 内核 2.6.24。它能精确控制一组进程的资源(CPU、内存、磁盘 I/O 等),是现代容器技术的核心底层技术。
  • 2008 年:LXC(首个 Linux 容器管理器)
    第一次把 cgroups 和 Linux 命名空间(Namespace,用于隔离进程 ID、网络等)结合起来,实现了完整的容器管理功能。用户可以通过 LXC 创建、启动、停止容器,但操作比较复杂。
  • 2013 年:Docker 横空出世
    基于 LXC 优化了用户体验,后来用自研的 libcontainer 替代 LXC,让容器操作变得简单易用。Docker 的出现真正让容器技术普及开来。
  • 2014 年及以后:百花齐放
    谷歌推出 LMCTFY(后并入 libcontainer)、CoreOS 推出 rkt,容器生态逐渐完善,最终 Kubernetes 成为容器编排的事实标准。

What:到底什么是容器?

一句话概括:容器是一种轻量级、可移植、自包含的软件打包技术,能让应用在任何环境中以相同方式运行

拆解来看,容器包含两部分:

  1. 应用程序本身:比如一个 Java 后端服务、一个 Python 脚本。
  2. 应用依赖:比如 Java 运行时(JRE)、Python 库、配置文件、系统工具等。

容器的核心特点:

  • 轻量级:不包含完整操作系统,只打包必要的依赖,体积通常是 MB 级(对比虚拟机的 GB 级)。
  • 可移植:在开发电脑上创建的容器,无需修改就能放到服务器、云平台上运行。
  • 隔离性:容器内的进程与主机及其他容器隔离,互不干扰(通过 Linux 命名空间实现)。
  • 资源可控:能限制容器使用的 CPU、内存等资源(通过 cgroups 实现)。

容器 vs 虚拟机:直观对比

很多人会把容器和虚拟机混为一谈,其实两者的设计思路完全不同。咱们用架构图和表格对比下:

特性容器(以 Docker 为例)虚拟机(以 VMware 为例)
底层依赖共享主机操作系统内核需安装完整操作系统(有独立内核)
启动速度秒级(比如启动 Nginx 容器约 0.1 秒)分钟级(启动 Windows 虚拟机约 30 秒)
体积大小通常几 MB 到几百 MB(如 Nginx 容器约 142MB)通常几 GB(如 Windows 10 虚拟机约 20GB)
资源占用低(1 台服务器可跑上千个容器)高(1 台服务器通常跑几十个虚拟机)
隔离级别进程级隔离(共享内核,隔离性较弱)完全隔离(独立内核,隔离性强)
迁移难度极简单(通过镜像复制)较复杂(需迁移整个虚拟机文件)

举个实际场景
如果要部署 10 个 Web 服务:

  • 用虚拟机:需要 10 台虚拟服务器,每台安装操作系统、Web 服务器,耗时且占资源。
  • 用容器:10 个容器共享主机内核,直接基于 Web 服务器镜像启动,几分钟搞定,资源占用仅为虚拟机的 1/10。

Why:为什么需要容器?解决 “环境一致性” 痛点

软件开发中,最头疼的问题之一就是 “环境不一致”:

  • 开发环境:程序员的笔记本(Windows/macOS,各种自定义配置)。
  • 测试环境:公司内部服务器(Linux,特定版本依赖)。
  • 生产环境:公有云 / 私有云(可能是不同的 Linux 发行版,严格的权限控制)。

结果就是:“在我电脑上能跑啊!” 成了开发和运维的日常争吵。

容器如何解决这个问题?
它借鉴了集装箱思想

  • 运输行业的痛点:以前货物运输时,不同货物(香蕉、铁桶)需要不同的处理方式,换交通工具(卡车→轮船)时要重新装卸,效率低且易损坏。
  • 集装箱的解决方案:统一标准的箱子,不管装什么货物,都能直接在各种交通工具间转移,无需重新打包。

容器对软件的作用,就像集装箱对货物的作用:

  • 开发人员把应用和所有依赖 “装进” 容器,形成一个标准化的 “软件集装箱”。
  • 这个容器可以在开发、测试、生产环境中无缝迁移,因为容器内的环境是完全一致的。

用矩阵图看容器的价值:
没有容器时,N 种服务和 M 种环境会形成 N×M 的适配难题(比如服务 A 在环境 1 正常,在环境 2 报错);有了容器后,只需确保容器能在环境中运行,服务与环境的适配问题被消除。

Docker 的 “集装箱” 特性对应

Docker 作为最流行的容器工具,完美体现了集装箱的设计思想:

集装箱特性Docker 对应功能实际例子
标准化包装镜像(Image)一个mysql:8.0镜像,包含 MySQL 8.0 及所有依赖,在哪都能跑
跨平台兼容容器可在任何支持 Docker 的环境运行本地开发的容器,直接部署到阿里云 ECS、腾讯云 CVM
隔离不干扰命名空间隔离(进程、网络、文件系统等)容器 A 的 MySQL 崩溃,不会影响容器 B 的 Nginx 服务
资源可控cgroups 资源限制限制容器最多使用 1 核 CPU、2GB 内存
高效搬运镜像仓库(Registry)从 Docker Hub 下载镜像,比手动安装快 10 倍
职责分工开发打包镜像,运维管理容器开发只关心代码,运维只关心容器运行环境

007 Docker 架构:核心组件与工作原理

Docker 采用客户端 - 服务器(C/S)架构,就像咱们用手机(客户端)给服务器发消息(请求),服务器处理后返回结果。咱们一步步拆解它的核心组件和工作流程。

Docker 的核心组件

Docker 的架构由以下几部分组成,缺一不可:

  1. Docker 客户端(Client)
    是用户与 Docker 交互的入口,通常是命令行工具(docker命令),也可以是图形化界面(如 Docker Desktop)。
    作用:接收用户输入的命令(如docker run),并发送给 Docker daemon 处理。

    命令示例

    # 查看客户端版本
    docker --version
    # 输出:Docker version 24.0.6, build ed223bc# 启动一个Nginx容器
    docker run -d -p 80:80 nginx
    
  2. Docker 守护进程(Daemon)
    后台运行的服务(进程名为dockerd),是 Docker 的 “大脑”。
    作用:

    • 接收并处理客户端的命令(如创建容器、下载镜像)。
    • 管理 Docker 的核心对象:镜像、容器、网络、存储卷。
    • 与其他守护进程通信(比如在集群环境中)。

    查看守护进程状态(Linux)

    systemctl status docker
    # 输出中"active (running)"表示正在运行
    
  3. Docker 镜像(Image)
    是容器的 “模板”,一个只读的文件集合,包含运行应用所需的所有内容(代码、依赖、配置、环境变量等)。
    特点:

    • 分层存储:镜像由多个只读层组成,复用相同的层(比如多个镜像都依赖 Ubuntu 底层,只存一份),节省空间。
    • 不可修改:一旦创建就不能修改,若要修改需创建新的镜像层。

    举例nginx:latest镜像包含 Ubuntu 系统基础文件、Nginx 程序、默认配置等,基于它可以启动多个 Nginx 容器。

  4. Docker 容器(Container)
    是镜像的 “运行实例”,相当于从模板创建的 “可执行文件”。
    与镜像的关系:就像 Java 中 “类” 和 “对象” 的关系(镜像是类,容器是对象)。
    特点:

    • 可读写:容器在镜像的只读层上增加了一个可写层,所有修改都保存在这一层。
    • 生命周期可控:可以被创建、启动、停止、重启、删除。
  5. 镜像仓库(Registry)
    是存放 Docker 镜像的 “仓库”,类似代码仓库(如 GitHub)。
    分类:

    • 公有仓库:最著名的是 Docker Hub(https://hub.docker.com/),包含数百万个公开镜像(如 Nginx、MySQL)。
    • 私有仓库:企业或个人搭建的仓库(如 Harbor),用于存放私密镜像(如公司内部的业务系统镜像)。

Docker 的工作流程:启动一个容器的全过程

docker run nginx命令为例,看看 Docker 各组件是如何协作的:

  1. 用户输入命令:在终端执行docker run nginx(客户端发起请求)。
  2. 客户端转发请求:Docker 客户端将命令转换为 API 请求,发送给 Docker daemon。
  3. 检查本地镜像:Docker daemon 先检查主机上是否有nginx镜像:
    • 若没有,就去默认的镜像仓库(Docker Hub)下载镜像(类似从网上下载软件安装包)。
    • 若有,直接使用本地镜像。
  4. 创建并启动容器:Docker daemon 基于nginx镜像创建容器(在镜像只读层上添加可写层),并启动容器内的 Nginx 进程。
  5. 返回结果:容器启动成功后,Docker daemon 将结果返回给客户端,用户在终端看到输出。

Docker 版本:CE 与 EE 的区别

Docker 分为两个版本,适合不同场景:

  • Docker CE(Community Edition):社区版,免费开源,适合个人开发者和小型团队。
  • Docker EE(Enterprise Edition):企业版,收费,提供官方支持、安全增强等功能,适合大型企业。

版本号规则(2017 年 3 月后):

  • 采用YY.MM格式(如 24.06 表示 2024 年 6 月发布)。
  • 每季度发布一个稳定版(如 24.03、24.06),CE 版维护 4 个月,EE 版维护 12 个月。
  • 每月发布一个 Edge 版(如 24.04、24.05),适合尝鲜新功能。

008 动手实操:从零开始运行你的第一个容器

理论讲完了,咱们动手实操,体验 Docker 的便捷。以下操作以 Linux(CentOS 7)为例,Windows/macOS 用户可安装 Docker Desktop,操作命令一致。

步骤 1:安装 Docker CE

# 1. 安装依赖工具
yum install -y yum-utils device-mapper-persistent-data lvm2# 2. 添加Docker软件源(阿里云,速度更快)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 3. 安装Docker CE
yum install -y docker-ce docker-ce-cli containerd.io-ce docker-ce-cli containerd.io# 4. 启动Docker服务并设置开机自启
systemctl start docker
systemctl enable docker# 5. 验证安装(输出版本信息表示成功)
docker --version

步骤 2:拉取第一个镜像

从 Docker Hub 拉取nginx镜像(Nginx 是常用的 Web 服务器):

docker pull nginx

执行后,终端会显示下载进度,类似:

Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
...
Digest: sha256:xxxxxx
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

查看本地镜像:

docker images
# 输出类似:
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    605c77e624dd   2 weeks ago    142MB

步骤 3:启动第一个容器

nginx镜像启动一个容器,并将容器的 80 端口映射到主机的 80 端口(这样就能通过主机 IP 访问容器内的 Nginx):

docker run -d -p 80:80 --name my-first-nginx nginx

参数说明:

  • -d:后台运行容器( detach )。
  • -p 80:80:端口映射,格式为 “主机端口:容器端口”。
  • --name my-first-nginx:给容器起个名字(方便后续操作)。
  • nginx:指定要使用的镜像。

步骤 4:验证容器运行状态

# 查看正在运行的容器
docker ps
# 输出类似:
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                               NAMES
f47b353d4a7a   nginx     "/docker-entrypoint.…"   3 seconds ago   Up 2 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   my-first-nginx

此时,在浏览器中输入主机的 IP 地址(如http://192.168.1.100),就能看到 Nginx 的默认欢迎页面,说明容器运行正常!

步骤 5:操作容器(启动、停止、删除)

# 停止容器
docker stop my-first-nginx# 启动已停止的容器
docker start my-first-nginx# 重启容器
docker restart my-first-nginx# 查看所有容器(包括已停止的)
docker ps -a# 删除容器(需先停止)
docker rm my-first-nginx

步骤 6:删除镜像

# 删除nginx镜像(需先删除基于该镜像的所有容器)
docker rmi nginx

小结:容器技术的核心价值

容器技术的出现,彻底改变了软件的开发、测试和部署方式:

  • 对开发人员:只需关注代码,不用关心环境差异(“Build Once, Run Anywhere”)。
  • 对运维人员:只需维护容器运行环境,不用为每个应用配置依赖(“Configure Once, Run Anything”)。
  • 对企业:缩短开发周期、降低运维成本、提高系统可靠性。

下一章,我们将深入学习 Docker 镜像的构建(通过 Dockerfile)和容器的高级操作,让你真正掌握容器技术的精髓!

http://www.dtcms.com/a/392584.html

相关文章:

  • Diffusion Model与视频超分(1):解读淘宝开源的视频增强模型Vivid-VR
  • 通过提示词工程(Prompt Engineering)方法重新生成从Ollama下载的模型
  • 有没有可以检测反爬虫机制的工具?
  • 大模型为什么需要自注意力机制?
  • 长度为K子数组中的最大和-定长滑动窗口
  • Linux安装Kafka(无Zookeeper模式)保姆级教程,云服务器安装部署,Windows内存不够可以看看
  • WEEX编译|续写加密市场叙事
  • 为 Element UI 表格增添排序功能
  • 点评项目(Redis中间件)第四部分缓存常见问题
  • 动态水印也能去除?ProPainter一键视频抠图整合包下载
  • DevSecOps 意识不足会导致哪些问题
  • LeetCode:27.合并两个有序链表
  • 适用于双节锂电池的充电管理IC选型参考
  • 格式说明符
  • 层数最深叶子节点的和(深度优先搜索)
  • 【git】安装和基本指令
  • 如何利用AI技术快速生成专业级的PPT和视频内容
  • Linux系统之----线程互斥与同步
  • ARM SMMUv2架构下的安全和非安全状态(secure/non-secure)下的的资源分配解析
  • 面向linux新手的OrcaTerm AI 最佳实践
  • 构建高可用 LVS-DR + Keepalived 负载均衡集群实战指南
  • 网络协议总结
  • Python多线程爬虫加速电商数据采集
  • JVM之直接内存(Direct Memory)
  • 深入理解C指针(四):回调函数与qsort——指针实战的终极舞台
  • 翻拍图像检测(即拍摄屏幕的照片)功能实现思路
  • 【Linux】进程概念(上):从冯诺依曼到进程入门
  • 计算机视觉(opencv)实战二十八——基于 OpenCV CSRT 跟踪器的实时目标
  • 【Mysql】深分页问题、页分裂问题、加密/解密、执行计划
  • 【名人简历】牛顿