【探索 Kubernetes|容器基础进阶篇 系列 2】容器资源限制利器

简介: 【探索 Kubernetes|容器基础进阶篇 系列 2】容器资源限制利器

关于作者


大家好,我是秋意零。

😈 CSDN作者主页

👿 简介

  • 👻 普通本科生在读
  • 在校期间参与众多计算机相关比赛,如:🌟 “省赛”、“国赛”,斩获多项奖项荣誉证书
  • 🔥 各个平台,秋意零 账号创作者
  • 🔥 云社区 创建者
点赞、收藏+关注下次不迷路!

欢迎加入云社区


回顾

上一章提到,容器本质是一个进程,通过 Linux 系统 NameSpace 技术实现资源隔离(障眼法),通过它修改了进程看待整个操作系统“视角”,只能看到某些指定的内容。

一、Docker Engine 和 Hypervisor 区别

  • 在之前虚拟机与容器技术的对比图中,不应该把 Docker Engine(或其他容器管理工具) 跟 Hypervisor 放在相同的位置,因为 Hypervisor 是对创建出来的虚拟机隔离环境负责,而 Docker Engine(或其他容器管理工具)是借助宿主机本身 NameSpace 实现的
  • 所以应该把 Docker Engine(或其他容器管理工具)放在和宿主机其他应用程序同级别的位置。都是宿主机统一管理,只不过这些进程设置了 Namespace 参数。而 Docker 在这里,更多的是辅助和管理

二、容器比虚拟机受欢迎?

优势

  • 因为虚拟机必须包含一个操作系统,进而让应用进程运行在这个虚拟机操作系统之上,这就不可避免地带来了额外的资源消耗和占用
  • 根据实验,一个运行着 CentOS 的 KVM 虚拟机启动后,在不做优化的情况下,虚拟机自己就需要占用 100~200 MB 内存。此外,用户应用运行在虚拟机里面,它对宿主机操作系统的调用就不可避免地要经过虚拟化软件的拦截和处理,这本身又是一层性能损耗,尤其对计算资源、网络和磁盘 I/O 的损耗非常大。
  • 相对于容器,这些消耗和占用都是不存在的,所以 ** “敏捷”和“高性能”是容器相较于虚拟机最大的优势 ** 。

劣势

隔离不彻底

不过,有利就有弊,基于 Linux Namespace 的隔离机制相比于虚拟化技术也有很多不足之处,其中最主要的问题就是:隔离得不彻底。如果你要在 Windows 宿主机上运行 Linux 容器,或者在低版本的 Linux 宿主机上运行高版本的 Linux 容器,都是行不通的。

安全问题

因为共享宿主机内核,容器中的应用暴露出来的攻击面就很大,所以生产环境中,没有人敢把运行在宿主机上的容器直接暴露到公网上。

三、Linux Cgroups 限制

虽然对容器的进程使用了 NameSpace 技术,但是对于宿主机上的进程和容器进程是处于同等级别的资源竞争关系。这就意味着,比如 100 号进程表面被隔离起来了,但是它还是会使用到宿主机上的资源(CPU、内存),也会被其他宿主机上的进程强占用资源,当然自己这个 100 号进程也有可能把所有资源吃光。这时就需要使用 Linux Cgroups 进行资源限制。

  • Linux Cgroups 就是 Linux 内核中用来为进程设置资源限制的一个重要功能。
  • Linux Cgroups 的全称是 Linux Control Group。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

Linux 中,Cgroups 给用户暴露出来的操作接口是文件系统,它以文件和目录的方式组织在 /sys/fs/cgroup 路径下,我们可以使用 mount -t 命令展现出来

[root@master ~]# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)

可以看到,在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录,也叫子系统。这些是可以被 Cgroups 进行限制的资源种类。

[root@master ~]# ll /sys/fs/cgroup/
total 0
drwxr-xr-x 5 root root  0 May 18 15:09 blkio
lrwxrwxrwx 1 root root 11 May 18 15:09 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 May 18 15:09 cpuacct -> cpu,cpuacct
drwxr-xr-x 5 root root  0 May 18 15:09 cpu,cpuacct
drwxr-xr-x 3 root root  0 May 18 15:09 cpuset
drwxr-xr-x 5 root root  0 May 18 15:09 devices
drwxr-xr-x 3 root root  0 May 18 15:09 freezer
drwxr-xr-x 3 root root  0 May 18 15:09 hugetlb
drwxr-xr-x 5 root root  0 May 18 15:09 memory
lrwxrwxrwx 1 root root 16 May 18 15:09 net_cls -> net_cls,net_prio
drwxr-xr-x 3 root root  0 May 18 15:09 net_cls,net_prio
lrwxrwxrwx 1 root root 16 May 18 15:09 net_prio -> net_cls,net_prio
drwxr-xr-x 3 root root  0 May 18 15:09 perf_event
drwxr-xr-x 5 root root  0 May 18 15:09 pids
drwxr-xr-x 5 root root  0 May 18 15:09 systemd

