在Kubernetes集群中实现共享GPU调度(GPUshare)

问题背景

Kubernetes 集群中,GPU资源作为一种外部资源(extended resources),部署Nvidia官方提供的插件(k8s-device-plugin)后,GPU资源在节点上是以个数暴露给kubernetes集群来进行调度的,也就是说如果有两个后端应用pod需要使用到GPU资源,但集群节点上只有一张GPU物理卡的情况下,会导致两个后端应用容器中仅有一个可以正常运行,另一个pod则会处于pending状态。

想要在Kubenentes集群中实现GPUshare,可以采用阿里云于2019年开源的gpushare-device-plugin

The Nvidia GPU sharing device plugin for Kubernetes is a Daemonset that allows you to automatically:

  • Expose the GPU Memory and GPU count on the node of your cluster // 将节点上的GPU资源以显存及显卡数的形式暴露给k8s
  • Run GPU sharing enabled containers in your Kubernetes cluster. //集群中的容器可以通过声明显存来共享GPU资源
    For more info, please refer gpusharing scheduler extender

本文用来记录部署gpushare-device-plugin 插件的过程及遇到的问题。

目标

将节点上的GPU资源以GPU显存或者GPU个数的形式暴露给Kubernetes,实现多容器共享GPU资源。

设计原则

一个outoftree的共享GPU调度方案,该方案依赖于Kubernetes的现有工作机制:

  1. Extended Resource定义
  2. Scheduler Extender机制
  3. Device Plugin机制
gpushare1.png

部署

官方安装向导

0. 准备 GPU Node

安装 gpushare-device-plugin 之前,确保在GPU节点上已经安装Nvidia-Driver以及Nvidia-Docker2,同时已将docker的默认运行时设置为nvidia,配置文件如下:/etc/docker/daemon.json

