您可以使用 Linux cgroups API,让 Google Kubernetes Engine (GKE) 工作负载管理子进程的资源(例如 CPU 和内存)。本文档介绍了如何为容器提供对 cgroups API 的读写权限,而无需以特权模式运行这些容器。
何时使用可写入的 cgroup
默认情况下,Kubernetes 通过在每个容器中装载 /sys/fs/cgroup 文件系统,为所有 Linux 容器提供对 cgroups API 的只读访问权限。您可以选择让 GKE 以读写模式在特定 Pod 中装载此文件系统,以便根进程管理和限制子进程的资源。
这些可写入的 cgroup 有助于提高在同一容器中运行系统进程和用户代码的应用(例如 Ray)的可靠性。通过写入 /sys/fs/cgroup 文件系统,Ray 可以为关键进程预留容器的部分资源。您可以使用可写入的 cgroup 来提高这些应用的可靠性,而不会因使用容器的特权模式而带来安全风险。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
- 确保您拥有运行 1.34.1-gke.2541000 版或更高版本的 Autopilot 或 Standard 集群。如需创建新集群,请参阅创建 Autopilot 集群。
- 确保您的集群使用 cgroup v2。如需了解详情,请参阅将节点迁移到 Linux cgroup v2。
为节点启用可写入的 cgroup
通过自定义 containerd 配置,在节点池上启用可写入的 cgroup。您可以将此配置应用于整个集群,也可以应用于 Standard 集群中的特定节点池。
在 containerd 配置文件中,添加 writableCgroups 部分并将 enabled 字段设置为 true。如需了解详情,请参阅在 GKE 节点中自定义 containerd 配置。
writableCgroups:
enabled: true
在创建或更新集群或节点池时,指定更新后的配置文件。
在工作负载中使用可写入的 cgroup
为集群或节点池启用可写入的 cgroup 后,请配置工作负载以满足以下所有要求:
- 选择已启用可写入 cgroup 的节点。
- 为 Pod 中的一个或多个容器启用可写入的 cgroup。
通过满足以下任一条件,使用有保证的服务质量 (QoS) 类:
- 对于在 Pod 级指定资源的工作负载,请在 Pod 规范中为
resources.requests和resources.limits设置相同的值。 - 对于为每个容器指定资源的工作负载,请在 Pod 中每个容器(包括 init 容器)的规范中为
resources.requests和resources.limits设置相同的值。
- 对于在 Pod 级指定资源的工作负载,请在 Pod 规范中为
如需配置这些要求,请按以下步骤操作:
如需选择启用了可写入 cgroup 的节点,请将
node.gke.io/enable-writable-cgroups: "true"标签添加到 Pod 规范的spec.nodeSelector字段中:node.gke.io/enable-writable-cgroups: "true"如需为工作负载启用可写入的 cgroup,请将以下标签之一添加到 Pod 规范的
metadata.annotations字段中:为整个 Pod 启用:
node.gke.io/enable-writable-cgroups: "true"为 Pod 中的特定容器启用:
node.gke.io/enable-writable-cgroups.CONTAINER_NAME: "true"将
CONTAINER_NAME替换为容器的名称。
如需为 Pod 配置有保证的 QoS 类,请为 Pod 中的每个容器或整个 Pod 指定相等的 CPU 和内存请求与限制,如以下示例所示:
resources: requests: cpu: "100m" memory: "100Mi" limits: cpu: "100m" memory: "100Mi"您必须为每个容器指定相同的请求和限制,即使您仅为 Pod 中的一个容器启用可写入的 cgroup 也是如此。
最终 Pod 规范应类似于以下示例。
此示例为 Pod 中的所有容器启用可写入的 cgroup:
apiVersion: v1 kind: Pod metadata: name: writable-cgroups-pod annotations: node.gke.io/enable-writable-cgroups: "true" spec: nodeSelector: node.gke.io/enable-writable-cgroups: "true" containers: - name: container image: busybox:stable command: ["/bin/sh", "-c"] args: - | trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM echo "Waiting for termination signal..." while true; do sleep 1; done resources: requests: cpu: "100m" memory: "100Mi" limits: cpu: "100m" memory: "100Mi"此示例为多容器 Pod 中的特定容器启用可写入的 cgroup:
apiVersion: v1 kind: Pod metadata: name: writable-cgroups-per-container annotations: node.gke.io/enable-writable-cgroups.busybox-container: "true" spec: nodeSelector: node.gke.io/enable-writable-cgroups: "true" containers: - name: busybox-container image: busybox:stable command: ["/bin/sh", "-c"] args: - | trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM echo "Waiting for termination signal..." while true; do sleep 1; done resources: requests: cpu: "100m" memory: "100Mi" limits: cpu: "100m" memory: "100Mi" - name: container-disabled image: busybox:stable command: ["/bin/sh", "-c"] args: - | trap 'echo "Caught SIGTERM, exiting..."; exit 0' TERM echo "Waiting for termination signal..." while true; do sleep 1; done resources: requests: cpu: "100m" memory: "100Mi" limits: cpu: "100m" memory: "100Mi"
验证 cgroup 文件系统是否可写入
如需验证 Pod 或容器的 /sys/fs/cgroup 文件系统上的权限,请按以下步骤操作:
- 确定要检查的 Pod。您可以使用在工作负载中使用可写入的 cgroup 部分中的某个示例 Pod。
在 Pod 中创建 shell 会话:
kubectl exec -it POD_NAME -- /bin/sh将
POD_NAME替换为 Pod 的名称。描述已挂载的 cgroup 文件系统:
mount | grep cgroup输出类似于以下内容:
cgroup on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)在此输出中,
rw表示文件系统可写入。如果您在输出中看到ro,则表示文件系统处于只读状态。