在子系统对应的资源种类下,你就可以看到该类资源具体可以被限制的方法。

  • cpu.cfs_period_us :限制进程在某一段时间内
  • cpu.cfs_quota_us :只能被分配到总量为某一段 CPU 时间
[root@master ~]# ls /sys/fs/cgroup/cpu,cpuacct/
cgroup.clone_children  cpuacct.stat          cpu.cfs_quota_us   cpu.stat           system.slice
cgroup.event_control   cpuacct.usage         cpu.rt_period_us   kubepods.slice     tasks
cgroup.procs           cpuacct.usage_percpu  cpu.rt_runtime_us  notify_on_release  user.slice
cgroup.sane_behavior   cpu.cfs_period_us     cpu.shares         release_agent

使用 Cgroups 子系统配置文件

- 前提知识

我们在 /sys/fs/cgroup/cpu 目录下创建一个 container 目录,这个目录被称为“控制组”,操作系统会在你新创建的 container 目录下,自动生成该子系统对应的资源限制文件。

$ cd /sys/fs/cgroup/cpu
$ mkdir container
#自动生成该子系统对应的资源限制文件。
$ ls container/
cgroup.clone_children  cpuacct.usage         cpu.rt_period_us   notify_on_release
cgroup.event_control   cpuacct.usage_percpu  cpu.rt_runtime_us  tasks
cgroup.procs           cpu.cfs_period_us     cpu.shares
cpuacct.stat           cpu.cfs_quota_us      cpu.stat

后台运行 while 死循环,并返回改进程号(PID)是 98158,也可以使用 jobs 命令查看后台进程号(PID)是多少

$ while : ; do : ; done &
[1] 98158
$ jobs -l
[1]+ 98158 Running                 while :; do
    :;
done &

使用 top 命令,可以看到 CPU 利用率,可以把我 2核 CPU 占用了 50%

$ top
%Cpu(s): 50.0 us,  3.1 sy,  0.0 ni, 46.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

现在我们查看 container 目录下的 cpu.cfs_quota_us 文件默认内容是 -1 表示没有任何限制, cpu.cfs_period_us 文件默认内容是 100000 us(100ms)

[root@test_2 cpu]# cat /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
-1
[root@test_2 cpu]# cat /sys/fs/cgroup/cpu/container/cpu.cfs_period_us
100000

- 限制

我们可以通过修改上诉两个文件内容,来限制某个进程 cpu 利用率

向 container 组里的 cpu.cfs_quota_us 文件写入 10000 us (10ms),这意味着每 100 ms 的时间里,被改控制组限制的进程只能使用 10 ms 的 CPU 时间,也就是说只能使用到 10% 的 CPU 带宽。

[root@test_2 cpu]# echo 10000 > /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us

我们把限制的进程 PID 写入 container 组里的 tasks 文件,这样能对该进程进行限制了

$ echo 98158 > /sys/fs/cgroup/cpu/container/tasks

可以看到之前的 CPU 使用率为 50%,现在为 5.2%,在 50%的基础上,使用率只要 10% 了,也就是 5%

$ top
%Cpu(s):  5.2 us,  0.5 sy,  0.0 ni, 94.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

对于容器来说,它在 system.slice 子系统下面,为每个容器创建以 docker-容器id.scope 命名为规则的目录,容器启动进程之后,把这个进程的 PID 填写到对于的控制组的 tasks 文件即可。

$ docker run -dit --cpu-period=100000 --cpu-quota=20000 --name=qyl_centos  centos
e2a823c812f71c594990308a06c5c4c805a2285851c0418ab086e366ef8006c5
$ ls /sys/fs/cgroup/cpu,cpuacct/system.slice/docker-e2a823c812f71c594990308a06c5c4c805a2285851c0418ab086e366ef8006c5.scope
cgroup.clone_children  cpuacct.stat          cpu.cfs_period_us  cpu.rt_runtime_us  notify_on_release
cgroup.event_control   cpuacct.usage         cpu.cfs_quota_us   cpu.shares         tasks
cgroup.procs           cpuacct.usage_percpu  cpu.rt_period_us   cpu.stat

