如何在Pod内获取核心数量

0 投票
1 回答
39 浏览
提问于 2025-04-14 15:20

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

撰写回答