{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

1. 部署 GPU share scheduler extender

cd /etc/kubernetes/
curl -O https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/config/scheduler-policy-config.json
cd /tmp/
curl -O https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/config/gpushare-schd-extender.yaml
kubectl create -f gpushare-schd-extender.yaml

2. 修改 scheduler 配置文件

/etc/kubernetes/scheduler-policy-config.json 加到 scheduler 配置文件中(/etc/kubernetes/manifests/kube-scheduler.yaml).
这是一个成功添加配置的例子 kube-scheduler.yaml

注意: 如果当前 Kubernetes 的默认 scheduler 是以静态pod的方式部署的, 不要在这个路径下编辑配置文件 /etc/kubernetes/manifest. 应该在该路径外编辑 yaml 文件后将其复制到 '/etc/kubernetes/manifest/' 路径下, 然后Kubernetes 会自动更新 scheduler.

2.1 在 scheduler 参数中加入 Policy config file 参数

- --policy-config-file=/etc/kubernetes/scheduler-policy-config.json

2.2 在 Pod Spec 中加入 volume mount

- mountPath: /etc/kubernetes/scheduler-policy-config.json
  name: scheduler-policy-config
  readOnly: true
- hostPath:
      path: /etc/kubernetes/scheduler-policy-config.json
      type: FileOrCreate
  name: scheduler-policy-config

3. 部署Device Plugin

wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-rbac.yaml
kubectl create -f device-plugin-rbac.yaml
wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-ds.yaml
kubectl create -f device-plugin-ds.yaml

可以通过修改DaemonSet中的参数来指定显存的单位是MiB/GiB

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: gpushare-device-plugin-ds
  namespace: kube-system
spec:
  selector:
    matchLabels:
        component: gpushare-device-plugin
        app: gpushare
        name: gpushare-device-plugin-ds
  template:
    metadata:
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ""
      labels:
        component: gpushare-device-plugin
        app: gpushare
        name: gpushare-device-plugin-ds
    spec:
      serviceAccount: gpushare-device-plugin
      hostNetwork: true
      nodeSelector:
        gpushare: "true"
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/acs/k8s-gpushare-plugin:v2-1.11-aff8a23
        name: gpushare
        # Make this pod as Guaranteed pod which will never be evicted because of node's resource consumption.
        command:
          - gpushare-device-plugin-v2
          - -logtostderr
          - --v=5
          - --memory-unit=GiB//
        resources:
          limits:
            memory: "300Mi"
            cpu: "1"
          requests:
            memory: "300Mi"
            cpu: "1"
        env:
        - name: KUBECONFIG
          value: /etc/kubernetes/kubelet.conf
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
        volumeMounts:
          - name: device-plugin
            mountPath: /var/lib/kubelet/device-plugins
      volumes:
        - name: device-plugin
          hostPath:
            path: /var/lib/kubelet/device-plugins

注意: 请移除 GPU device plugin, 例如 nvidia-device-plugin, 可以通过命令 kubectl delete ds -n kube-system nvidia-device-plugin-daemonset 来删除.

4. 给 gpushare 节点打标签

kubectl label node <target_node> gpushare=true

5. 安装Kubectl 扩展

5.1 需要已安装 kubectl 1.12+

在linux下安装 kubectl

curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.12.1/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/bin/kubectl

5.2 下载并安装 kubectl 扩展功能

cd /usr/bin/
wget https://github.com/AliyunContainerService/gpushare-device-plugin/releases/download/v0.3.0/kubectl-inspect-gpushare
chmod u+x /usr/bin/kubectl-inspect-gpushare

测试

1.部署后查看插件状态

gpushare2.png

2. 查看节点状态

gpushare3.png

3. 通过kubectl扩展功能查看gpushare

gpushare4.png

4. 官例测试

官例Yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: binpack-1
  labels:
    app: binpack-1
spec:
  replicas: 1
  selector: # define how the deployment finds the pods it mangages
    matchLabels:
      app: binpack-1
  template: # define the pods specifications
    metadata:
      labels:
        app: binpack-1
    spec:
      containers:
      - name: binpack-1
        image: cheyang/gpu-player:v2
        env:
        - name: NVIDIA_VISIBLE_DEVICES
          value: "all"
        resources:
          limits:
            # GiB
            aliyun.com/gpu-mem: 8

部署结果

可以看到两个binpack的pod都已成功运行了,通过kubectl可以查看到被使用了16G的显存。

gpushare5.png

两个pod中的日志如下。

gpushare6.png

进入pod,执行nvidia-smi,可以发现没有实现显存隔离。

gpushare7.png

其他: 阿里云cGPU隔离的实现

阿里云提供的共享GPU方案通过自主研发的宿主机内核驱动, 实现对NVIDIA GPU的底层nv驱动更有效的利用。共享GPU功能如下:
更加开放:适配开源标准的Kubernetes和NVIDIA Docker方案。
更加简单:优秀的用户体验。AI应用无需重编译,无需构建新的容器镜像进行CUDA库替换。
更加稳定:针对NVIDIA设备的底层操作更加稳定和收敛,而CUDA层的API变化多端,同时一些Cudnn非开放的API也不容易捕获。
完整隔离:同时支持GPU的显存和算力隔离。

ISSIUES

若指定aliyun.com/gpu-mem:stderr: nvidia-container-cli: device error: unknown device id: no-gpu-has-**MiB-to-run
可以尝试一下在container中添加env,如下:

containers:
    - name: cuda
      image: nvidia/cuda:latest
      env: //
        - name: NVIDIA_VISIBLE_DEVICES 
          value: "all"
      resources:
        limits:
          # GiB
          aliyun.com/gpu-mem: 1

注意事项

  • 按显存(GPU Memory)和按卡(GPU count)调度的方式可以在集群内并存,但是同一个节点内是互斥的。
  • 不支持共享GPU显存资源的隔离,需要应用在代码中配置该任务可使用的GPU显存大小。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,578评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,701评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,691评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,974评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,694评论 6 413
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,026评论 1 329
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,015评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,193评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,719评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,442评论 3 360
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,668评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,151评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,846评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,255评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,592评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,394评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,635评论 2 380

推荐阅读更多精彩内容