标签:top mkdir res proc文件 一段 period uid 种类 control
使用namespace技术,实现隔离
namespace 实际上修改了应用进程看待整个计算机的视图,即它的视线被操作系统做了限制,只能看到某些指定内容 。对宿主机来说,这些被“隔离”的进程和其他进程没有啥太大差别
用户运行在容器里的业务进程,和宿主机上其他进程一样,都是由宿主机操作系统统一管理,只不过这些被隔离的业务进程拥有额外设置过的namespace参数,docker 在这里扮演的角色是旁路辅助和管理工作
(敏捷和高性能是容器比虚拟机最大的优势)
虚拟化技术作为沙盒,要由Hypervisor来负责创建虚拟机,虚拟机是真实存在的,里面必须有一个完整的Guest OS才能执行用户的应用进程。带来了额外的资源消耗和占用
KVM虚拟机启动后,不做优化,就要占100-200MB内存。同事虚拟机里的业务进程,对操作系统调用需要经过虚拟化软件的拦截和处理,有一层的性能损耗。尤其对计算资源,网络和磁盘IO的损耗非常大。
容器化的业务应用,还是宿主机上的普通进程,虚拟化带来的性能损耗不存在。而且不需要GuestOS。容器额外的资源占用基础可以忽略。
namespace 隔离机制相比虚拟化技术有不足之处,主要问题:隔离不彻底
多个容器之间使用的还是同一个宿主机的操作系统内核
跨内核的镜像就无法使用。
有很多资源和对象不能被namespace化的,最典型的就是时间
如果容器中业务进程使用settimeofday(2)修改了系统事件,整个宿主机时间都会被修改。
seccomp技术,可以对容器内部的所有系统调用进行过滤和甄别进行安全加固,但是会拖累容器的性能。
如果只使用namespace技术,只是障眼法,看到的是想让你看到的
但是!在宿主机上这个容器1里的业务进程A和别的容器2里的业务进程B,在宿主机层面看到的是同等级的应用。平等的竞争关系。
虽然障眼法,表面被隔离了,但是它能使用的资源cpu,内存啥的,都是可以被宿主机上其他进程占用的,进程A也可以把整个宿主机的资源吃光
linux cgroups 就是来解决这个问题的
linux control groups,主要作用,限制一个进程组能够使用的资源上限,cpu,内存,磁盘,网络带宽,进程优先级设置,审计,进程挂起,恢复
cgroups给用户暴露出来的是linux文件系统/sys/fs/cgroup
$ mount -t cgroup
cpuset on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cpu on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
cpuacct on /sys/fs/cgroup/cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct)
blkio on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
memory on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
...
cpuset,cpu,memory这样的子系统,就是这台机器可以被cgroups限制的资源种类
进入cpu限制目录
$ ls /sys/fs/cgroup/cpu
cgroup.clone_children cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release
cgroup.procs cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat tasks
其中cfs_period 和cfs_quota这2个关键字,就可以用来限制进程使用cpu的情况
限制进程在长度为cfs_period的一段时间里,只能被分配到总量为cfs_quota的cpu时间
创建子目录控制组container
root@ubuntu:/sys/fs/cgroup/cpu$ mkdir container
root@ubuntu:/sys/fs/cgroup/cpu$ ls container/
cgroup.clone_children cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release
cgroup.procs cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat tasks
新创建目录container后,自动生成了子系统对应的资源限制文件
死循环测试
while : ; do : ; done &
[1] 226
死循环跑开,pid是226,把cpu的利用率打到100%。
$ top
%Cpu0 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
现在限制只能使用宿主机的20%cpu
// 每100ms时间里,被该控制组限制的进程只能使用20ms的cpu时间,20%的cpu带宽
$ echo 20000 > /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
// 将生效的进程pid写入tasks文件上
$ echo 226 > /sys/fs/cgroup/cpu/container/tasks
验证
$ top
%Cpu0 : 20.3 us, 0.0 sy, 0.0 ni, 79.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
bikio,块设备设定IO限制,用于磁盘等设备
cpuset,为进程分配单独的cpu核和对应的内存节点
memory,为进程设定内存使用的限制
其实说白了就是学习子系统目录加上资源文件的组合
$ docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu /bin/bash
启动的时候指定了只能用宿主机的20%的cpu
对应到文件系统中就是
$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_period_us
100000
$ cat /sys/fs/cgroup/cpu/docker/5d5c9f67d/cpu.cfs_quota_us
20000
namespace进行障眼法隔离,linux cgroups实现资源限制。
一个docker容器就是启动了linux namespace的应用进程,而这个进程能够使用的资源受cgroups限制的。
容器是一个单进程模型
容器里一个应用。进程的PID=1,好维护,后期k8s调度也方便
容器里一个应用且PID=1,就是要容器和业务应用同生命周期,这对后期K8S编排非常重要。以防出现“容器是正常运行,应用挂了的情况出现”,这样编排系统处理非常麻烦了
cgroups不完善的地方,/proc 存储了内核的特殊文件,用户可以访问这些文件,top指令查看资源情况,的数据来源。proc文件系统不知道通过通过cgroups对容器做了什么限制,
用户看到的top是宿主机的top结果
生产中必须要fix这个问题。要不可能会有问题。
(lxcfs)
标签:top mkdir res proc文件 一段 period uid 种类 control
原文地址:https://www.cnblogs.com/PythonOrg/p/14894790.html