容器技术是现今计算技术的重要组成部分,其发展历程可以追溯到很早的计算机系统提供的进程隔离工具。以下是容器技术的发展历程,其中涵盖了从早期的进程隔离技术到现代云计算和云原生的演变:
k8s 成为云原生技术事实标志

时间 | 事件 |
|---|---|
2001 | Linux Vserver 分区 |
2008 | LVS – 第一个 完整 的 Linux 容器管理器 |
2013 | Docker – 打包容器 |
2014 | Google K8s – 编排容器 – 云原生架构 |
2016 | Docker – OCI 标准 |
2017 | K8s API标准 – CRI |
容器技术自其诞生以来,通过文件系统和进程隔离逐步发展到今天的云原生生态系统。在这一过程中,技术创新带来了资源的高效利用和管理的便捷性。尤其是随着 Kubernetes 的普及和标准化,容器已成为现代应用开发和部署的核心技术之一,并对云计算产业的发展产生了深远影响。
物理机:实际的服务器或者计算机。
虚拟化:是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。
容器化:容器化是一种虚拟化技术,又称操作系统层虚拟化(Operating system levelvirtualization),这种技术将操作系统内核虚拟化,可以允许用户空间软件实例(instances)被分割成几个独立的单元,在内核中运行,而不是只有一个单一实例运行。
类比理解
我们从上面的历史发展来看,虚拟化和容器化的最主要目的就是资源隔离,随着资源隔离的实现逐渐也带来了更大的收益。
rm -f/* 不会把整个服务器搞死,也不影响其他人部署的程序使用。虚拟机:存在于硬件层和操作系统层间的虚拟化技术。
容器:存在于操作系统层和函数库层之间的虚拟化技术。
JVM 之类的虚拟机:存在于函数库层和应用程序之间的虚拟化技术。
补充:应用程序执行环境分层

主机虚拟化的原理是通过在物理服务器上安装一个 虚拟化层 来实现。这个虚拟化层可以在物理服务器和客户操作系统之间建立虚拟机,使得它们可以独立运行。
从软件框架的角度上,根据虚拟化层是直接位于硬件之上还是在一个宿主操作系统之上,将虚拟化划分为
Type1和Type2

Hypervisor:是一种系统软件,它充当计算机硬件和虚拟机之间的中介,负责有效地分配和利用由各个虚拟机使用的硬件资源,这些虚拟机在物理主机上单独工作,因此,Hypervisor 也称为 虚拟机管理器 Hypervisor:运行在一个宿主机操作系统之上(Vmware Workstation) 或者 系统里面,Hypervisor 作为宿主机操作系统中的一个应用程序,客户机就是在宿主机操作系统上的一个进程。容器虚拟化,有别于主机虚拟化,是操作系统层的虚拟化。
基本原理:通过 namespace 进行各程序的隔离,加上 cgroups 进行资源的控制,以此来进行虚拟化。
注意:Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前namespace 里的进程,对其他 namespace 中的进程没有影响。
Namespace | 系统调用参数 | 隔离的全局系统资源 | 内核版本 |
|---|---|---|---|
UTS | CLONE_NEWUTS | 主机名和域名 | 2.6.19 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 – 进程间通信 | 2.6.19 |
PID | CLONE_NEWPID | 进程编号 | 2.6.24 |
Network | CLONE_NEWNET | 网络设备、网络栈、端口等 | 2.6.29 |
Mount | CLONE_NEWNS | 文件系统挂载点 | 2.4.19 |
User | CLONE_NEWUSER | 用户和用户组 | 3.8 |
以上命名空间在容器环境下的隔离效果如下:
UTS:每个容器能看到自己的 hostname,拥有独立的主机名和域名。IPC:同一个 IPC namespace 的进程之间能互相通讯,不同的IPC namespace 之间不能通信。PID:每个 PID namespace 中的进程可以有其独立的 PID,每个容器可以有其 PID 为进程。1 的 rootNetwork:每个容器用有其独立的网络设备,IP地址,IP路由表,/proc/net目录,端口号。Mount:每个容器能看到不同的文件系统层次结构。User:每个 container 可以有不同的 user 和 group id.想想以下如果我们要隔离两个进程需要怎么办?
命令 | 功能 | 用途 |
|---|---|---|
dd | 复制文件并转换数据 | 创建镜像、测试性能、备份磁盘 |
mkfs | 创建文件系统 | 格式化新分区 |
df | 查看磁盘空间 | 查看挂载点使用情况 |
mount | 挂载文件系统 | 挂载 ISO、U盘、设备等 |
unshare | 创建隔离命名空间 | 容器底层调试、实验性隔离环境 |
① dd 命令:用于读取、转换并输出数据,可以从标准输入或文件中读取数据,根据指定的格式转换数据,再输出到文件、设备或标准输出
语法:dd OPTION ,参数如下:
参数 | 描述 |
|---|---|
if=文件名 | 输入文件名,默认为标准输入。即指定源文件。 |
of=文件名 | 输出文件名,默认为标准输出。即指定目的文件。 |
bs=bytes | 同时设置读入/输出的块大小为 bytes 个字节,如果是ibs设置单次读入块大小, obs 设置单次输出块大小, cbs 设置转换块大小 |
skip/seek=blocks | 从 输入/输出 文件开头跳过 blocks 个块后再开始复制 |
count=blocks | 仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数。 |
conv=<关键字>,关键字有如下类型:
conversion:用指定的参数转换文件ascii:转换 ebcdic 为 asciiebcdic:转换 asccii 为 ebcdicibm:转换 ascii 为 alternate ebcdicblock/unblock:把每一行转换为长度为 cbs,不足部分用空格lcase/ucase:交换输入的每对字节noerror:出错时不停止notrunc:不截断输出文件sync:将每个输入块填充到 ibs 个字节,不足部分用空(NULL)字符补齐案例
# 生成镜像文件
dd if=/dev/zero of=test.txt bs=8k count=1014
# 大写转小写
dd if=in.txt of=out.txt conv=ucase
# 测试磁盘写入速度
dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct② mkfs 命令:在设备上创建指定类型的文件系统,即 “格式化”
语法:mkfs [-V] [-t fstype] [fs-options] filesys [blocks] ,参数如下:
参数 | 描述 |
|---|---|
-t fstype | 指定要建立何种文件系统;如 ext3,ext4。 |
filesys | 指定要创建的文件系统对应的设备文件名。 |
blocks | 指定文件系统的磁盘块数。 |
-V | 详细显示模式。 |
fs-options | 传递给具体文件系统的参数。 |
案例
# 格式化分区为 ext4 文件系统
mkfs -t ext4 test.txt
mke2fs 1.46.5 (30-Dec-2021)
Discarding device blocks: done
Creating filesystem with 20480 4k blocks and 20480 inodes
Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done③ df 命令:用于显示目前在 Linux 系统上的文件系统磁盘使用情况统计。
语法:dd OPTION ,参数如下:
参数 | 描述 |
|---|---|
-a, --all | 包含所有的具有 0 Blocks 的文件系统。 |
-h, --human-readable | 使用人类可读的格式。 |
-H, --si | 很像 -h,但是用 1000 为单位而不是用 1024。 |
-t, --type=TYPE | 限制列出文件系统的类型。 |
-T, --print-type | 显示文件系统的形式。 |
案例:
lighthouse@VM-8-10-ubuntu:~$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 340M 1020K 339M 1% /run
/dev/vda2 69G 22G 45G 33% /
tmpfs 1.7G 24K 1.7G 1% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 340M 4.0K 340M 1% /run/user/1002
tmpfs 340M 4.0K 340M 1% /run/user/1001④ mount 命令:用于加载文件系统到指定的加载点
语法:
mount [-l]
mount [-t vfstype] [-o options] device dir常见参数如下:
参数 | 描述 |
|---|---|
-l | 显示已加载的文件系统列表。 |
-t vfstype | 指定加载文件系统类型,支持常见的 ext3, ext4, iso9660, tmpfs, xfs 等。 |
-o options | 主要用来描述设备或档案的挂接方式。 |
loop | 用来把一个文件当成硬盘分区挂接上系统。 |
ro | 采用只读方式挂接设备。 |
rw | 采用读写方式挂接设备。 |
device | 要挂接(mount)的设备。 |
dir | 挂载点的目录。 |
案例
lighthouse@VM-8-10-ubuntu:test$ sudo mkdir /mymount
lighthouse@VM-8-10-ubuntu:test$ sudo mount test.txt /mymount
lighthouse@VM-8-10-ubuntu:test$ ll /mymount/
total 24
drwxr-xr-x 3 root root 4096 Jul 9 20:51 ./
drwxr-xr-x 21 root root 4096 Jul 9 20:51 ../
drwx------ 2 root root 16384 Jul 9 20:47 lost+found/
lighthouse@VM-8-10-ubuntu:test$ df -t ext4
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda2 72127952 22751700 46319384 33% /
/dev/loop4 72652 24 66896 1% /mymount
# 取消挂载
lighthouse@VM-8-10-ubuntu:test$ sudo umount /mymount
lighthouse@VM-8-10-ubuntu:test$ df -t ext4
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda2 72127952 22751804 46319280 33% /⑤ unshare 命令:
语法:dd OPTION ,参数如下:
参数 | 描述 |
|---|---|
-i, --ipc | 不共享 IPC 空间。 |
-m, --mount | 不共享 Mount 空间。 |
-n, --net | 不共享 Net 空间。 |
-p, --pid | 不共享 PID 空间。 |
-u, --uts | 不共享 UTS 空间。 |
-U, --user | 不共享用户。 |
-V, --version | 版本查看。 |
--fork | 执行 unshare 的进程 fork 一个新的子进程,在子进程中执行 unshare 传入的参数。 |
--mount-proc | 执行子进程前,将 proc 优先挂载过去。 |
案例:
lighthouse@VM-8-10-ubuntu:test$ sudo unshare -u /bin/bash
root@VM-8-10-ubuntu:/home/lighthouse/code/test# hostname test1
root@VM-8-10-ubuntu:/home/lighthouse/code/test# hostname
test1
# 查看进程
root@VM-8-10-ubuntu:/home/lighthouse/code/test# ps -ajx | grep bash
1877172 1877180 1877180 1877180 pts/2 1886346 Ss 1001 0:00 -bash
1877180 1886346 1886346 1877180 pts/2 1886346 S+ 0 0:00 sudo unshare -u /bin/bash
1886346 1886347 1886347 1886347 pts/1 1886575 Ss 0 0:00 sudo unshare -u /bin/bash
1886347 1886348 1886348 1886347 pts/1 1886575 S 0 0:00 /bin/bash
1886348 1886576 1886575 1886347 pts/1 1886575 S+ 0 0:00 grep --color=auto bash
# exit 退出进程, 发现之前的没有持久设置
root@VM-8-10-ubuntu:/home/lighthouse/code/test# exit
exit
lighthouse@VM-8-10-ubuntu:test$ hostname
VM-8-10-ubuntu⚠️ 注意:unshare 是一个运行时命令,执行后会启动一个新的 shell 进程,该进程处于独立的命名空间中,但不会持久化 ,退出即失效。
① 进程隔离:unshare命令专门提供了一个参数--mount-proc,在新的namespace挂载一个独立的/proc目录,方便进行进程的监控。
lighthouse@VM-8-10-ubuntu:test$ sudo unshare --fork --pid --mount-proc /bin/bash
root@VM-8-10-ubuntu:/home/lighthouse/code/test# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 7636 4272 pts/1 S 21:00 0:00 /bin/bash
root 7 0.0 0.1 10336 3752 pts/1 R+ 21:00 0:00 ps -auxnamespace后,ps -aux只能查到两个进程,一个是bash,一个是grep。这就将namespace内部的进程与宿主机的进程隔离开了。② 文件隔离

cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。用途如下:
Resource limitation:限制资源使用,例:内存使用上限/cpu 的使用限制Prioritization:优先级控制,例:CPU 利用/磁盘 IO 吞吐Accounting:一些审计或一些统计Control:挂起进程/恢复执行进程① pidstat:用于检测一个进程的 CPU、内存、IO、线程等资源的占用情况。
sudo apt install sysstat # 安装
pidstat [option] [时间间隔] [次数] # 语法选项:
-u:检测 CPU 使用情况(默认)-r:检测内存使用情况-d:检测 IO 使用情况-p:指定进程 PID,如果指定 ALL 则监视所有进程-C:检测通过指定命令启动的进程示例:
pidstat 会输出所有进程的 CPU 占用情况。pidstat -p 1234 检测 PID 为 1234 的进程。pidstat -C bash 检测通过 bash 命令启动的进程。pidstat -r 检测内存占用情况。pidstat 1 3 每隔一秒检测一次,共检测三次。简单测试:
lighthouse@VM-8-10-ubuntu:test$ pidstat -C bash
Linux 5.15.0-126-generic (VM-8-10-ubuntu) 07/09/2025 _x86_64_ (2 CPU)
09:19:13 PM UID PID %usr %system %guest %wait %CPU CPU Command
09:19:13 PM 1001 1877180 0.00 0.00 0.00 0.00 0.00 0 bash
lighthouse@VM-8-10-ubuntu:test$ pidstat -r
Linux 5.15.0-126-generic (VM-8-10-ubuntu) 07/09/2025 _x86_64_ (2 CPU)
09:19:20 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
09:19:20 PM 0 1 0.09 0.00 184012 10948 0.31 systemd
09:19:20 PM 0 366 0.00 0.83 179024 81516 2.34 systemd-journal
09:19:20 PM 0 410 0.00 0.00 289312 27096 0.78 multipathd
09:19:20 PM 0 412 0.00 0.00 12120 5012 0.14 systemd-udevd
09:19:20 PM 101 828 0.00 0.00 16128 1608 0.05 systemd-network
09:19:20 PM 0 843 0.00 0.00 2816 1104 0.03 acpid
09:19:20 PM 103 848 0.00 0.00 8876 4008 0.12 dbus-daemon
09:19:20 PM 0 864 0.00 0.00 234504 4472 0.13 polkitd② stress:一个压力测试工具,可以对 CPU、内存、IO 等进行压力测试。
sudo apt install stress # 安装
stress [option] # 语法 参数:
-c --cpu N:产生 N 个进程,每个进程都循环调用 sqrt 函数产生 CPU 压力。-m --vm N:产生 N 个进程,每个进程都循环调用 malloc 和 free 函数,产生内存压力。示例:stress -c 1 创建一个进程进行 CPU 压力测试。

stress创建了一个进程进行CPU压力输出stress产生的压力100%的CPU资源① 信息查看
cgroups 版本查看
lighthouse@VM-8-10-ubuntu:~$ cat /etc/*release* # 查看当前系统版本
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04 LTS"
PRETTY_NAME="Ubuntu 22.04 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04 (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
lighthouse@VM-8-10-ubuntu:~$ cat /proc/filesystems |grep cg
nodev cgroup
nodev cgroup2 # 可以支持两个版本 cgroupcgroups 子系统查看
lighthouse@VM-8-10-ubuntu:test$ cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 0 109 1
cpu 0 109 1
cpuacct 0 109 1
blkio 0 109 1
memory 0 109 1
devices 0 109 1
freezer 0 109 1
net_cls 0 109 1
perf_event 0 109 1
net_prio 0 109 1
hugetlb 0 109 1
pids 0 109 1
rdma 0 109 1
misc 0 109 1查看挂载信息:这里是每一个资源的控制目录,比如在 /sys/fs/cgroup/cpu 目录下,就是控制CPU资源的配置文件
lighthouse@VM-8-10-ubuntu:~$ mount | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)查看一个进程上的 cgroup 限制
lighthouse@VM-8-10-ubuntu:~$ cat /proc/$$/cgroup
0::/user.slice/user-1001.slice/session-83590.scope # 层级编号:挂载的子系统:路径② 内存控制
创建内存控制组
cd /sys/fs/cgroup/memory
mkdir test_memory设置最大内存
echo "20971520" > test_memory/memory.limit_in_bytes将进程加入控制组
stress -m 1 --vm-bytes 50m # 每个进程占用 50M
pidstat -r
echo "15070" > test_memory/tasks③ CPU 控制
创建 CPU 控制组
cd /sys/fs/cgroup/cpu
mkdir test_cpu设置 CPU 占用率
echo "5000" > test_cpu/cpu.cfs_period_us
echo "2000" > test_cpu/cpu.cfs_quota_us将进程加入控制组
stress -c 1
pidstat -u
echo "60769" > test_cpu/tasks