[从零开始学容器] 8.容器的资源隔离与资源限制

资源隔离

Docker的资源隔离是基于Namespace的。在Linux中有8种Namespace,Docker仅使用了其中6种:Mount Namespace、PID Namespace、Net Namespace、IPC Namespace、UTS Namespace、User Namespace。

各个Namespace的作用

名称作用
Mount Namespace隔离不同的进程或进程组看到的挂载点,即不同的进程看到不同的挂载目录, 在独立的 Mount Namespace 内创建挂载目录是不影响主机的挂载目录的。
PID Namespace隔离进程,在不同的PID Namespace中,进程可以拥有相同的PID号。
UTS Namespace隔离主机名,允许每个UTS Namespace拥有一个独立的主机名
IPC Namespace隔离进程间通信。PID Namespace 和 IPC Namespace 一起使用可以实现同一 IPC Namespace 内的进程彼此可以通信,不同 IPC Namespace 的进程却不能通信
User Namespace隔离用户和用户组。一个比较典型的应用场景就是在主机上以非 root 用户运行的进程可以在一个单独的 User Namespace 中映射成 root 用户
Net Namespace隔离网络设备、IP地址和端口等信息。Net Namespace 可以让每个进程拥有自己独立的 IP 地址,端口和网卡信息

Namespace对于Docker

当 Docker 新建一个容器时, 它会创建这六种 Namespace,然后将容器中的进程加入这些 Namespace 之中,使得 Docker 容器中的进程只能看到当前 Namespace 中的系统资源。

正是由于 Docker 使用了 Linux 的这些 Namespace 技术,才实现了 Docker 容器的隔离,可以说没有 Namespace,就没有 Docker 容器。

资源限制

Docker容器有了Namespace之后,可以进行资源隔离了,但是使用的还是宿主机的CPU、内存等资源。如果容器占据了太多的资源,那么会影响主机的正常运行。在这里,Docker使用Linux内核的另一个核心技术cgroups

cgroups

cgroups(全称:control groups)是 Linux 内核的一个功能,它可以实现限制进程或者进程组的资源(如 CPU、内存、磁盘 IO 等)

cgroups的功能

功能描述
资源限制限制资源的使用量,例如我们可以通过限制某个业务的内存上限,从而保护主机其他业务的安全运行。
优先级控制不同的组可以有不同的资源( CPU 、磁盘 IO 等)使用优先级。
审计计算控制组的资源使用情况。
控制控制进程的挂起或恢复。

cgroups的核心概念

概念描述
子系统(subsystem)是一个内核的组件,一个子系统代表一类资源调度控制器。例如内存子系统可以限制内存的使用量,CPU 子系统可以限制 CPU 的使用时间。
控制组(cgroup)表示一组进程和一组带有参数的子系统的关联关系。例如,一个进程使用了 CPU 子系统来限制 CPU 的使用时间,则这个进程和 CPU 子系统的关联关系称为控制组。
层级树(hierarchy)是由一系列的控制组按照树状结构排列组成的。这种排列方式可以使得控制组拥有父子关系,子控制组默认拥有父控制组的属性,也就是子控制组会继承于父控制组。比如,系统中定义了一个控制组 c1,限制了 CPU 可以使用 1 核,然后另外一个控制组 c2 想实现既限制 CPU 使用 1 核,同时限制内存使用 2G,那么 c2 就可以直接继承 c1,无须重复定义 CPU 限制。

cgroups的子系统

可以通过命令sudo mount -t cgroup查看cgroup挂载信息

cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuset)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,net_prio,net_cls)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,perf_event)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,devices)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,blkio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuacct,cpu)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,pids)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,freezer)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,hugetlb)

可以看到cgroup挂载了很多子系统,包括cpu、内存等

1. CPU子系统

cpu子系统的创建只需在/sys/fs/cgroup/cpu/下创建新文件夹即可

如以下命令

