Bootstrap

docker:容器化虚拟化的原理

目录

1.什么是docker

2.什么是虚拟化和容器化

 3.为什么要容器化

4.容器虚拟化的实现

4.1容器虚拟化的原理

4.2容器虚拟化基础之NameSpace

4.2.1dd命令

常用选项

创建一个大小为100M的空文件

 

4.2.2df命令

常用选项

4.2.3mkfs命令

常用选项

将新创建的testdd格式化为ext4的文件系统。

4.2.4mount命令

常用选项

将新testdd挂载到~/mount目录

4.2.5unshare命令

常用选项

主机名隔离

4.2.6pid隔离

4.2.7mount隔离

4.3容器虚拟化基础值cgroups

4.3.1pidstat命令

常用选项

4.3.2stress命令

常用选项

使用stress持续给cpu压力,使用pidstat监控

4.3.3cgroups

4.3.3.1版本信息查看

4.3.3.2cgroups子系统查看

4.3.3.3cgroups挂载信息的查看

4.3.3.4 查看当前进程的groups信息

4.3.3.5cgroups限制内存

4.3.3.6 cgroups限制cpu


1.什么是docker

docker可以分为镜像,容器和仓库。

镜像(Image):Docker 镜像是一个只读的模板,它包含了运行一个特定应用程序或服务所需的所有文件系统内容,包括操作系统、应用程序代码、依赖库和配置文件等。镜像是创建容器的基础。

容器(Container):容器是基于镜像创建的可运行实例,它是一个独立的、轻量级的运行环境,容器之间相互隔离,互不影响。每个容器都可以看作是一个独立的微型服务器,能够在不同的主机上运行。

仓库(Repository):Docker 仓库是存储和管理镜像的地方,可以将其类比为代码的版本控制系统中的代码仓库。开发者可以将自己创建的镜像推送到仓库中,也可以从仓库中拉取其他人共享的镜像。

2.什么是虚拟化和容器化

虚拟化:将一台计算机虚拟化为多台逻辑计算机,每台逻辑计算机上有自己操作系统,自己的内存,cpu资源等等,虚拟化技术虚拟的是硬件,让操作系统以为自己在一个完全独立的硬件上运行的。

容器化:容器化技术也是虚拟化技术的一种,容器化技术虚拟的是操作系统,通过将操作系统的基本目录结构和文件,应用程序,依赖库整合在一起,形成一个包含系统镜像文件,再通过命名空间技术将系统镜像隔离起来, 让应用程序以为自己在一个完全独立的操作系统中运行。

用这张图更好的理解虚拟化和容器技术 

 

虚拟机:就是通过模拟硬件接口来欺骗操作系统。

容器:通过模拟系统的api接口来欺骗上层应用。

 3.为什么要容器化

1.资源利用率高:将利用率较低的服务器资源进行整合,用更少硬件资源运行更多业务,降低IT支出和 运维管理成本。

2.环境标准化:容器中含有除了操作系统内核以外的所有运行环境,确保了环境的一致性,不会出现这段代码在我的主机上没问题啊?

3.沙箱安全:无论在容器里怎么折腾,影响的始终是这个容器,不会波及整个系统或者其他容器。

4.维护扩展更容易:因为有仓库和镜像的存在,docker应用重复的部分很容易。

5.资源的弹性伸缩:因为容器可以使用容器编排技术进行快速部署,所以才能有弹性伸缩的能力。

6.容器对比虚拟机更轻量,启动更快:虚拟机有自己的内核,docker直接运行在宿主的内核。

4.容器虚拟化的实现

4.1容器虚拟化的原理

通过namespace技术完成系统资源的隔离如进程隔离,文件系统隔离,网络隔离,用户隔离等等通过cgroups技术完成对系统资源的限制。

4.2容器虚拟化基础之NameSpace

