目录
一、Cgroup
1.CGROUP概念
2.CGROUP 子系统
3.CGROUP 示例
二、内存资源限制
1.内存资源限制概念
2.内存资源限制参数 1
3.内存资源限制参数 2
三、CPU 资源限制
1.容器中 CPU 使用
2.容器 CPU 限制参数
四、实验演示
在linux内核里提供进程资源限制的一个底层原理,是一个内核机制。
Linux Cgroup 全称 Linux Control Group, 是 Linux 内核的一个功能,用来限制,控制与分离一个进程组群的资源(如 CPU、内存、磁盘输入输出等)。这个项目最早是由 Google 的工程师在 2006 年发起,最早的名称为进程容器( process containers )。在 2007 年时,因为在 Linux 内核中,容器(container)这个名词太过广泛,为避免混乱,被重命名为 cgroup,并且被合并到 2.6.24 版的内核中去
(1)限制资源使用 #限制进程组群
(2)优先级控制
(3)一些审计或一些统计
(4)挂起进程,恢复执行进程
cpu 子系统,主要限制进程的 cpu 使用率
cpuacct 子系统,可以统计 cgroups 中的进程的 cpu 使用报告
cpuset 子系统,可以为 cgroups 中的进程分配单独的 cpu 节点或者内存节点
memory 子系统,可以限制进程的 memory 使用量,内存子系统,限制内存的使用量
blkio 子系统,可以限制进程的块设备 io
devices 子系统,可以控制进程能够访问某些设备
net_cls 子系统,可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制
net_prio — 这个子系统用来设计网络流量的优先级
freezer 子系统,可以挂起或者恢复 cgroups 中的进程
ns 子系统,可以使不同 cgroups 下面的进程使用不同的 namespace
hugetlb — 这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统
# 查看 Cgroup 挂载点
[root@master ~]# mount -t cgroup
#把cgroup的子系统挂载到当前目录下,我们只要对这些文件做操作,就可以实现这些所谓的cgroup的底层功能的控制。
# 创建隔离组
[root@master cpu]# cd /sys/fs/cgroup/cpu 这个目录为挂在后的挂载点,cpu为挂载cpu子系统
[root@master cpu]# mkdir cpu_test #创建进程组群
# 示例代码(用C语言写的代码)
int main(void)
{
int i = 0;
for(;;) i++;
return 0;
}
#在我们的void函数里,创建一个变量是整型类型叫i,初始值为0,在死循环中i++的意思是i=i+1,无限叠加,
[root@master cpu]# echo 20000 > /sys/fs/cgroup/cpu/cpu_test/cpu.cfs_quota_us
[root@master cpu]# echo 23732 >> /sys/fs/cgroup/cpu/cpu_test/tasks
mount -t cgroup
#把cgroup的子系统挂载到当前目录下,我们只要对这些文件做操作,就可以实现这些所谓的cgroup的底层功能的控制。
vim main.c
int main(void)
{
int i = 0;
for(;;) i++;
return 0;
}
#在我们的void函数里,创建一个变量是整型类型叫i,初始值为0,在死循环中i++的意思是i=i+1,无限叠加。
yum -y install gcc gcc-c++
#安装编译环境
gcc main.c
#把源码main.c编译可执行文件
./a.out
#执行生成的编译文件
top
#查看cpu的使用情况,已经达到100%了
cd /sys/fs/cgroup/cpu
cat tasks
#当前所有进程都在这里面
mkdir cpu_test cd cpu_test/ ls
#cpu.cfs_quota_us代表当前用户可以使用的大小
echo 5360 >> tasks
#a.out的进程号写入tasks文件
echo 20000 >> cpu.cfs_quota_us
#一个周期默认的最大配额是10万,这里给到两万
top
#cpu占比明显下降,这就是cpu资源限制的方法
docker ps -a
#虽然没有给容器做资源限制,但是docker默认给容器做了资源限制.
#不是说已经做了资源限制,而是已经把资源限制的目录创建好了。
cd /sys/fs/cgroup/cpu/docker
#查看容器的资源限制目录
#进入到目录里面,将资源配额写入到cpu.cfs_period_us中,就相当于对整个容器做了资源限制.
可压缩性资源:资源被降低以后,不会影响进程的正常运行
不可压缩性资源:资源被降低以后,会影响进程的正常运行
内存(不可压缩性资源)
默认情况下,如果不对容器做任何限制,容器能够占用当前系统能给容器提供的所有资源
Docker 限制可以从 Memory、CPU、Block I/O 三个方面
OOME:Out Of Memory Exception
一旦发生 OOME,任何进程都有可能被杀死,包括 docker daemon 在内
为此,Docker 调整了 docker daemon 的 OOM 优先级,以免被内核关闭
#在kubernetes中,默认不允许开启虚拟内存,如果开启可能会报错,无法启动
默认情况下,如果不对容器做任何限制,容器能够占用当前系统中的所有 CPU 资源
大多数进程是采用 CFS 调度算法(公平调度原则)
1.13 Docker 版本后支持实时调度算法
docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress -vm 2
#-m表示--memage设置当前的物理内存, -vm 2 为压力测试的一个选项
docker run --name stress -it --rm --cpus 2 lorel/docker-stress-ng:latest stress --cpu 8
#--cpus指定cpu的使用核心数
docker run --name stress -it --rm --cpuset-cpus 0 lorel/docker-stress-ng:latest stress --cpu 8
#指定使用哪个CPU核心
终端1:
docker run --name stress -it --rm lorel/docker-stress-ng:latest stress -vm 2
终端2:
free -m
#查看内存使用情况
docker stats
#查看docker的运行状态
#查看当前容器的的内存大小
终端1:
docker run --name stress -it --rm lorel/docker-stress-ng:latest stress -vm 20
终端2:
docker stats
查看内存资源使用情况
终端1:
docker run --name stress -it --rm -m 100m lorel/docker-stress-ng:latest stress -vm 20
#加入内存资源限制
#没有把错误传递到系统,过度占用内存,随机杀死进程,出现OOM的报错提示
终端2:
docker stats
#查看资源使用情况,观察内存限制的效果。
终端1:
docker run --name stress -it --rm lorel/docker-stress-ng:latest stress --cpu 8
#不加入资源限制,现在实在对物理机的最大CPU资源做压力测试
#会报很多的OOM的错误提示,不断随即删除进程释放资源
终端2:
docker stats
#查看资源使用情况
终端1:
docker run --name stress -it --rm --cpus 6 lorel/docker-stress-ng:latest stress --cpu 8
#会报错,因为没有6个cpu核心
docker run --name stress -it --rm --cpus 0.1 lorel/docker-stress-ng:latest stress --cpu 8
终端2:
docker stats
#查看资源使用情况
终端1:
docker run --name stress -it --rm --cpuset-cpus 0-1 lorel/docker-stress-ng:latest stress --cpu 8
#分配的--cpuset-cpus的值,决定了它的上限,数值如果为0,代表使用cpu的最大值为100%,数值为0-1的时候,表示0-1号的cpu都可以用,最高可以使用cpu至200%
终端2:
docker stats
#查看资源使用情况
终端1:
docker run --name stress -it --rm --cpuset-cpus 0-1 --cpus 0.1 lorel/docker-stress-ng:latest stress --cpu 8
#0-1的cpu都可以用,但是cpu的最大使用值为10%
终端2:
docker stats
#查看docker的资源使用情况