mkdir /sys/fs/cgroup/cpu/mydocker

使用命令ls -l /sys/fs/cgroup/cpu/mydocker查看创建文件夹后的文件夹内容

-rw-r--r--. 1 root root 0 Dec 11 10:53 cgroup.clone_children
--w--w--w-. 1 root root 0 Dec 11 10:53 cgroup.event_control
-rw-r--r--. 1 root root 0 Dec 11 10:53 cgroup.procs
-r--r--r--. 1 root root 0 Dec 11 10:53 cpuacct.stat
-rw-r--r--. 1 root root 0 Dec 11 10:53 cpuacct.usage
-r--r--r--. 1 root root 0 Dec 11 10:53 cpuacct.usage_percpu
-rw-r--r--. 1 root root 0 Dec 11 10:53 cpu.cfs_period_us
-rw-r--r--. 1 root root 0 Dec 11 11:03 cpu.cfs_quota_us
-rw-r--r--. 1 root root 0 Dec 11 10:53 cpu.rt_period_us
-rw-r--r--. 1 root root 0 Dec 11 10:53 cpu.rt_runtime_us
-rw-r--r--. 1 root root 0 Dec 11 10:53 cpu.shares
-r--r--r--. 1 root root 0 Dec 11 10:53 cpu.stat
-rw-r--r--. 1 root root 0 Dec 11 10:53 notify_on_release
-rw-r--r--. 1 root root 0 Dec 11 10:58 tasks

cgroup自动创建了很多关联文件,其中cpu.cfs_quota_us标识某一个阶段限制的CPU时间总量,单位为微秒。我们想限制某个进程最多使用 1 核 CPU,就在这个文件里写入 100000(100000 代表限制 1 个核) ,tasks 文件中写入进程的 ID 即可(如果要限制多个进程 ID,在 tasks 文件中用换行符分隔即可)。

2. Memroy子系统

与上面一样,使用命令mkdir /sys/fs/cgroup/memory/mydocker即可创建Memroy的子系统

其中 memory.limit_in_bytes 文件代表内存使用总量,单位为 byte。
例如,这里对内存使用限制为 1G,则向 memory.limit_in_bytes 文件写入 1073741824

cd /sys/fs/cgroup/memory/mydocker
echo $$ > tasks 

删除cgroups

上面创建的子系统不需要后,可以直接删除创建的文件夹即可

如:

rmdir /sys/fs/cgroup/cpu/mydocker

Docker使用cgroups

先创建一个限制为1Gb的Nginx容器

docker run -d -m=1g nginx

然后使用命令ls -l /sys/fs/cgroup/memory查看cgroups的内存子系统的目录

[root@centeros home]# ls -l /sys/fs/cgroup/memory
total 0
-rw-r--r--.  1 root root 0 Nov 30 11:07 cgroup.clone_children
--w--w--w-.  1 root root 0 Nov 30 11:07 cgroup.event_control
-rw-r--r--.  1 root root 0 Nov 30 11:07 cgroup.procs
-r--r--r--.  1 root root 0 Nov 30 11:07 cgroup.sane_behavior
drwxr-xr-x.  4 root root 0 Dec 11 11:19 docker

可以看到有docker目录,进入目录

[root@centeros memory]# cd docker/
[root@centeros docker]# ls
3c65b074d1626159abba5c2096b992bbda2dd235f5357a51ebecea855e366273  memory.force_empty              memory.kmem.tcp.limit_in_bytes      memory.memsw.failcnt             memory.oom_control          memory.use_hierarchy
7d8786780f1cba1ec40a452e103c5ca11c3826203452aefbc9f8d08306ada012

有刚刚创建的容器ID,进入,查看一下该容器的memroy.limit_in_bytes文件内容

[root@centeros 3c65b074d1626159abba5c2096b992bbda2dd235f5357a51ebecea855e366273]# cat memory.limit_in_bytes 
1073741824

正好是1Gb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值