NameSpace就是用来隔离系统资源的,相当于一班有个叫张三的同学,二班也有个叫张三的,但是这两个并不是一个人,班级就相当于命名空间。

4.2.1dd命令

dd是 Unix 和 Linux 系统中的一个命令,主要用于复制和转换文件。它可以在不同的存储设备或文件系统之间进行数据的精确复制,也可以对数据进行格式转换等操作。

dd [选项]... [输入文件] [输出文件]
常用选项

if=输入文件:指定输入文件,若未指定则默认从标准输入读取。

of=输出文件:指定输出文件,若未指定则默认输出到标准输出。

bs=块大小:设置输入和输出的块大小,单位可以是字节(默认)、K(千字节)、M(兆字节)等。例如,bs=1M表示每个块的大小为 1 兆字节。

count=块数:指定要复制的块数。

skip=块数:在输入文件中跳过指定数量的块后再开始复制。

seek=块数:在输出文件中从指定的块数位置开始写入。

创建一个大小为100M的空文件
dd if=/dev/zero of=testdd bs=1M count=100;

4.2.2df命令

查看文件系统的使用情况

dd [选项]
常用选项

-h:以人类可读的格式显示磁盘使用情况,例如将字节转换为 GB、MB 等更易读的单位。

-a:显示所有文件系统,包括系统特殊文件系统(如 /proc、/sys 等)。

-T:显示文件系统的类型。

-i:显示 inode 信息,而不是磁盘块使用情况。inode 是文件系统中用于存储文件元数据的结构。

4.2.3mkfs命令

make filesystem用于在指定文件的分区创建新的文件系统。

mkfs [选项] [-t 文件系统类型] [设备名称] [块数量]
常用选项

-t:指定文件系统类型。

将新创建的testdd格式化为ext4的文件系统。

但是这个时候使用df是查看不到该文件系统的,因为该文件系统并没有被挂在到操作系统的目录树上。

4.2.4mount命令

将文件系统挂载到操作系统的目录树上。

mount [-t 文件系统类型] [-o 挂载选项] 设备名 挂载点
常用选项

-t 文件系统类型:用于指定要挂载的文件系统类型,像ext4ntfsxfs等。若不指定,系统会自动检测。

-o 挂载选项:可设置特殊挂载选项,例如只读挂载、指定用户等。

将新testdd挂载到~/mount目录
sudo mount -t ext4 ./testdd ~/mount

4.2.5unshare命令

unshare命令是一个在linux中用于创建命名空间的命令。

unshare [选项] 程序 [参数]
常用选项

-m, --mount:创建新的挂载命名空间,使得在新命名空间中进行的挂载和卸载操作不会影响到其他命名空间。

-u, --uts:创建新的 UTS命名空间,允许新命名空间中的进程拥有独立的主机名和 NIS 域名。

-i, --ipc:创建新的 IPC命名空间,隔离进程间的通信资源,如消息队列、共享内存等。

-n, --net:创建新的网络命名空间,为进程提供独立的网络栈,包括网络接口、路由表等。

-p, --pid:创建新的 PID命名空间,使得新命名空间中的进程有独立的 PID 编号。

-U, --user:创建新的用户命名空间,允许在新命名空间中映射不同的用户和组 ID。

--fork:创建一个子进程。

--mount-proc:创建一个新的挂载点将proc目录挂载上去。

主机名隔离

在另一个会话查看

4.2.6pid隔离

 /proc目录下存储的全局命名空间所有进程的信息,他会动态更新,如果不挂载到当前命名空间,还会能看见所有进程。

4.2.7mount隔离

1.在mount隔离的命名空间启动个bash 使用dd命令复制一个10M的镜像文件

2.将镜像文件格式化

3.将镜像文件挂载到./test目录并在当前窗口查看

另一个窗口查看

4.3容器虚拟化基础值cgroups

cgroups全程ctrlgropus,简单来说cgroups的作用就是限制进程使用的内核资源。

