Docker学习——①

文章目录

  • 1、什么是虚拟化、容器化?
  • 2、为什么要虚拟化、容器化?
  • 3、虚拟化实现方式
    • 3.1 应用程序执行环境分层
    • 3.2 虚拟化常见类别
    • 3.3 常见虚拟化实现
      • 3.3.1 主机虚拟化(虚拟机)实现
      • 3.3.2 容器虚拟化实现
      • 3.3.3 空间隔离实战--基础知识
      • 3.3.4 PID 隔离
      • 3.3.5 Mount 隔离
      • 3.3.6 容器虚拟化基础之 cgroups
      • 3.3.7 CGroups 资源控制实战
      • 3.3.8 容器虚拟化基础之 LXC
      • 3.3.9 LXC 容器操作实战

1、什么是虚拟化、容器化?

  • 物理机:实际的服务器或者计算机。相对于虚拟机而言的对实体计算机的称呼。物理机提供给虚拟机以硬件环境,有时也称为“寄主”或“宿主”。
  • 虚拟化:是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率。
  • 容器化:容器化是一种虚拟化技术,又称操作系统层虚拟化(Operating system level virtualization),这种技术将操作系统内核虚拟化,可以允许用户空间软件实例(instances)被分割成几个独立的单元,在内核中运行,而不是只有一个单一实例运行。这个软件实例,也被称为是一个容器(containers)。对每个实例的拥有者与用户来说,他们使用的服务器程序,看起来就像是自己专用的。容器技术是虚拟化的一种。docker 是现今容器技术的事实标准。

举个生活中的例子。

物理机如下,就像一个庄园,独立占用了一块土地,花园都是自己的,其他人无法共
享使用。
在这里插入图片描述

虚拟机相当于开发商的一个楼盘,一栋楼一套房子一户人家,共享一块宅基地,共享
小区的花园,共享小区的游乐设施。
在这里插入图片描述

容器相当于在 1 个房子里面,开辟出来一个又一个的胶囊公寓,共享这套房子的卫生
间、共享厨房、共享 WiFi,只有衣服、电脑等私人物品是你自己的。
在这里插入图片描述

2、为什么要虚拟化、容器化?

