Docker安全与资源

一、cgroup资源配置方法

******1.******cgroup概念

cgroup(control group控制族群)

(1)什么是cgroup

和namespace类似,也是将进程进程分组,但是目的与namespace不一样,namespace是为了隔离进程组之前的资源,而cgroup是为了对一组进程进行统一的资源监控和限制。

(2)为什么要使用cgroup

在Linux里,对进程进程分组,比如Session group、process group等,后来需要追踪一组进程的内存和IO使用情况,出现了cgroup,用来统一对进程进行分组,并在分组的基础上对进程进程监控和资源控制管理等。

(3)cgroup的作用

cgroup(control group控制族群)是一个内核特性,用于限制、统计、隔离一组进程的资源(CPU、内存、磁盘、网络等),首字母不要大写。Docker通过cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。

cgroup 主要功能包括:
  • 资源限制:限制一组进程的可用资源阈值。
  • 资源监控:监控 cgroup 级别的资源使用状态。
  • 进程控制:控制(挂起 or 恢复)cgroup 中的所有进程。
  • 优先级控制:控制不同 cgroup 的优先级,当资源不足时,优先满足优先级高的 cgroup。

控制族群就是按照一组某种标准划分的进程。Cgroup中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也可以从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用cgroups以控制族群为单位分配资源,同时受到cgroups以控制族群为单位设定限制。

注意:

  • 单数形式(cgroup)指所有特性,也可以作为"cgroup controllers"的修饰。
  • 复数形式(cgroups)指多个 cgroup。
(4)docker利用cgroup隔离其命名空间

cgroup是一种资源控制手段,也是容器隔离的6个名称空间的一种实现手段

Docker 是一款常用的容器化管理工具,其中的命名空间是其重要特性之一。Docker 命名空间可以分为六种类型,每种类型都有其独特的作用和用途。下面一一介绍这六种命名空间:

1. Mount (mnt)

这种命名空间隔离的是挂载点。通过这个空间,我们可以在容器中挂载文件系统,而不会影响到主机系统的挂载点,实现了文件系统的隔离。

2. Process ID (pid)

这种命名空间隔离了进程 ID。使用这种空间可以将容器内部的进程 ID 隔离开来,从而避免与宿主机的进程 ID 冲突。

3. Network (net)

这种命名空间隔离的是网络配置。通过这个空间,我们可以自定义容器的网络配置,而不会影响到宿主机或其他容器的网络配置,实现了网络的隔离。

4. Interprocess Communication (ipc)

这种命名空间隔离的是进程间通信。使用这个空间,可以将容器内部的进程间通信隔离,避免与宿主机或其他容器的进程间通信冲突。

5. User ID (user)

这种命名空间隔离的是用户 ID。使用这种命名空间可以让容器内部的用户 ID 和宿主机上的用户 ID 隔离开来,从而避免权限问题。

6. UTS Namespace (uts)

这种命名空间隔离的是主机的主机名和域名。使用这种空间可以让容器内部有独立的主机名和域名,而不会影响到宿主机的主机名和域名。

当我们需要在 Docker 中进行资源隔离和管理时,这些命名空间 是非常有用的。通过这些命名空间,可以更好地隔离各个容器之间的资源,从而使容器的资源利用更加高效,保持容器的互相独立性。

每个容器相当于一个进程

进程相当于资源

(5)docker中的cgroup驱动器

对于cgroup的操作驱动,大多数linux发行版上,操作系统默认的驱动都为systemd。

docker支持的cgroup驱动器有两个:cgroupfs和systemcd

  • cgroupfs是文件驱动修改,内核功能没有提供任何的系统调用接口,而是对 linux vfs 的一个实现,因此可以用类似文件系统的方式进行操作。
  • systemd封装了 cgroups 的软件也能让你通过它们定义的接口控制 cgroups 的内容,因此是通过接口调用驱动修改。

docker默认的cgroup的驱动为cgroupfs,可通过启动参数native.cgroupdriver=systemd进行修改

Kubernetes的默认驱动和docker的驱动是一致的。

因为多数linux发行版的cgroup的驱动为systemd,所以当再选择cgroupfs作为驱动时,会致使操作系统中存在两个cgroup驱动,会带来不稳定的影响。所以在系统已经使用systemd的基础上,配置不推荐使用cgroupfs,直接使用systemd即可。

二、使用 Stress 工具测试 CPU 和内存

1.用 Stress 工具测试 CPU 和内存

[root@localhost ~]# docker pull centos:7 
[root@localhost ~]# cd /root/stress/

[root@localhost ~]# vim /root/stress/Dockerfile
FROM centos:7 
MAINTAINER 5CC 
RUN yum -y install wget 
RUN wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo 
RUN yum -y install stress 


[root@localhost ~]# cd /root/stress 
[root@localhost stress]# docker build -t centos:stress .


[root@localhost stress]# docker run -tid --name cpu100 --cpu-shares 100 centos:stress stress -c 10
[root@localhost ~]# docker exec -it cpu100 bash

备注:

stress是一个压力测试工具,用于测试cpu和内存的负载

