云原生运维学习笔记:容器技术的演进、底层原理与 Docker 全生命周期管理

云原生运维学习笔记:容器技术的演进、底层原理与 Docker 全生命周期管理

在之前的系列笔记中,我们深入剖析了 OpenStack 这一经典私有云平台,以及华为云等公有云上的 IaaS 层基础设施(计算、存储、网络)。随着业务架构向微服务和分布式演进,以虚拟机为核心的基础设施面临着启动慢、资源开销大、环境一致性难以保证等瓶颈。云原生(Cloud Native)时代正式到来,而容器技术则是构建云原生架构最核心的基石。

本篇笔记将回归技术本源,从操作系统级虚拟化的历史演进讲起,深入剖析 Linux 内核 Namespace 与 Cgroups 的底层机制,对比容器与虚拟机的本质差异。随后,我们将进入实操环节,完成 Docker Engine 的定制化部署、C/S 架构拆解,并系统性地复盘 Docker 镜像(Image)生命周期管理中的所有核心指令与底层细节。


一、 容器技术的演进与底层基石

很多初学者认为 Docker 就是容器,这其实是本末倒置。Docker 只是容器技术发展过程中的一个极为成功的产品化封装,真正实现"隔离"与"限制"的,是 Linux 内核中沉淀了近 30 年的底层技术。

1.1 操作系统级虚拟化的历史演进

容器的发展并非一蹴而就,而是伴随着对操作系统资源隔离机制的不断探索:

  • 早期隔离思想 :1979 年,Unix V7 引入了 chroot() 系统调用。它能够修改进程的根目录,实现简单的文件系统隔离。虽然它没有 CPU、内存、网络的隔离,但这是人类第一次尝试将进程"关在笼子里",被视为容器最早的技术原型。
  • 完整 OS 级隔离雏形:1998 年 FreeBSD 推出 Jails,在 chroot 的基础上增加了进程和网络隔离,允许在一台物理机上运行多个独立的虚拟系统;2000 年 Solaris Zones 实现了更彻底的 CPU/内存/网络/文件系统隔离。
  • Linux 内核技术准备 :
    • 2002 年:Linux 引入 PID Namespace,实现进程 ID 隔离。
    • 2003 年:引入 Network Namespace,实现网络栈隔离。
    • 2004-2006 年:IPC、Mount Namespace 陆续并入内核。
    • 2007 年:Google 工程师主导的 Cgroups(Control Groups)合入内核,实现了 CPU、内存、IO 等资源的限制。
    • 2008 年:User Namespace 逐步完善,容器内部的 root 不再是宿主机的 root,解决了巨大的安全隐患。
      至此,Linux 容器底层的两座基石(Namespace 做隔离,Cgroups 做限制)全部就位。
  • 从 LXC 到 Docker :2008 年 LXC(Linux Containers)诞生,它是第一个完整的 Linux 用户态容器工具,但配置复杂、缺乏镜像机制。直到 2013 年,dotCloud 公司基于 LXC 孵化出了 Docker,创新性地提出了镜像分层、Dockerfile、镜像仓库等概念,将容器从"运维专家的玩具"变成了"应用打包分发的标准"。
  • 标准化与云原生编排:2014 年 Docker 1.0 发布;2015 年 OCI(开放容器基金会)成立,制定了镜像和运行时规范;同年 Google 开源 Kubernetes 并最终成为容器编排的事实标准。2022 年 Kubernetes 1.24 彻底移除了 dockershim,containerd 成为 K8s 默认的容器运行时,Docker 回归其作为开发者工具的本来面目。

1.2 容器与虚拟机的本质差异

传统虚拟化(如 VMware, KVM)的核心目标是创建完整的虚拟机,除了应用及其依赖(通常几十 MB),还需安装完整的 Guest OS(几十 GB)。而容器是操作系统级虚拟化,所有容器共享同一个 Host OS 内核。

这种架构的差异带来了以下显著区别:

  • 启动速度:虚拟机需要走完整的 BIOS 自检、OS 引导,处于分钟级;容器本质上只是宿主机上的一个特殊进程,秒级甚至毫秒级启动。
  • 性能与开销:虚拟机多了一层 Hypervisor 硬件虚拟化层,有性能损耗;容器直接运行在宿主机内核上,性能接近原生,且几乎没有额外的内存和存储开销。
  • 运行密度:单台宿主机通常只能运行几十个虚拟机,但可以轻松支撑上千个容器。

1.3 解决的核心问题:环境一致性

