在 Kubernetes 中,Pod 的资源限制(request 和 limit)主要是通过 cgroup 来实现的,request 和 limit 的值会直接映射到容器的 cgroup 配置中,控制容器使用的资源(CPU 和内存)。这些限制是在容器运行时通过 容器运行时 (如 Docker、containerd 等)和 Linux cgroup 系统实现的。
1. 请求资源(request)与限制资源(limit)的定义
- request :容器在调度时请求的资源量(CPU 或内存)。它表示 Pod 在集群中调度时需要的最低资源量。如果一个 Pod 没有设置
request,则调度器可能会将 Pod 放置到资源充足的节点上,但不会强制资源保证。 - limit :容器能够使用的最大资源量。如果容器请求超过
limit的资源,Linux 内核会限制容器的资源使用(例如,通过 OOM Killer 来终止过度占用内存的容器)。limit限制的是容器的资源上限,防止单个容器占用过多资源,影响其他容器。
2. 底层原理:cgroup 和容器运行时
容器通过 cgroup(Control Groups)来实现资源的隔离和限制。cgroup 是 Linux 内核的一个特性,用来限制、控制和监视进程的资源使用。
2.1 cgroup 和 Kubernetes 中的资源限制
- CPU 限制 :容器的
request和limit会被转换为 cgroup 中的 CPU 配额。例如,如果容器的request设置为 1 CPU,limit设置为 2 CPU,cgroup 会为该容器分配 1 个 CPU 的请求资源,并且限制它最多只能使用 2 个 CPU 的资源。 - 内存限制 :容器的内存
request和limit会对应到 cgroup 的内存子系统(memory),指定容器可用的最小和最大内存。当容器使用的内存超过了limit,会触发 OOM(Out of Memory)情况,内核会根据limit设置对容器进行杀掉或限制。
2.2 容器运行时如何应用 request 和 limit
容器运行时(如 Docker 或 containerd)负责启动容器,并将 request 和 limit 转换为 cgroup 的配置。具体实现过程如下:
-
容器启动时 :容器运行时读取 Pod 配置中的
request和limit值,并将其映射到相应的 cgroup 设置中。比如,对于 CPU 限制,Docker 会使用 cgroup 的cpu.cfs_quota_us和cpu.cfs_period_us来限制 CPU 使用。- CPU 请求 (request):容器的
request会被转换为cpu.cfs_quota_us,表示容器在调度时需要的 CPU 资源。 - CPU 限制 (limit):容器的
limit会被转换为cpu.cfs_quota_us,表示容器的最大 CPU 配额。
- CPU 请求 (request):容器的
-
资源管理:
- CPU:容器的 CPU 使用会受到 cgroup 的管理,容器的 CPU 使用会被限制在指定的配额范围内。
- 内存 :内存限制是通过 cgroup 的
memory.limit_in_bytes来实现的。如果容器请求的内存超过limit,容器将被杀死(OOM)。
-
容器资源超限:
-
当容器超出
bashlimit资源时,Linux 内核会根据资源类型采取不同的策略:
- CPU 限制 :如果容器使用的 CPU 超过了设置的
limit,容器会被限制只能使用一定量的 CPU 时间,无法进一步占用更多 CPU。 - 内存限制 :如果容器的内存使用超出了
limit,Linux 内核会通过 OOM(Out Of Memory)机制来终止该容器,以保证系统的稳定性。
- CPU 限制 :如果容器使用的 CPU 超过了设置的
-
2.3 Linux Cgroup 实现方式
在 Linux 内核中,资源限制是通过 cgroup(控制组)实现的。cgroup 用于限制、控制和监控进程的资源使用,包括 CPU、内存、磁盘 I/O 等。
-
CPU 限制 :cgroup 通过
cpu.cfs_quota_us和cpu.cfs_period_us设置 CPU 配额。cpu.cfs_period_us:设置 CPU 周期的总时长(默认是 100ms)。cpu.cfs_quota_us:设置容器在周期内允许使用的最大时间(默认是 -1,表示没有限制)。比如,如果设定为 50000 微秒,容器每个周期只能使用 50ms 的 CPU。
-
内存限制 :cgroup 使用
memory.limit_in_bytes来限制容器的最大内存使用量。如果容器的内存超过了limit,内核会触发 OOM(Out of Memory)机制,杀死进程。
3. 调度器如何使用 request 和 limit
在 Kubernetes 中,调度器 会根据 Pod 的 request 来选择合适的节点进行调度。调度器会确保节点有足够的资源(CPU、内存)来满足 Pod 的 request,同时避免超出节点的资源限制。
- request :调度时参考 Pod 的
request,确保节点有足够的资源来调度 Pod。request是保证 Pod 最低可以获得的资源。 - limit :
limit不会影响调度过程,但会影响容器的资源使用。容器的实际资源使用不能超过limit,否则会被操作系统限制或杀死。
4. 总结
在 Kubernetes 中,request 和 limit 是通过 Linux cgroup 来实现资源控制的:
- request 表示容器请求的最低资源量,会影响调度时选择节点的过程。
- limit 表示容器可以使用的最大资源量,超过这个限制会导致容器被限制或杀死。
- cgroup 是实现这些限制的底层机制,它通过限制 CPU 配额、内存限制等来控制容器的资源使用。
通过 request 和 limit,Kubernetes 提供了一个灵活的资源管理机制,确保容器在集群中的资源使用是可控的,并且能够避免资源过度消耗或浪费。