任务

任务
管理集群
Debug DNS 方案
Enabling Service Topology (EN)
IP Masquerade Agent 用户指南
Kubernetes 云管理控制器
Safely Drain a Node while Respecting the PodDisruptionBudget (EN)
为 Kubernetes 运行 etcd 集群
为系统守护进程预留计算资源
为节点发布扩展资源
使用 CoreDNS 进行服务发现
使用 KMS 提供商进行数据加密
使用 Kubernetes API 访问集群
关键插件 Pod 的调度保证
启用端点切片
命名空间演练
在 Kubernetes 集群中使用 NodeLocal DNSCache
在 Kubernetes 集群中使用 sysctl
在实时集群上重新配置节点的 Kubelet
声明网络策略
开发云控制器管理器
控制节点上的 CPU 管理策略
控制节点上的拓扑管理策略
搭建高可用的 Kubernetes Masters
改变默认 StorageClass
更改 PersistentVolume 的回收策略
自定义 DNS 服务
访问集群上运行的服务
通过命名空间共享集群
通过配置文件设置 Kubelet 参数
配置 API 对象配额
配置多个调度器
配置资源不足时的处理方式
限制存储消耗
集群 DNS 服务自动伸缩
集群安全
集群管理
静态加密 Secret 数据
用插件扩展 kubectl
管理巨页(HugePages)
调度 GPUs

Edit This Page

调度 GPUs

Kubernetes 支持对节点上的 AMD 和 NVIDA GPU 进行管理,目前处于实验状态。对 NVIDIA GPU 的支持在 v1.6 中加入,已经经历了多次不向后兼容的迭代。而对 AMD GPU 的支持则在 v1.9 中通过 设备插件 加入。

这个页面介绍了用户如何在不同的 Kubernetes 版本中使用 GPU,以及当前存在的一些限制。

从 v1.8 起

从 1.8 版本开始,我们推荐通过 设备插件 的方式来使用 GPU。

在 1.10 版本之前,为了通过设备插件开启 GPU 的支持,我们需要在系统中将 DevicePlugins 这一特性开关显式地设置为 true:--feature-gates="DevicePlugins=true"。不过, 从 1.10 版本开始,我们就不需要这一步骤了。

接着你需要在主机节点上安装对应厂商的 GPU 驱动并运行对应厂商的设备插件 (AMDNVIDIA)。

当上面的条件都满足,Kubernetes 将会暴露 nvidia.com/gpuamd.com/gpu 来作为 一种可调度的资源。

你也能通过像请求 cpumemory 一样请求 <vendor>.com/gpu 来在容器中使用 GPU。然而,当你要通过指定资源请求来使用 GPU 时,存在着以下几点限制:

  • GPU 仅仅支持在 limits 部分被指定,这表明:
    • 你可以仅仅指定 GPU 的 limits 字段而不必须指定 requests 字段,因为 Kubernetes 会默认使用 limit 字段的值来作为 request 字段的默认值。
    • 你能同时指定 GPU 的 limitsrequests 字段,但这两个值必须相等。
    • 你不能仅仅指定 GPU 的 request 字段而不指定 limits
  • 容器(以及 pod)并不会共享 GPU,也不存在对 GPU 的过量使用。
  • 每一个容器能够请求一个或多个 GPU。然而只请求一个 GPU 的一部分是不允许的。

下面是一个例子:

apiVersion: v1
kind: Pod
metadata:
  name: cuda-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: cuda-vector-add
      # https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
      image: "k8s.gcr.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1 # requesting 1 GPU

部署 AMD GPU 设备插件

官方的 AMD GPU 设备插件 有以下要求:

  • Kubernetes 节点必须预先安装 AMD GPU 的 Linux 驱动。

如果你的集群已经启动并且满足上述要求的话,可以这样部署 AMD 设备插件:

# 针对 Kubernetes v1.9
kubectl create -f https://raw.githubusercontent.com/RadeonOpenCompute/k8s-device-plugin/r1.9/k8s-ds-amdgpu-dp.yaml