4.3.1pidstat命令

pidstat监控linux系统资源的命令,这个命令不是系统自带的命令,需要下载。

pidstat [options] [interval [count]]

interval:间隔多少时间查询一次。

count:一共查多少次。

常用选项

-u:默认选项,显示 CPU 使用情况的统计信息,包括用户时间、系统时间、CPU 利用率等。

-r:显示内存使用情况的统计信息,如页面错误、内存使用率等。

-d:显示磁盘 I/O 使用情况的统计信息,包括读写字节数、I/O 请求数等。

-p:指定要监控的进程 ID。可以指定多个进程 ID,用逗号分隔。如果不指定-p选项,则默认监控所有进程。

-C:可以根据指定的命令名称或进程名称来筛选并显示相关进程的性能数据

-l:显示命令名和参数,而不仅仅是进程 ID。

4.3.2stress命令

stress是一个用于对 Linux 系统进行压力测试的工具,它可以模拟系统在高负载情况下的运行状态

stress [OPTION]... [NUM]

num:指定要生成的进程数或者是任务数。

常用选项

-c:指定产生 CPU 压力的进程数。例如-c 4表示创建 4 个进程来占用 CPU 资源,模拟 CPU 高负载情况。

-i:指定产生内存压力的进程数。这些进程会不断地进行内存读写操作,以测试系统的内存处理能力。

-m:指定产生内存分配压力的进程数。进程会尝试分配大量内存,可用于检测系统内存分配和管理的性能。

-d:指定产生磁盘 I/O 压力的进程数。这些进程会进行大量的磁盘读写操作,以测试系统的磁盘 I/O 性能。

-t:指定压力测试的持续时间。例如-t 60s表示测试持续 60 秒,-t 5m表示持续 5 分钟。

使用stress持续给cpu压力,使用pidstat监控
pidstat -C stress -p ALL -u 2 10000
stress -c 1

 

4.3.3cgroups

4.3.3.1版本信息查看
cat /proc/filesystems | grep cgroup

说明我这个系统支持 cgroup和cgroup2

4.3.3.2cgroups子系统查看
cat /proc/cgroups

这些是cgroups支持的资源控制

4.3.3.3cgroups挂载信息的查看
mount | grep group

4.3.3.4 查看当前进程的groups信息
cat /proc/$$/groups
&& 代表当前进程pid

cd到这个 /sys/fs/cgroup/user.slice/user-0.slice/session-82425.scope目录下

 

cgroup.procs:只要将pid添加到这个文件,这个进程就会这个cgroup组限制

memory.max:使用内存的最大上限,如果超过这个上限操作系统会尝试回收,回收失败直接杀死进程。

memory.high:使用内存的最大上限,如果超过这个上线,操作系统会使用一些策略限制,但不会直接杀死。

因为这个是在cgroup的根目录下所以没有显示cpu限制文件。

4.3.3.5cgroups限制内存

1.在cgroup目录下创建一个test_memory目录

mkdir test_memory

2.将memory.max设置100m

echo 104857600 > ./memory.max

3.启动pidstat监控stress

pidstat -C stress -p ALL -r 2 1000000

 4.启动stress每次申请120M的内存

stress -m 1 --vm-bytes 120M

5.将pid添加到cgroup.procs中

echo "3569257" > cgroup.procs

添加上去的瞬间stress直接挂了,因为memory.max限制为100M

4.3.3.6 cgroups限制cpu

1.在cgroup目录下创建一个test_cpu目录

2.启动stress将cpu打满

stress -c 1

3.使用pidstat监视stress

pidstat -C stress -p ALL -u

cpu已经被打满 

4.配置cpu.max文件

echo "20000 100000" > cpu.max
cpu使用的最大值是100000,20000代表只能使用20%的cpu

5.将pid添加到cgroup.procs

echo 3691769 > cgroup.procs

 cpu的使用率立马调到20%左右

;