目录
[Jail 时代](#Jail 时代)
[虚拟机 vs Docker](#虚拟机 vs Docker)
[2. 容器化技术](#2. 容器化技术)
[2.1 Namespace](#2.1 Namespace)
[1. dd 命令](#1. dd 命令)
[2. mkfs 命令](#2. mkfs 命令)
[3. df 命令](#3. df 命令)
[4. mount 命令](#4. mount 命令)
[5. unshare 命令](#5. unshare 命令)
[2.2 CGroup](#2.2 CGroup)
[2.1 pidstat](#2.1 pidstat)
[2.2 stress](#2.2 stress)
[3. CGroup 控制](#3. CGroup 控制)
[3.1 查看 CGroup 支持的资源控制](#3.1 查看 CGroup 支持的资源控制)
[3.2 内存控制](#3.2 内存控制)
[3.3 CPU 控制](#3.3 CPU 控制)
[4. 总结](#4. 总结)
1.发展历史
容器技术是现今计算技术的重要组成部分,其发展历程可以追溯到很早的计算机系统提供的进程隔离工具。以下是容器技术的发展历程,其中涵盖了从早期的进程隔离技术到现代云计算和云原生的演变:
Jail 时代
- 1979 年 - chroot 的发明: 在贝尔实验室开发的第 7 版 Unix 中引入了 chroot 系统调用。它通过将进程的根目录更改为文件系统中的新位置,实现文件系统的隔离,这一技术被称为 Chroot Jail。可以说,这奠定了容器技术的基础。
- 2000 年 - FreeBSD Jail: 为了实现安全性和易于管理,FreeBSD Jail 在原有的 chroot 功能上增加了独立的进程和网络空间,从而为托管环境中的客户服务提供了更好的资源隔离。
- 2001 年 - Linux VServer : 类似于 FreeBSD Jail,Linux VServer 将文件系统、网络地址、内存等资源进行分区,实现了更为复杂的资源隔离。
- 2004 年 - Solaris Containers: 这一技术结合了系统资源控制和区域隔离,并增加了快照和克隆功能,为后来的云计算技术发展铺平了道路。
云时代
- 2006 年 - 云计算概念的提出: Google 提出了当数据量达到现在的1000倍甚至10000倍时,该如何处理的问题。云计算的概念引领了新的资源管理和分配需求。
- 2006 年 - Process Containers 和 cgroups: 由 Google 推出,用于限制、统计和隔离一组进程的资源使用。一年后,它被更名为"Control Groups (cgroups)",并最终并入 Linux 内核。
- 2008 年 - LXC 和 GAE 的推出 : LXC 是第一个完整的 Linux 容器管理器实现。同时,Google 推出了 Google App Engine,将开发平台作为一种服务提供。
云原生时代
- 2011 年 - Warden 和 Kubernetes 的出现: CloudFoundry 推出 Warden,解决多主机环境下的容器管理问题。
- 2013 年 - Docker 的问世与风靡 : Docker 作为一个工具和生态系统,将应用程序及其依赖打包到可以跨平台运行的容器中。Docker 迅速成为业界标准,带动了容器生态的繁荣。
- 2014 年 - Kubernetes 的崛起 : Google 发布了 Kubernetes,支持对容器的编排和管理。随着各大公司加入,Kubernetes 成为了云原生架构的重要部分。
- 2015-2016 年 - OCI 和 CNCF 的成立 : 为了解决行业标准问题,Docker 和其他公司成立 OCI,以制定容器和镜像的标准。与此同时,CNCF 的成立,推动了云原生计算的发展。
技术标准的确立
- 2016 年 - CRI 标准的发布 : 为了将 Kubernetes 和特定的容器运行时解耦,Google 和红帽主导发布 CRI 接口标准。
- 2017 年 - containerd 的发展 : 随着 containerd 成为标准的 CRI,实现了容器运行时的标准化,各大厂商纷纷采用 containerd 和 Kubernetes 作为云原生解决方案的基础。
容器技术自其诞生以来,通过文件系统和进程隔离逐步发展到今天的云原生生态系统。在这一过程中,技术创新带来了资源的高效利用和管理的便捷性。尤其是随着 Kubernetes 的普及和标准化,容器已成为现代应用开发和部署的核心技术之一,并对云计算产业的发展产生了深远影响。
虚拟机 vs Docker
虚拟机
虚拟机技术在硬件层之上,在操作系统层就开始进行隔离。虚拟机通过伪造一个硬件的抽象接口,把操作系统嫁接到硬件上。
容器
容器也是一种虚拟化的实现技术,它在操作系统之上进行环境隔离,每个容器可以有自己的一套工具和库,但是它们共享操作系统的内核!
docker 不需要虚拟内核,所以启动可以更快,相当于 windows 的开机时间省去了。
2. 容器化技术
容器化技术,目前最流行的实现方案就是Docker。容器化技术的核心在于实现各种资源的隔离
对于Linux而言,主要依赖于namespace和CGroup技术。
2.1 Namespace
- 作用 :实现进程、文件系统、用户等资源的隔离。
- 具体实现:通过将一个或多个进程指定在同一个namespace中,使得这些进程只能看到与自己相关的资源。
命令详解
1. dd
命令
dd
命令用于读取、转换并输出数据,可以从标准输入或文件中读取数据,根据指定的格式转换数据,再输出到文件、设备或标准输出。
语法
dd OPTION
参数
|----------------|-------------------------------------|
| 参数 | 描述 |
| if=文件名
| 输入文件名,默认为标准输入。即指定源文件。 |
| of=文件名
| 输出文件名,默认为标准输出。即指定目的文件。 |
| bs=bytes
| 同时设置读入/输出的块大小为 bytes
个字节。 |
| count=blocks
| 仅拷贝 blocks
个块,块大小等于 ibs
指定的字节数。 |
2. mkfs
命令
mkfs
命令用于在设备上创建 Linux 文件系统,俗称格式化。
语法
mkfs [-V] [-t fstype] [fs-options] filesys [blocks]
参数
|--------------|--------------------------|
| 参数 | 描述 |
| -t fstype
| 指定要建立何种文件系统;如 ext3,ext4。 |
| filesys
| 指定要创建的文件系统对应的设备文件名。 |
| blocks
| 指定文件系统的磁盘块数。 |
| -V
| 详细显示模式。 |
| fs-options
| 传递给具体文件系统的参数。 |
示例
3. df
命令
df
命令用于显示目前在 Linux 系统上的文件系统磁盘使用情况统计。
语法
df [OPTION]... [FILE]...
常见参数
|------------------------|--------------------------------|
| 参数 | 描述 |
| -a, --all
| 包含所有的具有 0 Blocks 的文件系统。 |
| -h, --human-readable
| 使用人类可读的格式。 |
| -H, --si
| 很像 -h
,但是用 1000 为单位而不是用 1024。 |
| -t, --type=TYPE
| 限制列出文件系统的类型。 |
| -T, --print-type
| 显示文件系统的形式。 |
4. mount
命令
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
| 挂载点的目录。 |
5. unshare
命令
unshare
命令主要用于使用与父程序不共享的名称空间运行程序。
语法
unshare [options] program [arguments]
常用参数
|-----------------|--------------------------------------------------------|
| 参数 | 描述 |
| -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
优先挂载过去。 |
ushare
这个命令,本身也是一个进程,是在宿主机环境运行的
⭕使用
为了不影响后续实验,要记得 exit 哦~
实战
进程隔离
unshare
命令专门提供了一个参数--mount-proc
,在新的namespace
挂载一个独立的/proc
目录,方便进行进程的监控。
可以看到,创建了新的namespace
后,ps -aux
只能查到两个进程,一个是bash
,一个是grep
。这就将namespace
内部的进程与宿主机的进程隔离开了。
文件隔离
挂载文件系统
懒卸载挂载点
总结
- 这些命令在 Linux 系统管理和维护中非常常用,可以帮助管理和操作文件系统、磁盘和进程。
dd
和unshare
命令,在数据备份和容器化技术中有着重要的应用。
2.2 CGroup
- 作用 :实现CPU、内存、网络等资源的隔离。
- 具体实现:通过创建cgroup控制组,限制进程对资源的使用。
相关命令
2.1 pidstat
pidstat
用于检测一个进程的 CPU、内存、IO、线程等资源的占用情况。
-
安装:
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
每隔一秒检测一次,共检测三次。
简单测试:
2.2 stress
stress
是一个压力测试工具,可以对 CPU、内存、IO 等进行压力测试。
-
安装:
apt install stress
-
语法:
stress [option]
参数:
-c --cpu N
:产生 N 个进程,每个进程都循环调用sqrt
函数产生 CPU 压力。-m --vm N
:产生 N 个进程,每个进程都循环调用malloc
和free
函数,产生内存压力。
示例:
- CPU 压力 :
stress -c 1
创建一个进程进行 CPU 压力测试。
- 左侧使用
stress
创建了一个进程进行CPU压力输出 - 右侧检测
stress
产生的压力 - 结果一个进程占满了
100%
的CPU资源
3. CGroup 控制
3.1 查看 CGroup 支持的资源控制
-
查看支持的资源控制:
cat /proc/cgroups
-
查看 CGroup 挂载信息:
mount | grep cgroup
这里就是每一个资源的控制目录,比如在/sys/fs/cgroup/cpu
目录下,就是控制CPU资源的配置文件。
3.2 内存控制
-
创建内存控制组:
cd /sys/fs/cgroup/memory
mkdir test_memory -
设置最大内存:
echo "20971520" > test_memory/memory.limit_in_bytes
-
将进程加入控制组:
stress -m 1 --vm-bytes 50m
pidstat -r
echo "15070" > test_memory/tasks
3.3 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
ps:配好了环境的这台服务器,没有权限测试 ,哎之后有机会,回来填坑
后面应该是实现 echo 后,stress
的CPU占用率立马下降了的结果,来实现了cgroup
成功对进程的CPU进行了限制
4. 总结
结合 pidstat
和 stress
工具,可以方便地进行资源监控和压力测试,进一步验证 CGroup 的效果。
总结
容器化技术在Linux中基于namespace和cgroup实现
- namespace完成不同容器之间的环境隔离
- cgroup完成多个容器对资源的占用限制,合理分配资源。
这是Docker等容器化技术的基本原理和底层依赖。