# 针对 Kubernetes v1.10
kubectl create -f https://raw.githubusercontent.com/RadeonOpenCompute/k8s-device-plugin/r1.10/k8s-ds-amdgpu-dp.yaml

请到 RadeonOpenCompute/k8s-device-plugin 报告有关此设备插件的问题。

部署 NVIDIA GPU 设备插件

对于 NVIDIA GPUs,目前存在两种设备插件的实现:

官方的 NVIDIA GPU 设备插件

官方的 NVIDIA GPU 设备插件 有以下要求:

  • Kubernetes 的节点必须预先安装了 NVIDIA 驱动
  • Kubernetes 的节点必须预先安装 nvidia-docker 2.0
  • Docker 的默认运行时必须设置为 nvidia-container-runtime,而不是 runc
  • NVIDIA 驱动版本 ~= 361.93

如果你的集群已经启动并且满足上述要求的话,可以这样部署 NVIDIA 设备插件:

# 针对 Kubernetes v1.8
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.8/nvidia-device-plugin.yml

# 针对 Kubernetes v1.9
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.9/nvidia-device-plugin.yml

请到 NVIDIA/k8s-device-plugin 报告有关此设备插件的问题。

GCE 中使用的 NVIDIA GPU 设备插件

GCE 使用的 NVIDIA GPU 设备插件 并不要求使用 nvidia-docker,并且对于任何实现了 Kubernetes CRI 的容器运行时,都应该能够使用。这一实现已经在 Container-Optimized OS 上进行了测试,并且在 1.9 版本之后会有对于 Ubuntu 的实验性代码。

在你 1.12 版本的集群上,你能使用下面的命令来安装 NVIDIA 驱动以及设备插件:

# 在容器优化的操作系统上安装 NVIDIA 驱动:
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/stable/daemonset.yaml

# 在 Ubuntu 上安装 NVIDIA 驱动 (实验性质):
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/stable/nvidia-driver-installer/ubuntu/daemonset.yaml

# 安装设备插件:
kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes/release-1.12/cluster/addons/device-plugins/nvidia-gpu/daemonset.yaml

请到 GoogleCloudPlatform/container-engine-accelerators 报告有关此设备插件以及安装方法的问题。

集群内存在不同类型的 NVIDIA GPU

如果集群内部的不同节点上有不同类型的 NVIDIA GPU,那么你可以使用 节点标签和节点选择器 来将 pod 调度到合适的节点上。

例如:

# 为你的节点加上它们所拥有的加速器类型的标签
kubectl label nodes <node-with-k80> accelerator=nvidia-tesla-k80
kubectl label nodes <node-with-p100> accelerator=nvidia-tesla-p100

对于 AMD GPUs,您可以部署 节点标签器,它会自动给节点打上 GPU 属性标签。目前支持的属性:

  • 设备 ID (-device-id)
  • VRAM 大小 (-vram)
  • SIMD 数量(-simd-count)
  • 计算单位数量(-cu-count)
  • 固件和特性版本 (-firmware)
  • GPU 系列,两个字母的首字母缩写(-family)
    • SI - Southern Islands
    • CI - Sea Islands
    • KV - Kaveri
    • VI - Volcanic Islands
    • CZ - Carrizo
    • AI - Arctic Islands
    • RV - Raven

示例:

$ kubectl describe node cluster-node-23
Name:               cluster-node-23
Roles:              <none>
Labels:             beta.amd.com/gpu.cu-count.64=1
                    beta.amd.com/gpu.device-id.6860=1
                    beta.amd.com/gpu.family.AI=1
                    beta.amd.com/gpu.simd-count.256=1
                    beta.amd.com/gpu.vram.16G=1
                    beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/hostname=cluster-node-23
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
......

在 pod 的 spec 字段中指定 GPU 的类型:

apiVersion: v1
kind: Pod
metadata:
  name: cuda-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: cuda-vector-add
      # https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
      image: "k8s.gcr.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1
  nodeSelector:
    accelerator: nvidia-tesla-p100 # or nvidia-tesla-k80 etc.

这能够保证 pod 能够被调度到你所指定类型的 GPU 的节点上去。

反馈