在 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 提供了一个灵活的资源管理机制,确保容器在集群中的资源使用是可控的,并且能够避免资源过度消耗或浪费。