如何在Pod内获取核心数量
Kubernetes 让我们可以为一个 pod 设置 CPU 和内存的使用限制。有人想知道有没有办法在 pod 内部获取这些 CPU 的请求和限制,而不需要使用 kubectl
这个命令行工具。
1 个回答
0
Kubernetes 使用 cgroups 来设置和执行资源限制。cgroups 有两个版本:
- cgroups V1
- cgroups V2
在 cgroups V1 中,可以通过读取配额(Quota,简称 Q)和周期(Period,简称 P)来计算可用的核心数。具体的计算公式是 cores = math.ceil(Q / P)
。你可以在以下路径找到相关信息:
- /sys/fs/cgroup/cpu/cpu.cfs_quota_us
- /sys/fs/cgroup/cpu/cpu.cfs_period_us
在 cgroups V2 中,cpu.cfs_period_us 和 cpu.cfs_quota_us 的对应文件是 cpu.max。通常可以在 /sys/fs/cgroup/cpu.max
找到这个文件,文件的格式可以参考 cgroup-v2.txt。这个文件里包含了配额(Q)和周期(P),它们之间用空格分开。如果没有设置 CPU 限制,配额会被设置为 max
,计算核心数的公式还是一样的,cores = math.ceil(Q / P)
。
下面是 Python3 的代码:
import typing
import multiprocessing
from pathlib import Path
def get_cpu_cores_via_cgroups() -> typing.Optional[int]:
# cgroups V1
cfs_period_path = "/sys/fs/cgroup/cpu/cpu.cfs_period_us"
cfs_quota_path = "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"
# cgroups V2
cpu_max_path = "/sys/fs/cgroup/cpu.max"
cpu_cores = _get_cpu_cores(cfs_period_path, cfs_quota_path, cpu_max_path)
return cpu_cores
def _get_cpu_cores(cfs_period_path: str, cfs_quota_path: str, cpu_max_path: str) -> typing.Optional[int]:
cpu_cores = None
cfs_period = Path(cfs_period_path)
cfs_quota = Path(cfs_quota_path)
if cfs_period.exists() and cfs_quota.exists():
with cfs_period.open("rb") as fp_p, cfs_quota.open("rb") as fp_q: # we are in a linux container with cpu quotas!
p, q = int(fp_p.read()), int(fp_q.read())
# get the cores allocated by dividing the quota in microseconds by the period in microseconds
cpu_cores = math.ceil(q / p) if q > 0 and p > 0 else None
else:
cpu_max = Path(cpu_max_path)
if cpu_max.exists():
line = cpu_max.read_text()
cpu_cores = cpu_cores_from_cgroups_v2_cpu_max(line)
return cpu_cores
def cpu_cores_from_cgroups_v2_cpu_max(line: str) -> typing.Optional[int]:
cpu_cores = None
parts = line.split(" ")
if len(parts) == 2:
# Check whether there is no limit set for CPU
if parts[0] == "max":
return multiprocessing.cpu_count()
# The first value is the allowed time quota in microseconds for which all processes collectively in
# a child group can run during one period.
q = int(parts[0])
# The second value specifies the length of the period.
p = int(parts[1])
cpu_cores = math.ceil(q / p) if q > 0 and p > 0 else None
return cpu_cores