开发人员和运维人员常常面临一个 N×M 的矩阵困境:N 种服务(依赖不同的库和包)部署到 M 种环境(开发、测试、生产)。Docker 将应用及其所有依赖打包成一个轻量级、可移植、自包含的容器,实现了Build Once, Run Anywhere(一次构建,到处运行),彻底消除了环境不一致带来的"依赖地狱"。


二、 Docker 架构与生态体系

2.1 OCI 规范

为了保证容器生态健康发展,Docker、Google、CoreOS 等公司成立了 OCI。OCI 规范包含两大部分:Runtime Spec (容器运行环境规范)和 Image Format Spec(镜像打包格式规范)。有了这套标准,不同组织的容器可以在不同的运行时上运行,保证了互操作性。

2.2 Docker 核心架构

Docker 采用标准的 C/S(客户端/服务端)架构,主要包含三个核心组件:

  1. Docker Client(客户端) :用户交互的终端,执行 docker run、docker pull 等指令。它本身不直接创建容器,而是将指令通过 Socket 发送给 Docker Daemon。
  2. Docker Host(宿主机) :运行 dockerd 守护进程,真正负责镜像构建、拉取、容器创建与生命周期管理。
    • Images(镜像):只读模板,包含应用及依赖环境,采用分层存储。
    • Containers(容器):镜像的运行实例。在只读的镜像层之上叠加一层可读写层,所有运行时的数据修改都在这一层。
  3. Registry(镜像仓库):集中存放镜像的远程仓库(如 Docker Hub、Harbor 等),用于分发和分享镜像。

完整交互流程 :用户执行 docker run nginx -> Client 将请求发给 Daemon -> Daemon 检查本地是否有 nginx 镜像 -> 若无,则向 Registry 请求下载 -> 镜像下载到本地后,Daemon 创建网络、存储资源并启动容器。


三、 实战:Docker 环境的定制化部署

在真实的国内网络环境和生产服务器(如 CentOS 7)中,我们需要进行一系列前置准备才能顺利部署 Docker。

3.1 基础环境与 YUM 源配置

首先,挂载本地 ISO 镜像作为系统 YUM 源,确保基础依赖包的安装。

bash 复制代码
# 1. 挂载光驱(需在虚拟机光驱中加载 CentOS 7 ISO 镜像)
[root@docker ~]# mkdir /dvd
[root@docker ~]# cp /etc/fstab /etc/fstab.bak
[root@docker ~]# echo '/dev/sr0 /dvd iso9660 defaults 0 0' >> /etc/fstab
[root@docker ~]# mount /dvd
mount: /dev/sr0 写保护,将以只读方式挂载

# 2. 备份并替换原有 YUM 源
[root@docker ~]# mkdir /etc/yum.repos.d/bak
[root@docker ~]# mv /etc/yum.repos.d/*repo /etc/yum.repos.d/bak
[root@docker ~]# vim /etc/yum.repos.d/dvd.repo
[dvd]
name=local repo from dvd
baseurl=file:///dvd
gpgcheck=0

# 3. 清理并重新生成缓存
[root@docker ~]# yum clean all
[root@docker ~]# yum makecache

防火墙配置 :注意,防火墙不能简单关闭,因为部分容器服务依赖防火墙的 NAT 功能进行流量转发。我们将默认区域设为 trusted 以放行所有流量,同时保留 firewalld 服务。

bash 复制代码
[root@docker ~]# systemctl enable firewalld.service --now
[root@docker ~]# firewall-cmd --set-default-zone=trusted
success

3.2 安装 Docker Engine 与镜像加速

由于官方源下载缓慢,此处配置华为云镜像站作为 Docker CE 的 YUM 源。

bash 复制代码
# 1. 配置 Docker CE 仓库
[root@docker ~]# cat > /etc/yum.repos.d/docker-ce.repo <<'EOF'
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.huaweicloud.com/docker-ce/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=0
EOF

# 2. 安装并启动 Docker
[root@docker ~]# yum install -y docker-ce
[root@docker ~]# systemctl enable docker.service --now

配置镜像加速 :由于国内无法直接访问 Docker Hub 官方仓库(docker.io),必须配置镜像加速器。此外,如果企业内部有私有仓库,可以通过 insecure-registries 配置信任(跳过 HTTPS 证书校验)。

bash 复制代码
[root@docker ~]# mkdir -p /etc/docker 
[root@docker ~]# tee /etc/docker/daemon.json <<'EOF'
{
  "insecure-registries": ["hub.laoma.cloud"],
  "registry-mirrors": ["http://hub.laoma.cloud","https://docker.m.daocloud.io"]
}
EOF
[root@docker ~]# systemctl restart docker

3.3 C/S 架构分离部署实践

