Namespace
Namespace 其实就是一种隔离机制,将运行在同一宿主机上的容器隔离开,不同 Namespace 下容器间不能访问彼此的资源。
隔离的两个作用:
- 充分利用系统资源(同一台宿主机上可以运行多个用户容器);
- 安全性(访问资源控制)。
查看系统支持的 Namespace:
1 | $ ls -l /proc/self/ns/ |
cgroups
cgroups 可以对指定的 进程 做各种计算机资源的限制,如 CPU 使用率、内存使用量、IO 设备的流量等等。
cgroups 通过不同的子系统限制了不同的资源,每个子系统限制一种资源。每个子系统限制资源的方式都是类似的,就是把相关的一组进程分配到一个控制组里,然后通过树结构进行管理,每个控制组都设有自己的资源控制参数。
定义:Linux manual page - cgroups
- CPU 子系统,用来限制一个控制组(一组进程,你可以理解为一个容器里所有的进程)可使用的最大 CPU。
- memory 子系统,用来限制一个控制组最大的内存使用量。
- pids 子系统,用来限制一个控制组里最多可以运行多少个进程。
- cpuset 子系统, 这个子系统来限制一个控制组里的进程可以在哪几个物理 CPU 上运行。
Cgroups 有 v1 和 v2 两个版本:
- Cgroups v1 在 Linux 中很早就实现了,各种子系统比较独立,每个进程在各个 Cgroups 子系统中独立配置,可以属于不同的 group。虽然这样比较灵活,但是也存在问题,会导致对同一进程的资源协调比较困难(比如 memory Cgroup 与 blkio Cgroup 之间就不能协作)。虽然 v1 有缺陷,但是在主流的生产环境中,大部分使用的还是 v1。
- Cgroups v2 做了设计改进,解决了 v1 的问题,使各个子系统可以协调统一地管理资源。不过 Cgroups v2 在生产环境的应用还很少,因为该版本很多子系统的实现需要较新版本的 Linux 内核,还有无论是主流的 Linux 发行版本还是容器云平台,比如 Kubernetes,对 v2 的支持也刚刚起步。
对于启动的每个容器,都会在 Cgroups 子系统下建立一个目录,在 Cgroups 中这个目录也被称作控制组,比如下图里的”docker-
“”docker- “等。然后我们设置这个控制组的参数,通过这个方式,来限制这个容器的内存资源。
在 Ubuntu 20.04,我安装 Docker 是使用 get-docker.com 脚本安装的,默认使用 systemd 来管理的,所以目录和图中有一些不同。
1 | # /sys/fs/cgroup/memory/docker/<容器ID> |
案例:将这个控制组 memory 最大用量设置为 2GB。
设置后,cgroup.procs 里面所有进程 Memory 使用量之和,最大也不会超过 2GB。
1 | # (2* 1024 * 1024 * 1024 = 2147483648) |
EOF