我们从上面的历史发展来看,虚拟化和容器化的最主要目的就是资源隔离,随着资源
隔离的实现逐渐也带来了更大的收益

  • 资源利用率高
    将利用率较低的服务器资源进行整合,用更少硬件资源运行更多业务,降低 IT 支出和运维管理成本。
    比如上图中我们的土地直接复用,使用这块土地的人多了,但是成本还是庄园那块地。

  • 环境标准化
    一次构建,随处执行。实现执行环境的标准化发布,部署和运维。开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
    在这里插入图片描述

  • 资源弹性伸缩
    根据业务情况,动态调整计算、存储、网络等硬件及软件资源。比如遇到双 11 了,把服务扩容 100 个,双 11 过去了, 把扩容的 100 个收回去

  • 差异化环境提供
    同时提供多套差异化的执行环境,限制环境使用资源。
    比如我的服务一个以来 Ubuntu 操作系统,一个服务依赖 CentOS 操作系统,但是没有预算购买两个物理机,这个时候容器化就能很好的提供多种不同的环境。
    在这里插入图片描述

  • 沙箱安全
    为避免不安全或不稳定软件对系统安全性、稳定性造成影响,可使用虚拟化技术构建虚拟执行环境。
    比如我在容器里面执行 rm -rf /* 不会把整个服务器搞死,也不影响其他人部署的程序使用。

  • 容器对比虚拟机更轻量,启动更快
    传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
    docker 不需要虚拟内核,所以启动可以更快,相当于 windows 的开机时间省去了。

  • 维护和扩展容易
    Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。比如 docker hub 提供了很多镜像,各个系统的一个命令就可以拿到了,研发也可以自己定制镜像分享给各个产品。

3、虚拟化实现方式

3.1 应用程序执行环境分层

在这里插入图片描述
硬件层:提供硬件抽象,包括指令集架构、硬件设备及硬件访问接口
操作系统层 :提供系统调用接口,管理硬件资源
程序库层:提供数据结构定义及函数调用接口

3.2 虚拟化常见类别

虚拟机
存在于硬件层和操作系统层间的虚拟化技术。虚拟机通过“伪造”一个硬件抽象接口,将一个操作系统以及操作系统层以上的层嫁接到硬件上,实现和真实物理机几乎一样的功能。比如我们在一台 Windows 系统的电脑上使用 Android 虚拟机,就能够用这台电脑打开 Android 系统上的应用。

容器
存在于操作系统层和函数库层之间的虚拟化技术。容器通过“伪造”操作系统的接口,将函数库层以上的功能置于操作系统上。以 Docker 为例,其就是一个基于 Linux 操作系统的 Namespace 和 Cgroup 功能实现的隔离容器,可以模拟操作系统的功能。简单来说,如果虚拟机是把整个操作系统封装隔离,从而实现跨平台应用的话,那么容器则是把一个个应用单独封装隔离,从而实现跨平台应用。所以容器体积比虚拟机小很比特就业课多,理论上占用资源更少。容器化就是应用程序级别的虚拟化技术。容器提供了将应用程序的代码、运行时、系统工具、系统库和配置打包到一个实例中的标准方法。容器共享一个内核(操作系统),它安装在硬件上。

JVM 之类的虚拟机
存在于函数库层和应用程序之间的虚拟化技术。Java 虚拟机同样具有跨平台特性,所谓跨平台特性实际上也就是虚拟化的功劳。我们知道 Java 语言是调用操作系统函数库的,JVM 就是在应用层与函数库层之间建立一个抽象层,对下通过不同的版本适应不同的操作系统函数库,对上提供统一的运行环境交给程序和开发者,使开发者能够调用不同操作系统的函数库。

3.3 常见虚拟化实现

3.3.1 主机虚拟化(虚拟机)实现

主机虚拟化的原理是通过在物理服务器上安装一个虚拟化层来实现。这个虚拟化层可以在物理服务器和客户操作系统之间建立虚拟机,使得它们可以独立运行。从软件框架的角度上,根据虚拟化层是直接位于硬件之上还是在一个宿主操作系统之上,将虚拟化划分为 Type1 和 Type2.
Type1 类的 Hypervisor(Hypervisor 是一种系统软件,它充当计算机硬件和虚拟机之间的中介,负责有效地分配和利用由各个虚拟机使用的硬件资源,这些虚拟机在物理主机上单独工作,因此,Hypervisor 也称为虚拟机管理器。)直接运行在硬件之上,没有宿主机操作系统,Hypervisor 直接控制硬件资源和客户机。典型框架为 Xen、Vmware ESX。

在这里插入图片描述

Type2 类的 Hypervisor 运行在一个宿主机操作系统之上(Vmware Workstation)或者系统里面,Hypervisor 作为宿主机操作系统中的一个应用程序,客户机就是在宿主机操作系统上的一个进程。

3.3.2 容器虚拟化实现

容器虚拟化实现原理
容器虚拟化,有别于主机虚拟化,是操作系统层的虚拟化。通过 namespace 进行各程序的隔离,加上 cgroups 进行资源的控制,以此来进行虚拟化。

容器虚拟化基础之 NameSpace

什么是 Namespace(命名空间)?
namespace 是 Linux 内核用来隔离内核资源的方式。通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。

Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前namespace 里的进程,对其他 namespace 中的进程没有影响。Linux 提供了多个 API 用来操作 namespace,它们是 clone()、setns() 和 unshare() 函数,为了确定隔离的到底是哪项 namespace,在使用这些 API 时,通常需要指定一些调用参数:CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWPID、CLONE_NEWUSER、CLONE_NEWUTS 和CLONE_NEWCGROUP。如果要同时隔离多个 namespace,可以使用 | (按位或)组合这些参数。

目前,Linux已经支持8种全局资源的虚拟化。

cgroup namespace:该namespace可单独管理自己的cgroupipc namespace:该namespace有自己的IPC,比如共享内存、信号量等network namespace:该namespace有自己的网络资源,包括网络协议栈、网络设备、路由表、防火墙、端口等mount namespace:该namespace有自己的挂载信息,即拥有独立的目录层次pid namespace:该namespace有自己的进程号,使得namespace中的进程PID单独编号,比如可以PID=1time namespace:该namespace有自己的启动时间点信息和单调时间,比如可设置某个namespace的开机时间点为1年前启动,再比如不同的namespace创建后可能流逝的时间不一样user namespace:该namespace有自己的用户权限管理机制(比如独立的UID/GID),使得namespace更安全uts namespace:该namepsace有自己的主机信息,包括主机名(hostname)、NIS domain name

每个进程都有这样8中namesapce,如果两个进程的对应的namespace值是一样的,那么他们就处于同一个namespace,彼此之间是可见的。反之,他们在不同的容器中,彼此是不可见的。

举个例子
三年一班的小明和三年二班的小明,虽说他们名字是一样的,但是所在班级不一样,那么,在全年级排行榜上面,即使出现两个名字一样的小明,也会通过各自的学号来区分。对于学校来说,每个班级就相当于是一个命名空间,这个空间的名称是班级号。班级号用于描述逻辑上的学生分组信息,至于什么学生分配到 1 班,什么学生分配到2 班,那就由学校层面来统一调度。

namespace系统调用参数被隔离的全局系统资源引入内核版本
UTSCLONE_NEWUTS主机名和域名2.6.19
IPCCLONE_NEWIPC信号量、消息队列和共享内存 - 进程间通信2.6.19
PIDCLONE_NEWPID进程编号2.6.24
NetworkCLONE_NEWNET网络设备、网络栈、端口等2.6.29
MountCLONE_NEWNS文件系统挂载点2.4.19
UserCLONE_NEWUSER用户和用户组3.8

以上命名空间在容器环境下的隔离效果:

UTS:每个容器能看到自己的 hostname,拥有独立的主机名和域名。
IPC:同一个 IPC namespace 的进程之间能互相通讯,不同的 IPC namespace 之间不能通信。
PID:每个 PID namespace 中的进程可以有其独立的 PID,每个容器可以有其 PID 为1 的 root 进程。
Network:每个容器用有其独立的网络设备,IP 地址,IP 路由表,/proc/net 目录,端口号。
Mount:每个容器能看到不同的文件系统层次结构。
User:每个 container 可以有不同的 user 和 group id。

想想以下如果我们要隔离两个进程需要怎么办?
(1)首先容器进程与进程之间需要隔离,所以需要 PID 隔离
(2)首先容器 A 进程不能读取容器 B 进程通讯内容需要隔离信号量等,所以需要 IPC隔离
(3)首先容器 A 进程不能读取容器 B 进程的文件,所以需要 Mount 隔离
(4)首先容器 A 进程不能读取容器 B 进程的 socket,所以需要网络隔离、主机隔离
(5)Docker 允许用户在主机和容器间共享文件夹,同时不需要限制容器的访问权限,这就容易让容器突破资源限制。需要借助用户空间来完成用户之间的隔离。

3.3.3 空间隔离实战–基础知识

学习NameSpace 隔离就是了解隔离能力并不是 docker 提供的,而是操作系统内核提供基本能力

dd 命令详解
Linux dd 命令用于读取、转换并输出数据。
dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。

dd OPTION

参数:

if=文件名:输入文件名,默认为标准输入。即指定源文件。
of=文件名:输出文件名,默认为标准输出。即指定目的文件。
ibs=bytes:一次读入 bytes 个字节,即指定一个块大小为 bytes 个字节。
obs=bytes:一次输出 bytes 个字节,即指定一个块大小为 bytes 个字节。
bs=bytes:同时设置读入/输出的块大小为 bytes 个字节。
cbs=bytes:一次转换 bytes 个字节,即指定转换缓冲区大小。
skip=blocks:从输入文件开头跳过 blocks 个块后再开始复制。
seek=blocks:从输出文件开头跳过 blocks 个块后再开始复制。
count=blocks:仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数。
conv=<关键字>,关键字可以有以下 11 种:

conversion:用指定的参数转换文件。
ascii:转换 ebcdic 为 ascii
ebcdic:转换 ascii 为 ebcdic
ibm:转换 ascii 为 alternate ebcdic
block:把每一行转换为长度为 cbs,不足部分用空格填充
unblock:使每一行的长度都为 cbs,不足部分用空格填充
lcase:把大写字符转换为小写字符
ucase:把小写字符转换为大写字符
swap:交换输入的每对字节
noerror:出错时不停止
notrunc:不截短输出文件
sync:将每个输入块填充到 ibs 个字节,不足部分用空(NUL)字符补齐

案例1:生成 1 个镜像文件

dd if=/dev/zero of=test.img bs=8k count=10240

/dev/zero是Linux下一个特殊的设备文件,它会提供无限制数量的零字节数据作为输入
if=/dev/zero:将从/dev/zero读取零字节数据以填充新创建的文件
of=fdimage.img:指定了新创建的文件的名称,即 fdimage.img
bs=8k:将以8千字节的块大小从输入文件读取数据,并将其写入输出文件
count=10240:指定了要复制或写入的块的数量。在这里,块的数量被设置为10240,因此将创建一个大小为8k * 10240 = 80MB的文件fdimage.img,其中所有数据都将是零字节。

注意:最终文件的大小=ibs*count

案例2:将 testfile 文件中的所有英文字母转换为大写,然后转成为 testfile_1 文件

在这里插入图片描述

dd if=testfile of=testfile_1 conv=ucase

在这里插入图片描述

mkfs 命令详解
用于在设备上创建 Linux 文件系统,俗称格式化,比如我们使用 U 盘的时候可以格式化

mkfs [-V] [-t fstype] [fs-options] filesys [blocks]

参数:

-V : 详细显示模式
-t fstype:指定要建立何种文件系统;如 ext3,ext4
fs-options:传递给具体的文件系统的参数
filesys :指定要创建的文件系统对应的设备文件名
blocks:指定文件系统的磁盘块数

案例1:将test.img格式化为ext4文件系统

mkfs -t ext4 ./test.img

df 命令详解
Linux df(disk free) 命令用于显示目前在 Linux 系统上的文件系统磁盘使用情况统计

df [OPTION]... [FILE]...

参数:

-a, --all 包含所有的具有 0 Blocks 的文件系统
-h, --human-readable 使用人类可读的格式(预设值是不加这个选项的…)
-H, --si 很像 -h, 但是用 1000 为单位而不是用 1024
-t, --type=TYPE 限制列出文件系统的 TYPE
-T, --print-type 显示文件系统的形式

案例1:查看磁盘使用情况

df -h
文件系统的名称或挂载点		文件系统的总容量	 已使用空间量    未使用的可用空间   已使用空间的百分比   文件系统挂载的位置
Filesystem      		Size  			 Used 		    Avail 			Use% 				Mounted on
devtmpfs        		909M     		 0  			909M   			0% 					/dev
tmpfs           		919M     		 0  			919M   			0% 					/dev/shm
tmpfs           		919M  			 101M  		    819M  			11% 				/run
tmpfs           		919M     		 0  			919M   			0% 					/sys/fs/cgroup
/dev/vda1        		40G   			 18G   		    21G  			46% 				/
tmpfs           		184M     		 0  			184M   			0% 					/run/user/995
tmpfs           		184M     		 0  			184M   			0% 					/run/user/1000
tmpfs           		184M     		 0  			184M   			0% 					/run/user/0

案例2:查看磁盘的系统类型

df -Th

mount 命令详解

mount 命令用于加载文件系统到指定的加载点。此命令的也常用于挂载光盘,使我们可以访问光盘中的数据,因为你将光盘插入光驱中,Linux 并不会自动挂载,必须使用Linux mount 命令来手动完成挂载。

Linux 系统下不同目录可以挂载不同分区和磁盘设备,它的目录和磁盘分区是分离的,可以自由组合(通过挂载)

不同的目录数据可以跨越不同的磁盘分区或者不同的磁盘设备。

挂载的实质是为磁盘添加入口(挂载点)。

mount [-l]
mount [-t vfstype] [-o options] device dir

参数:

-l:显示已加载的文件系统列表
-t: 加载文件系统类型支持常见系统类型的 ext3,ext4,iso9660,tmpfs,xfs 等,大部分情况可以不指定,mount 可以自己识别
-o options 主要用来描述设备或档案的挂接方式

loop:用来把一个文件当成硬盘分区挂接上系统
ro:采用只读方式挂接设备
rw:采用读写方式挂接设备

device: 要挂接(mount)的设备
dir: 挂载点的目录

mount ./test.img ../testmymount/

将当前目录下的test.img挂在到上级目录下的testmymount下

在这里插入图片描述

在这里插入图片描述

注意:不是根目录下所有目录都能作为挂载点,由于挂载操作会使得挂载目录中原有文件被隐藏,所以根目录以和系统原有目录都不能作为挂载点,可能造成系统异常甚至崩溃,最好新建一个空目录作为挂载点

unshare 命令详解
它可以将进程与Linux系统的某些命名空间分离开来,使其成为一个独立的进程,在该进程中可以自定义一些命名空间,如网络、文件系统、进程、户等。

unshare [options] program [arguments]
参数含义
-i, --ipc不共享 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 优先挂载过去

案例1:进行主机名的隔离

[root@fl testmymount]# unshare -u /bin/bash
[root@fl testmymount]# hostname test1
[root@fl testmymount]# hostname
test1

然后再启动另外一个shell,再查看hostname
在这里插入图片描述

3.3.4 PID 隔离

unshare -p /bin/bash

运行这个命令后,会出现以下错误
在这里插入图片描述
主要原因是:因为如果不建新进程,新的 namespace 会用 unshare的 PID 作为新的空间的父进程,而这个 unshare 进程并不在新的 namespace 中,所以会报个错 Cannot allocate memory

如果要正常运行,则需要添加 --fork参数

unshare -p --fork /bin/bash

执行之后,通过命令 ll /proc 查看proc目录
在这里插入图片描述

然后再启动另外一个shell,也查看proc目录

在这里插入图片描述

结果是一样的,原因就是:
因为 Linux 下的每个进程都有一个对应的 /proc/PID 目录,该目录包含了大量的有关当前进程的信息。 对一个 PID namespace 而言,/proc 目录只包含当前namespace 和它所有子孙后代 namespace 里的进程的信息。创建一个新的 PID namespace 后,如果想让子进程中的 top、ps 等依赖 /proc 文件系统的命令工作,还需要挂载 /proc 文件系统。而文件系统隔离是 mount namespace 管理的,所以 linux特意提供了一个选项–mount-proc 来解决这个问题。如果不带这个我们看到的进程还是系统的进程信息。

带上–mount-proc选项

unshare --fork --pid --mount-proc /bin/bash

在这里插入图片描述
再通过命令 ps -ef 查看进程信息

在这里插入图片描述

因此成功的做到了pid的隔离

3.3.5 Mount 隔离

执行 Mount 隔离命令

unshare --mount --fork /bin/bash

创建一个名为data.img的空白文件

dd if=/dev/zero of=data.img bs=8k count=10240

将data.img进行格式化

mkfs -t ext4 ./data.img

创建挂载的目录

mkdir ../datamount

进行挂载

mount -t ext4 ./data.img ../datamount/

使用命令 df -h 进行检测

在这里插入图片描述

打开一个新的 shell 窗口,使用命令 df -h 查看
在这里插入图片描述
在这里没有找到 /root/datamount 这个挂载点,因此可以确认mount隔离成功

如果想要取消挂载,使用命令umount即可

umount 挂载点

3.3.6 容器虚拟化基础之 cgroups

1、什么是 cgroups
cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。简单说,cgroups 可以限制、记录任务组所使用的物理资源。本质上来说,cgroups 是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。

2、为什么使用 cgroups
其可以做到对 cpu,内存等资源实现精细化的控制,目前越来越火的轻量级容器Docker 及 k8s 中的 pod 就使用了 cgroups 提供的资源限制能力来完成 cpu,内存等部分的资源控制。比如在一个既部署了前端 web 服务,也部署了后端计算模块的八核服务器上,可以使用 cgroups 限制 web server 仅可以使用其中的六个核,把剩下的两个核留给后端计算模块

3、cgroups 的用途
Resource limitation: 限制资源使用,例:内存使用上限/cpu的使用限制
Prioritization: 优先级控制,例:CPU 利用/磁盘 IO 吞吐
Accounting: 一些审计或一些统计
Control: 挂起进程/恢复执行进程

4、cgroups 可以控制的子系统

blkio对块设备的 IO 进行限制
cpu限制 CPU 时间片的分配
cpuacct生成 cgroup 中的任务占用 CPU 资源的报告,与 cpu 挂载在同一目录
cpuset给 cgroup 中的任务分配独立的 CPU(多处理器系统) 和内存节点
devices限制设备文件的创建,和对设备文件的读写
freezer暂停/恢复 cgroup 中的任务
memory对 cgroup 中的任务的可用内存进行限制,并自动生成资源占用报告
perf_eventcgroup 中的任务创建的数据报文的类别标识符,这让 Linux 流量控制器(tc 指令)可以识别来自特定 cgroup 任务的数据包,并进行网络限制
hugetlb限制使用的内存页数量
pids限制任务的数量
rdma限制 RDMA 资源(Remote Direct Memory Access,远程直接数据存取)

3.3.7 CGroups 资源控制实战

pidstat
pidstat 是 sysstat 的一个命令,用于监控全部或指定进程的 CPU、内存、线程、设备IO 等系统资源的占用情况。Pidstat 第一次采样显示自系统启动开始的各项统计信息,后续采样将显示自上次运行命令后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息

pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ]

参数

-u:默认参数,显示各进程的 CPU 使用统计
-r:显示各进程的内存使用统计
-d:显示各进程的 IO 使用情况
-p:指定进程号,ALL 表示所有进程
-C:指定命令
-l:显示命令名和所有参数

CentOS 安装

#卸载
yum remove sysstat -y
#安装
yum install sysstat -y

stress
stress 是 Linux 的一个压力测试工具,可以对 CPU、Memory、IO、磁盘进行压力测试

stress [OPTION [ARG]]

参数

-c, --cpu N:产生 N 个进程,每个进程都循环调用 sqrt 函数产生 CPU 压力
-i, --io N:产生 N 个进程,每个进程循环调用 sync 将内存缓冲区内容写到磁盘上,产生 IO 压力。通过系统调用 sync 刷新内存缓冲区数据到磁盘中,以确保同步。如果缓冲区内数据较少,写到磁盘中的数据也较少,不会产生 IO 压力。在 SSD 磁盘环境中尤为明显,很可能 iowait 总是 0,却因为大量调用系统调用 sync,导致系统 CPU 使用率 sys 升高
-m, --vm N:产生 N 个进程,每个进程循环调用 malloc/free 函数分配和释放内存

  • - -vm-bytes B:指定分配内存的大小
  • - -vm-keep:一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)

-d, --hdd N:产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件)

  • - -hdd-bytes B:指定文件大小

-t, --timeout N:在 N 秒后结束程序
-q, --quiet:程序在运行的过程中不输出信息

CentOS 安装

#卸载
yum remove stress -y
#安装
yum install stress -y

案例1:在监视期间每2秒报告 “stress” 进程及其子进程的用户CPU使用情况,共报告1000次

shell窗口1,执行以下命令

stress -c 1

在这里插入图片描述

shell窗口2,执行以下命令

pidstat -C stress -p ALL -u 2 1000

在这里插入图片描述

shell窗口3,执行以下命令

在这里插入代码片

在这里插入图片描述

这里明显能看到,系统 CPU 使用率 sys 升高

cgroups 版本查看

cat /proc/filesystems |grep cgroup

在这里插入图片描述

如果看到 cgroup2,表示支持 cgroup v2

cgroups 子系统查看

cat /proc/cgroups

在这里插入图片描述

cgroups 挂载信息查看

mount |grep cgroup

在这里插入图片描述
可以看到默认存储位置为 /sys/fs/cgroup

查看一个进程上的 cgroup 限制
以当前 shell 进程为例,查看进程的 cgroup

cat /proc/$$/cgroup   #$$ 表示当前进程的pid

在这里插入图片描述

比如 cpu 在 cpuacct,cpu下,我们可以找到这个目录,里面有对 init 进程的详细限制信息

ll /sys/fs/cgroup/cpu,cpuacct

在这里插入图片描述

在这里插入图片描述

使用 cgroups 对内存进行控制

第一步:创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录/sys/fs/cgroup/memory,我们创建目录 test_memory

在这里插入图片描述
目录 test_memory创建完成之后,系统会自动把控制组的配置信息初始化好

第二步:设置最大内存使用限制为20M

在这里插入图片描述

第三步:启动 1 个消耗内存的进程,每个进程占用 50M 内存

在这里插入图片描述

第四步:打开一个新的 shell 窗口 B 窗口,使用 pidstat 查看状态

在这里插入图片描述

第五步:打开一个新的 shell C 窗口,将stress进程 的pid 移动到test_memory下的task里,只要进程pid在task里,内存使用就会受到限制

在这里插入图片描述
在这里插入图片描述

此时再看其他两个shell窗口,发现stress已经退出了,因为它本来需要申请50m,现在受到了限制,最多只能申请20m,所以退出了

使用 cgroups 对 cpu 进行控制

第一步:创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录/sys/fs/cgroup/cpu,我们创建目录 test_cpu,可以看到系统会自动为我们创建 cgroup的 cpu 策略

在这里插入图片描述

第二步:打开新的 shell 窗口 B,使用 stress 模拟一个任务,cpu 使用率为 100

stress -c 1

第三步:打开新的shell 窗口 C,使用命令pidstat查看stress任务的cpu的使用率

在这里插入图片描述

第四步:打开新的 shell 窗口 C 窗口,我们设置 cproup 的 cpu 使用率为 30%,cpu 使用率的计算公式 cfs_quota_us/cfs_period_us

在这里插入图片描述
cfs_period_us:cfs_period_us 表示一个 cpu 带宽,单位为微秒。系统总 CPU 带宽 ,默认值 100000
cfs_quota_us:cfs_quota_us 表示 Cgroup 可以使用的 cpu 的带宽,单位为微秒。cfs_quota_us 为-1,表示使用的 CPU 不受 cgroup 限制。cfs_quota_us 的最小值为1ms(1000),最大值为 1s

所以我们将 cfs_quota_us 的值设置为 30000 ,从理论上讲就可以限制 test_cpu 控制的进程的 cpu 利用率最多是 30%

echo 30000 > ./cpu.cfs_quota_us

在这里插入图片描述

第五步:将stress进程的pid加入到tasks 文件进行控制

echo "27324" > ./tasks

第六步:查看shell 窗口 C中stress任务的cpu的使用率

在这里插入图片描述

由结果可以知道,cpu的使用率从接近100%,下降到了30%

至此我们成功的模拟了对内存和 cpu 的使用控制,而 docker 本质也是调用这些的 API来完成对资源的管理,只不过 docker 的易用性和镜像的设计更加人性化

3.3.8 容器虚拟化基础之 LXC

LXC(LinuX Containers)Linux 容器,一种操作系统层虚拟化技术,为 Linux 内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享 API 来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得 Linux 用户可以容易的创建和管理系统或应用容器。

LXC 是最早一批真正把完整的容器技术用一组简易使用的工具和模板来极大的简化了容器技术使用的一个方案

LXC 虽然极大的简化了容器技术的使用,但比起直接通过内核调用来使用容器技术,其复杂程度其实并没有多大降低,因为我们必须要学会 LXC 的一组命令工具,且由于内核的创建都是通过命令来实现的,通过批量命令实现数据迁移并不容易。其隔离性也没有虚拟机那么强大。后来就出现了 docker,所以从一定程度上来说,docker 就是 LXC 的增强版。

在这里插入图片描述

3.3.9 LXC 容器操作实战

LXC 的常用命令如下:

lxc-checkconfig
检查系统环境是否满足容器使用要求
格式:lxc-checkconfig

lxc-create
创建 lxc 容器
格式:lxc-create -n NAME -t TEMPLATE_NAME [-- template-options]

lxc-start
启动容器,-d表示在后台运行
格式:lxc-start -n NAME -d

lxc-ls
列出所有容器,-f 表示打印常用的信息
格式:lxc-ls -f

lxc-info
查看容器相关的信息
格式:lxc-info -n NAME

lxc-attach
进入容器执行命令
格式:lxc-attach --name=NAME [-- COMMAND]

lxc-stop
停止容器
格式:lxc-stop -n NAME

lxc-destory
删除处于停机状态的容器
格式:lxc-destory -n NAME

CentOS 卸载和安装 LXC

安装前执行检查看下是否需要卸载,如果需要卸载,执行下面的命令完成卸载

# 一、检查是否安装。清理资源
systemctl status lxc #检查是否安装
lxc-ls -f #遍历所有容器
lxc-stop -n 容器名字 #停止对应的容器
lxc-destroy -n 容器名字 #删除对应的容器
# 二、 卸载软件
yum remove lxc lxc-templates lxc-libs lxc-extra libvirt debootstrap 
# 三、检查,提示服务不存在
systemctl status lxc

安装 LXC

# 一、 配置源
yum -y install epel-release #这个软件包里包含 epel yum 源和GPG 的配置
# 二、 安装程序
# lxc 主程序包
# lxc-templates lxc 的配置模板
# bridge-utils 网桥管理工具 lxc-libs lxc 所需的库文件
# libcgroup cgroup 安装包
# libvirt 管理 Linux 的虚拟化功能所需的服务器端守护程序。 需要针对特定驱动程序的管理程序。
# debootstrap debootstrap 是 Debian 引导程序,它允许您将 Debian 基本系统(例如 Debian 或 Ubuntu)安装到当前正在运行的系统的目录中。
yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt lxc-extra debootstrap 
#三、启动和检查
#如果未运行输入以下命令完成启动
systemctl start lxc #启动 lxc 服务
systemctl start libvirtd #启动虚拟机监控服务
systemctl status lxc #检查lxc服务的状态
systemctl status libvirtd #检查虚拟机监控服务的状态

检查 lxc 的功能支持情况

lxc-checkconfig

在这里插入图片描述

查看 lxc 提供的容器模板

ls /usr/share/lxc/templates/

在这里插入图片描述

创建一个 lxc 虚拟主机,这个命令就会下载安装指定环境下的软件包,创建新容器。整个过程需要时间较长,与容器的类型有关。

创建 LXC 主机,-t 指定模板容器,- -name 指定要创建容器的名称,下面创建的是ubuntu

lxc-create -t ubuntu --name lxchost1 -- -r xenial -a amd64

下面创建的是centos

lxc-create -t centos --name centos1 -- --release 7 --arch x86_64

这里,我就创建一个ubuntu容器

在这里插入图片描述

通过命令 lxc-ls -f 遍历所有的容器,查看创建的容器信息

在这里插入图片描述

启动容器,我们可以看到容器状态为运行中,并分配了一个ipv4的地址

在这里插入图片描述

查看容器的详细信息

lxc-info -n lxchost1

在这里插入图片描述

容器 ip 为 192.168.122.84,我们通过 ssh 进入容器,查看 ip 地址,磁盘挂载信息,目录信息和宿主机都不一样

在这里插入图片描述
用户名和密码都是ubuntu

此时和宿主机做一个对比

宿主机的根目录

在这里插入图片描述

容器的根目录

在这里插入图片描述

可以发现宿主机和容器进行了文件系统的隔离

宿主机的挂载点

在这里插入图片描述

容器的的挂载点

在这里插入图片描述

挂载点也发生了隔离,除此之外,也可以自行查看其他信息,比如进程等,最终也是一样的结果,都发生了隔离

停止容器
在这里插入图片描述

删除容器

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/178823.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

没有PDF密码,如何解密文件?

PDF文件有两种密码&#xff0c;一个打开密码、一个限制编辑密码&#xff0c;因为PDF文件设置了密码&#xff0c;那么打开、编辑PDF文件就会受到限制。想要解密&#xff0c;我们需要输入正确的密码&#xff0c;但是有时候我们可能会出现忘记密码的情况&#xff0c;或者网上下载P…

Linux-----nginx的简介,nginx搭载负载均衡以及nginx部署前后端分离项目

目录 nginx的简介 是什么 nginx的特点以及功能 Nginx负载均衡 下载 安装 负载均衡 nginx的简介 是什么 Nginx是一个高性能的开源Web服务器和反向代理服务器。它的设计目标是为了解决C10k问题&#xff0c;即在同一时间内支持上万个并发连接。 Nginx采用事件驱动的异…

听GPT 讲Rust源代码--library/std(12)

题图来自 Decoding Rust: Everything You Need to Know About the Programming Language[1] File: rust/library/std/src/os/watchos/mod.rs 该文件&#xff08;rust/library/std/src/os/watchos/mod.rs&#xff09;的作用是为Rust标准库提供支持WatchOS操作系统的特定功能。 W…

C语言实现俄罗斯方块游戏

文章目录 1 前言2 游戏截图3 源代码 1 前言 本文介绍的是我空闲时间用C语言写的一个俄罗斯方块游戏&#xff0c;整个程序只有一个文件&#xff0c;实现了基本的游戏功能&#xff0c;但还是有些缺陷&#xff0c;希望有心之士能够继续完善&#xff0c;感谢各位&#xff01; 2 游戏…

【大数据基础平台】星环TDH社区集群版本部署

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f…

Spring-Spring 之底层架构核心概念解析

BeanDefinition BeanDefinition表示Bean定义&#xff0c;BeanDefinition中存在很多属性用来描述一个Bean的特点。比如&#xff1a; class&#xff0c;表示Bean类型scope&#xff0c;表示Bean作用域&#xff0c;单例或原型等lazyInit&#xff1a;表示Bean是否是懒加载initMeth…

【云备份|| 日志 day3】服务端配置信息模块

云备份day3 使用文件配置加载一些程序的运行关键信息可以让程序的运行更加灵活&#xff0c;且当需要修改部分内容时&#xff0c;不需要在代码上修改&#xff0c;只需要修改配置文件&#xff0c;然后重启服务器即可。 配置信息 热点判断时间文件下载URL前缀路径压缩包后缀名称…

模电学习路径

交流通路实质 列出电路方程1&#xff0c;方程1对时刻t做微分 所得方程1‘ 即为 交流通路 方程1对时刻t做微分&#xff1a;两个不同时刻的方程1相减&#xff0c;并 令两时刻差为 无穷小 微分 改成 差 模电学习路径&#xff1a; 理论 《电路原理》清华大学 于歆杰 朱桂萍 陆文…

学习 SpringMVC 必备的 4 大知识点

一、什么是 SpringMVC 前面我们了解了Spring、SpringBoot&#xff0c;那么 Spring MVC 又是什么呢&#xff1f;关于三者&#xff0c;我们可以这样理解&#xff1a;Spring MVC 是 Spring 框架的核心模块&#xff0c;而 Spring Boot 是 Spring 的脚手架。 Spring MVC 又称作 Sp…

【特殊矩阵的压缩存储】

文章目录 特殊矩阵的压缩存储特殊的矩阵 特殊矩阵的压缩存储 矩阵&#xff1a;一个由m x n个元素排成的m行n列的表。 矩阵的常规存储&#xff1a; 将矩阵描述为一个二维数组。 矩阵的常规存储的特点&#xff1a; 可以将元素进行随机存取&#xff1b; 矩阵运算非常简单&#xf…

linux查看文件夹使用情况以及查看文件大小

1、ls ls 命令是 Linux 中最常用的文件和目录列表命令之一。它可以显示文件的各种属性&#xff0c;包括文件大小。 ls -l <文件名>上述命令会显示文件的详细信息&#xff0c;其中包括文件的大小。文件大小以字节为单位显示&#xff0c;并且在输出中的第 5 列。4096 表示…

我做云原生的那几年

背景介绍 在2020年6月&#xff0c;我加入了一家拥有超过500人的企业。彼时&#xff0c;前端团队人数众多&#xff0c;有二三十名成员。在这样的大团队中&#xff0c;每个人都要寻找自己的独特之处和核心竞争力。否则&#xff0c;你可能会沉没于常规的增删改查工作中&#xff0…

【C++】C++11【下】lambda表达式|thread线程库

目录 1、lambda表达式 1.1 lambda表达式的引入 1.2 lambda表达式的语法 1.3 lambda表达式的原理 2、线程库 2.1thread类的介绍 2.2 线程函数参数 2.3 原子性操作库(atomic) 2.4 使用场景 应用场景1&#xff1a; 应用场景2: 应用场景3&#xff1a; 应用场景4&#xf…

在Qt中解决opencv的putText函数无法绘制中文的一种解决方法

文章目录 1.问题2.查阅资料3.解决办法 1.问题 在opencv中&#xff0c;假如直接使用putText绘制中文&#xff0c;会在图像上出现问号&#xff0c;如下图所示&#xff1a; 2.查阅资料 查了一些资料&#xff0c;说想要解决这个问题&#xff0c;需要用到freetype库或者用opencv…

Java--多线程--Thread类+Runnable接口

1.多进程与多线程 1.1多进程&#xff1a; 一个进程是一个包含自身地址的程序&#xff0c;每个独立执行的程序都称为进程&#xff0c;也就是正在执行的程序&#xff0c;系统可以分配给每个进程一段有限的使用CPU的时间&#xff08;CPU时间片&#xff09;&#xff0c;CPU在这个时…

Django实战项目-学习任务系统-查询列表分页显示

接着上期代码框架&#xff0c;6个主要功能基本实现&#xff0c;剩下的就是细节点的完善优化了。 接着优化查询列表分页显示功能&#xff0c;有很多菜单功能都有查询列表显示页面情况&#xff0c;如果数据量多&#xff0c;不分页显示的话&#xff0c;页面展示效果就不太好。 本…

pytorch 笔记:GRU

1 介绍 对于输入序列中的每个元素&#xff0c;每一层都计算以下函数&#xff1a; ht​ 是t时刻 的隐藏状态xt​ 是t时刻 的输入ht−1​ 是 t-1时刻 同层的隐藏状态或 0时刻 的初始隐藏状态rt​,zt​,nt​ 分别是重置门、更新门和新门。σ 是 sigmoid 函数∗ 是 Hadamard 乘积。…

OpenCV 笔记(4):图像的算术运算、逻辑运算

Part11. 图像的算术运算 图像的本质是一个矩阵&#xff0c;所以可以对它进行一些常见的算术运算&#xff0c;例如加、减、乘、除、平方根、对数、绝对值等等。除此之外&#xff0c;还可以对图像进行逻辑运算和几何变换。 我们先从简单的图像加、减、逻辑运算开始介绍。后续会有…

【Git企业开发】第四节.Git的分支管理策略和bug分支

文章目录 前言一、Git的分支管理策略 1.1 Fast forward 模式和--no-ff 模式 1.2 企业分支管理策略二、bug分支三、删除临时分支四、总结总结 前言 一、Git的分支管理策略 1.1 Fast forward 模式和--no-ff 模式 通常合并分支时&#xff0c;如果可能&#xff0c;Git 会…

61. 旋转链表、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;李歘歘的博客 &#x1f3c6; &#x1f33a;每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点&#xff0c;以及职场小菜鸡的生活。&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&am…