为了展示 Docker 的架构特性,我们进行服务端与客户端的分离部署。

Server 端配置(开启远程 TCP 访问) :

Docker Daemon 默认只监听本地的 Unix Socket,不允许远程连接。我们需要修改 systemd 的启动参数,让其监听 2375 端口(注意:生产环境裸奔 2375 端口极度危险,需配合 TLS 加密或内网防火墙)。

bash 复制代码
[root@docker ~]# vim /usr/lib/systemd/system/docker.service
# 在 ExecStart 参数中最后添加 -H tcp://0.0.0.0:2375
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375

[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker
[root@docker ~]# lsof -i :2375
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
dockerd 2565 root    3u  IPv6  76021      0t0  TCP *:2375 (LISTEN)

Client 端配置 :

在另一台机器(无需安装完整 Docker,只需安装客户端 CLI 工具)上操作:

bash 复制代码
[root@client ~]# yum install -y docker-ce-cli
# 通过 -H 参数指定远程 Docker Daemon 的地址进行通信
[root@client ~]# docker -H 10.1.8.130 run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
...

此时,镜像和容器实际上都存储在 Server 端的 /var/lib/docker 目录下,Client 仅作指令下发。


四、 Docker 镜像管理核心指令与实战

镜像(Image)是 Docker 的核心资产,掌握镜像的全生命周期管理是日常运维的基础。

4.1 搜索与下载:search & pull

虽然可以通过 docker search 搜索镜像,但由于网络原因经常报错,更推荐直接通过 Docker Hub 官方 API 或 Harbor API 查询版本标签。

查询镜像版本(利用 curl 与 jq):

bash 复制代码
# 查询官方镜像 nginx 的所有 tag
curl -s "https://registry.hub.docker.com/v2/repositories/library/nginx/tags/" | jq '.results[].name'

# 查询私有 Harbor 仓库(带认证)中 nginx 镜像的所有标签
curl -s -u student:Student123 "http://hub.laoma.cloud/api/v2.0/projects/library/repositories/nginx/artifacts" | jq -r '.[].tags[].name' | sort -V

下载镜像:

bash 复制代码
# 拉取 centos 8 镜像
[root@docker ~]# docker image pull centos:8
8: Pulling from library/centos
3c72a8ed6814: Pull complete 
Digest: sha256:76d24f3ba3317fa945743bb3746fbaf3a0b752f10b10376960de01da70685fbd
Status: Downloaded newer image for centos:8
docker.io/library/centos:8

注:输出中的 3c72a8ed6814 是镜像层的唯一 ID。Docker 采用分层存储(通常是 overlay2 驱动),相同层在不同镜像间可以共享,极大节省磁盘空间。

4.2 查看与打标签:ls & tag

bash 复制代码
# 查看本地镜像列表
[root@docker ~]# docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
httpd         latest    958373fdd7e8   4 months ago   148MB
hello-world   latest    74cc54e27dc4   4 months ago   10.1kB
centos        8         5d0da3dc9764   3 years ago    231MB

# 自定义输出格式
[root@docker ~]# docker image ls --format "{{.Repository}}:{{.Tag}}"
httpd:latest
hello-world:latest
centos:8

# 给镜像打标签(类似软链接)
[root@docker ~]# docker image tag centos:8 myos:v1
[root@docker ~]# docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
centos        8         5d0da3dc9764   3 years ago    231MB
myos          v1        5d0da3dc9764   3 years ago    231MB

最佳实践:在 CI/CD 流程中,经常将最新构建的镜像打上 v1.0.0、v1.0、v1 和 latest 等多个标签,方便版本回退和精确控制。

4.3 深入剖析:inspect & history

bash 复制代码
# 查看镜像的详细元数据(JSON格式)
[root@docker ~]# docker image inspect myos -f '{{.Architecture}}'
amd64
[root@docker ~]# docker image inspect myos -f '{{.Os}}'
linux

# 查看镜像的构建历史(分层记录)
[root@docker ~]# docker image history myos
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
5d0da3dc9764   3 years ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      3 years ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc...   0B        
<missing>      3 years ago   /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0...   231MB 

4.4 清理与删除:rm & prune

bash 复制代码
# 删除镜像(通过标签)
[root@docker ~]# docker image rm myos:v1
Untagged: myos:v1

# 删除镜像(如果被容器引用,需加 -f 强制删除)
[root@docker ~]# docker image rm 958373fdd7e8
Error response from daemon: conflict: unable to delete 958373fdd7e8 (must be forced) - image is being used by stopped container ...
[root@docker ~]# docker image rm -f 958373fdd7e8
Untagged: httpd:latest
Deleted: sha256:958373fdd7e8...

# 清理所有未被使用的镜像(非常危险,慎用 -a)
[root@docker ~]# docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: nginx:latest
...
Total reclaimed space: 117.7MB

4.5 离线分发:save & load

在无外网的生产环境,将镜像打包成 tar 文件再传输是常规操作。注意与 export/import 的区别:save 保存的是完整的镜像层(保留历史记录),export 只导出容器当前的文件系统快照(丢失历史元数据)。

bash 复制代码
# 保存镜像为 tar 包
[root@docker ~]# docker image save httpd hello-world -o images.tar
[root@docker ~]# ls -lh images.tar
-rw------- 1 root root 148M Nov  5 12:00 images.tar

# 强制删除本地镜像
[root@docker ~]# docker image rm httpd hello-world -f

# 从 tar 包导入镜像
[root@docker ~]# docker image load -i images.tar 
Loaded image: httpd:latest
Loaded image: hello-world:latest

4.6 仓库推送:login & push

如果要将本地自定义的镜像分享给团队,需要推送到 Registry(如 Docker Hub 或私有 Harbor)。

bash 复制代码
# 登录 Docker Hub
[root@docker ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub.
Username: mage16196
Password: 
Login Succeeded

# 推送前必须打上符合规范的 tag: username/image:tag
[root@docker ~]# docker image tag hello-world:latest mage16196/myhello
[root@docker ~]# docker image push mage16196/myhello
The push refers to repository [docker.io/mage16196/myhello]
9c27e219663c: Layer already exists 
latest: digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042 size: 525

五、 总结与心得体会

通过今天对容器技术的系统性梳理与实操,我对云原生的底层基石有了全新的认知。

以前只是觉得 Docker 很神奇,敲个命令就能跑起一个 MySQL 或 Nginx。但深入了解后才发现,Docker 真正伟大的地方在于它的"产品化能力"。它并非容器技术的发明者,而是将 Linux 内核里生涩的 Namespace、Cgroups 组合起来,创造性地加上了镜像分层、Dockerfile,并推出了 Registry 仓库,硬生生把运维领域的隔离技术,变成了软件工程领域的"标准打包容器"。

在实操环节,我深刻体会到了国内网络环境对国外基础组件的限制。配置 daemon.json 镜像加速、替换系统 YUM 源,这些在官方文档里找不到的"中国特色"踩坑经验,才是真实生产环境里的硬核技能。同时,C/S 架构的分离部署也让我意识到,Docker 的 daemon 实际上就是运行在宿主机上的一个高度特权进程,在生产环境中如果不加防护地暴露 2375 端口,无异于直接把服务器的 root 权限拱手让人。

掌握了镜像管理的核心指令(pull、save、load、push 等)后,我们已经具备了在离线环境、混合云环境之间高效搬运基础设施的能力。下一步,我将进入 Dockerfile 的编写与多阶段构建优化,探讨如何制作出体积更小、更安全的业务镜像,并继续向容器编排神器 Kubernetes 进发。云原生之路,基础打得越牢,后面走得越稳。

相关推荐
Rabitebla8 小时前
【Linux 底层原理】进程(十):进程等待详解---从僵尸进程到 wait、waitpid 与 status
linux·c++·笔记·学习·visual studio
Decay__8 小时前
18_MySQL 智能巡检方案 —— 巡检项清单 / 一键巡检脚本 / 健康评分
运维·数据库·sql·mysql·架构
小lu飞9 小时前
2026小红书小工具怎么制作:纯前端 ZIP 打包、沙箱限制与笔记挂载流程
前端·笔记·ai·ai编程
天远API13 小时前
零信任架构实战:基于天远运营商三要素详版V即时版构建自动化消费电子大促电商平台高价值权益秒杀与优惠券防羊毛高并发实名核验网关
运维·人工智能·架构·自动化
无心水13 小时前
24、系统架构师论文写作专题 核心考点与学习笔记
笔记·学习·系统架构·架构师·安全架构·软考架构师·软考系统架构设计师
蒸蒸yyyyzwd13 小时前
邓明 Agent 系统面试-意图识别学习笔记
笔记·学习
Android系统攻城狮13 小时前
Linux FFmpeg深度解析之avcodec_default_get_encode_buffer调用流程与实战(二十八)
linux·运维·服务器·ffmpeg·车载音视频·ffmpeg音视频
乐维_lwops14 小时前
案例解读:大型综合性科创产业园运维监控落地实践
运维·网络·人工智能·安全·it监控·国产运维智能体
阿里云云原生15 小时前
HiRoute 新版本发布:结合自己的真实工作选择最佳模型
云原生