查看 qyl_centos 容器的 PID 是多少,这里可以看到是 1822

[root@master01 ~]# docker top qyl_centos
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                1822                1801                0                   15:54               pts/0               00:00:00            /bin/bash

查看 tasks 文件中进程 PID,可以看到是 1822,与上述 qyl_centos 容器 PID 一致

$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/docker-e2a823c812f71c594990308a06c5c4c805a2285851c0418ab086e366ef8006c5.scope/tasks
1822

也可以看 cpu.cfs_period_uscpu.cfs_quota_us 是和 docker run 运行容器时限制一致

$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/docker-e2a823c812f71c594990308a06c5c4c805a2285851c0418ab086e366ef8006c5.scope/cpu.cfs_period_us
100000
$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/docker-e2a823c812f71c594990308a06c5c4c805a2285851c0418ab086e366ef8006c5.scope/cpu.cfs_quota_us
20000

✊ 最后


👏 我是秋意零,欢迎大家一键三连、加入云社区

👋 我们下期再见(⊙o⊙)!!!

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
6天前
|
存储 Kubernetes C++
【专栏】Kubernetes VS Docker Swarm了解两者特点,助力选取合适容器编排工具
【4月更文挑战第27天】对比Kubernetes和Docker Swarm:K8s在可扩展性和自动化方面出色,有强大社区支持;Swarm以简易用著称,适合初学者。选择取决于项目需求、团队技能和预期收益。高度复杂项目推荐Kubernetes,快速上手小项目则选Docker Swarm。了解两者特点,助力选取合适容器编排工具。
|
1天前
|
存储 弹性计算 Kubernetes
【阿里云云原生专栏】深入解析阿里云Kubernetes服务ACK:企业级容器编排实战
【5月更文挑战第20天】阿里云ACK是高性能的Kubernetes服务,基于开源Kubernetes并融合VPC、SLB等云资源。它提供强大的集群管理、无缝兼容Kubernetes API、弹性伸缩、安全隔离及监控日志功能。用户可通过控制台或kubectl轻松创建和部署应用,如Nginx。此外,ACK支持自动扩缩容、服务发现、负载均衡和持久化存储。多重安全保障和集成监控使其成为企业云原生环境的理想选择。
112 3
|
4天前
|
存储 Java Serverless
ACK One Argo 工作流集群:玩转容器对象存储
ACK One Argo 工作流集群:玩转容器对象存储
ACK One Argo 工作流集群:玩转容器对象存储
|
4天前
|
存储 Kubernetes 监控
使用Kubernetes进行容器编排:技术详解与实践
【5月更文挑战第16天】Kubernetes,简称K8s,是开源容器编排系统,用于自动化部署、扩展和管理容器化应用。核心概念包括节点、Pod(最小部署单元)、服务、标签和副本集。其特点有高可用性、可扩展性、自动化和可移植性。实践使用涉及安装配置集群、编写YAML部署清单、应用部署、监控管理和扩展更新。Kubernetes帮助提升应用的可用性、可扩展性和可移植性。
|
5天前
|
运维 Kubernetes Shell
Kubernetes详解(十二)——节点选择器与资源注解
Kubernetes详解(十二)——节点选择器与资源注解
21 2
|
6天前
|
分布式计算 Kubernetes 监控
容器服务Kubernetes版产品使用合集之怎么实现把 spark 跑在k8s
容器服务Kubernetes版,作为阿里云提供的核心服务之一,旨在帮助企业及开发者高效管理和运行Kubernetes集群,实现应用的容器化与微服务化。以下是关于使用这些服务的一些建议和合集,涵盖基本操作、最佳实践、以及一些高级功能的使用方法。
28 1
|
6天前
|
运维 Kubernetes Linux
Kubernetes详解(九)——资源配置清单创建Pod实战
Kubernetes详解(九)——资源配置清单创建Pod实战
20 2
|
6天前
|
JSON Kubernetes API
Kubernetes详解(八)——Kubernetes资源配置清单
Kubernetes详解(八)——Kubernetes资源配置清单
14 2
|
6天前
|
存储 Kubernetes 关系型数据库
Kubernetes详解(二)——Kubernetes结构与资源对象
Kubernetes详解(二)——Kubernetes结构与资源对象
20 0
|
6天前
|
Kubernetes Java 调度
Java容器技术:Docker与Kubernetes
Java容器技术:Docker与Kubernetes
40 0

推荐镜像

更多