cpu.shares。这个值是 CPU cgroup 对于控制组之间的 CPU 分配比例,它的缺省值是 1024。

-c:运行10个stress进程

使用cpu share命令设置容器使用cpu的优先级

[root@localhost ~]# docker run -tid --name cpu512 --cpu-shares 512 centos:stress stress -c 10 

[root@localhost ~]# docker exec -it cpu512 bash
进入容器用top命令查看资源利用情况

设置cpu资源翻倍

[root@localhost~]#docker run -tid --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10 
[root@localhost ~]# docker exec -it cpu1024 bash

进入容器用top命令查看资源利用情况

三个容器的对比(查看其中stress的进程数量)

备注:

测试完后删掉这三个容器

docker rm cpu100 -f

docker rm cpu512 -f

docker rm cpu1024 -f

2.CPU周期限制

[root@localhost ~]# docker run -tid --name mem --cpu-period 100000 --cpu-quota 200000 centos:stress 
[root@localhost ~]# docker exec -it mem bash
[root@738f9fc62048 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
[root@738f9fc62048 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us

备注:

  • --cpu-period 是用来指定容器对 CPU 的使用要在多长时间内做一次重新分配。
  • --cpu-quota 是用来指定在这个周期内,最多可以有多少时间用来跑这个容器。
  • cpu-period 和 cpu-quota 的单位为微秒(μs)

3.CPU Core 控制

[root@localhost ~]# docker run -tid --name cpu1 --cpuset-cpus 0-2 centos:stress

注意:docker主机需要更多的cpu内核,否则包含3个内核的容器无法创建,增加内核后重启一下docker主机

0-2表示0、1、2三个内核

[root@localhost ~]# docker exec -it cpu1 bash 
[root@5204fe18208e /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus

4.CPU 配额控制参数的混合使用

[root@localhost ~]# docker run -tid --name cpu3 --cpuset-cpus 3 --cpu-shares 512 centos:stress stress -c 1 
[root@localhost ~]# docker exec -it cpu3 bash

进入容器用top命令查看资源利用情况

注意:

docker主机的cpu内核数量要大于等于满足配额数量

[root@localhost ~]# docker run -tid --name cpu4 --cpuset-cpus 3 --cpu-shares 1024 centos:stress stress -c 1
[root@localhost ~]# docker exec -it cpu4 bash

进入容器用top命令查看资源利用情况

对比两次的显示结果,重点查看%CPU这一列的值,应该为2:1的比例

stress -c 1 命令,将会给系统一个随机负载,产生 1 个进程

5.内存限额

允许该容器最多使用 200M 的内存和 300M 的 swap

[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M

备注:

--vm 1:启动 1 个内存工作线程

--vm-bytes 280M:每个线程分配 280M 内存

  • 分配 280M 内存。
  • 释放 280M 内存。
  • 再分配 280M 内存。
  • 再释放 280M 内存。
  • 一直循环......

让工作线程分配的内存超过 300M,分配的内存超过限额,stress 线程报错,容器退出:

[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M

6.Block IO 的限制

默认情况下,所有容器能平等地读写磁盘,可以通过设置--blkio-weight 参数来改变容器block IO 的优先级。

--blkio-weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500。取值范围10--1000

在下面的例子中,容器 A 读写磁盘的带宽是容器 B 的两倍。

[root@localhost ~]# docker run -it --name container_A --blkio-weight 600 centos:stress 
[root@5e7093d94869 /]# cat /sys/fs/cgroup/blkio/blkio.weight 

[root@localhost ~]# docker run -it --name container_B --blkio-weight 300 centos:stress 
[root@39947b6517d4 /]# cat /sys/fs/cgroup/blkio/blkio.weight 
cat /sys/fs/cgroup/blkio/blkio.bfq.weight

注意:

kernel 5.10 或更高的版本不在适用

要使 --blkio-weight 生效,需要保证 IO 的调度算法为 CFQ。可以使用下面的方式查看:

root@localhost:~# cat /sys/block/sda/queue/scheduler

noop [deadline] cfq

7.bps iops 的限制

限制容器写 /dev/sda 的速率为 5 MB/s

[root@localhost ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress 
[root@e3eb0e9ad6fc /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct

不限速

[root@localhost ~]# docker run -it centos:stress 
[root@cb6691338f52 /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
相关推荐
DC_BLOG26 分钟前
IPv6(四)
运维·服务器·网络·ip
shelby_loo27 分钟前
通过 Docker 部署 MySQL 服务器
服务器·mysql·docker
沈艺强32 分钟前
伊犁linux 创建yum 源过程
linux·运维·服务器
拾光师36 分钟前
linux命令行快捷键
linux·运维·服务器
wang_book3 小时前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
prcyang3 小时前
Docker Compose
运维·docker·容器
蜗牛^^O^4 小时前
Docker和K8S
java·docker·kubernetes
脚踏实地的大梦想家4 小时前
【Docker】安装全流程与配置完整镜像源(可安装 nginx)
运维·docker·容器
Zww08914 小时前
docker部署个人网页导航
运维·docker·容器
运维小白。。4 小时前
Nginx 反向代理
运维·服务器·nginx·http