从监控到隔离,阿里云容器服务提升您的GPU资源使用体验

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 通过使用阿里云容器服务的GPU支持,可以提升GPU资源管理的可见性,了解到需要多少的GPU资源可以支撑图像识别,语音识别,在线翻译等业务,如何能用最少的成本满足业务需求;而可以在无需修改现有GPU程序的前提下,保障多个容器共享同一个GPU时,实现彼此互相隔离。

从监控到隔离,阿里云容器服务提升您的GPU资源使用体验

推动人工智能不断向前的动力来自于强大的算力,海量的数据和优化的算法,而Nvidia GPU是最流行的异构算力提供者,是高性能深度学习的基石。但是GPU不菲的价格一直是用户的心头之痛,而从使用率的角度来看,模型预测场景下,应用独占GPU模式实际上会对这种宝贵的资源造成大量的浪费。但是共享GPU实际上也不是一蹴而就,比如一方面用户需要判断多少的分配GPU资源可以达到成本和QPS平衡的最优,另一方面也要考虑同时当多个应用运行在一个GPU设备上时,应用的SLA如何保障。
image.png
而通过使用阿里云容器服务,一方面借助托管的Prometheus,提升GPU资源管理的可见性,快速了解到需要多少的GPU资源可以支撑图像识别,语音识别,在线翻译等业务,如何能用最少的成本满足业务需求;而另一方面,借助昊天cGPU,在无需修改现有GPU程序的前提下,保障多个容器共享同一个GPU时,彼此互相隔离。
我们通过一个实际的例子向您展示如何利用托管Prometheus的监控能力查看GPU的显存使用,并且通过昊天cGPU进行资源隔离。

前置条件

使用步骤

通过托管Prometheus监控独享GPU

  1. 登录ARMS控制台, 选择Kubernetes所在的集群
  2. 在ARMS控制台中Prometheus界面中,点击集群列表中需要监控集群的安装按钮。此过程需要2分钟左右,请点击确认。

image.png

  1. 在该集群的已安装插件中可以看到 GPU NodeGPU APP,分别从节点维度和应用维度监控GPU资源

image.png

  1. 运行测试应用

利用命令行部署如下应用, 参考文档

apiVersion: apps/v1beta1
kind: StatefulSet

metadata:
  name: app-3g-v1
  labels:
    app: app-3g-v1
spec:
  replicas: 1
  serviceName: "app-3g-v1"
  podManagementPolicy: "Parallel"
  selector: # define how the deployment finds the pods it manages
    matchLabels:
      app: app-3g-v1
  updateStrategy:
    type: RollingUpdate
  template: # define the pods specifications
    metadata:
      labels:
        app: app-3g-v1
    spec:
      containers:
      - name: app-3g-v1
        image: registry.cn-shanghai.aliyuncs.com/tensorflow-samples/cuda-malloc:3G
        resources:
          limits:
            nvidia.com/gpu: 1

部署成功后,查看应用的状态,可以知道应用的名称是app-3g-v1-0

kubectl get po
NAME          READY   STATUS    RESTARTS   AGE
app-3g-v1-0   1/1     Running   1          2m56s
  1. 通过应用角度监控, 点击GPU App进入可以观察到GPU的显存使用率, 可以发现这个应用的GPU显存占用率仅为20%,有80%的浪费。而它使用的显存也是比较稳定在3.4GB左右,而该GPU总的显存是16GB左右。

image.png
此时可以发现一个应用独占一张GPU卡的模式非常浪费。因此可以考虑通过使用cGPU(container GPU)可以将多个应用部署在同一个GPU卡上。
可以先将该容器移除

kubectl delete sts app-3g-v1

使用cGPU保障多容器共享

为带有GPU设备的节点打标签

在安装cGPU相关组件之前,需要给gpu节点打上标签"cgpu=true",步骤如下:
(1)登录容器服务 Kubernetes 版控制台
(2)在 Kubernetes 菜单下,单击左侧导航栏中的集群 > 节点,进入节点列表页面。选择所需的集群,在页面右上角单击标签管理。
(3)选择所需的集群,在页面右上角单击标签管理。

(4)在节点列表中,批量选择节点,然后单击添加标签。

(5)填写标签名称和值(名称为cgpu,值为true),点击确定。

安装cGPU相关组件

(1)登录容器服务 Kubernetes 版控制台。(2)在左侧导航栏选择市场 > 应用目录,在右侧选中 ack-cgpu。(3)在应用目录 -> ack-cgpu页面上,在右侧的创建面板中选择前提条件中创建的集群和命名空间,并单击创建。
image.png

  1. 安装kubectl-inspect-cgpu

kubectl-inspect-gpushare是一个查询节点GPU分配情况的工具,它依赖集群的kubeconfig配置文件。请登录到linux客户端进行安装。请确保"~/.kube/config"文件已经存在,如何下载集群的kubeconfig文件,请参考用kubectl管理集群。kubeconfig文件配置完成以后,接着在该节点上执行如下操作安装kubectl-inspect-cgpu:

# cd /usr/local/bin
# wget http://aliacs-k8s-cn-beijing.oss-cn-beijing.aliyuncs.com/cgpu/kubectl-inspect-cgpu
# chmod u+x /usr/local/bin/kubectl-inspect-cgpu
  1. 通过kubectl-inspect-cgpu检查GPU资源
# kubectl inspect cgpu
NAME                       IPADDRESS      GPU0(Allocated/Total)  GPU Memory(GiB)
cn-hangzhou.192.168.2.167  192.168.2.167  0/15                   0/15
----------------------------------------------------------------------
Allocated/Total GPU Memory In Cluster:
0/15 (0%)

此时可以发现该节点的GPU资源维度已经从卡变成GPU显存

部署共享GPU工作负载

  1. 按照GPU显存维度调度重新创建工作负载

只需要将之前的部署yaml做两处的修改:

  • 将实例的副本数从1改为2,这样可以指定部署两个负载。而在原有GPU独享的配置下,单个GPU卡智能调度单个容器;修改配置后,可以部署两个Pod实例。
  • 将资源维度从nvidia.com/gpu变为aliyun.com/gpu-mem, 单位也从个变成了GiB

由于每个应用不足以独享GPU资源,因此它们可以部署到同一个GPU设备上。

apiVersion: apps/v1beta1
kind: StatefulSet

metadata:
  name: app-3g-v1
  labels:
    app: app-3g-v1
spec:
  replicas: 2
  serviceName: "app-3g-v1"
  podManagementPolicy: "Parallel"
  selector: # define how the deployment finds the pods it manages
    matchLabels:
      app: app-3g-v1
  template: # define the pods specifications
    metadata:
      labels:
        app: app-3g-v1
    spec:
      containers:
      - name: app-3g-v1
        image: registry.cn-shanghai.aliyuncs.com/tensorflow-samples/cuda-malloc:3G
        resources:
          limits:
            aliyun.com/gpu-mem: 4

从运行结果看,可以看到两个Pod都运行在同一个GPU设备上

#  kubectl inspect cgpu -d

NAME:       cn-hangzhou.192.168.2.167
IPADDRESS:  192.168.2.167

NAME         NAMESPACE  GPU0(Allocated)
app-3g-v1-0  default    4
app-3g-v1-1  default    4
Allocated :  8 (53%)
Total :      15
--------------------------------------------------------

Allocated/Total GPU Memory In Cluster:  8/15 (53%)
  1. 而分别登陆两个容器的时候可以看到他们各自的GPU显存的上限已经设置为4301MiB, 也就是在容器内使用的GPU显存不会超过这个上限
kubectl exec -it app-3g-v1-0 nvidia-smi
Mon Apr 13 01:33:10 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.01    Driver Version: 418.87.01    CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  On   | 00000000:00:07.0 Off |                    0 |
| N/A   37C    P0    57W / 300W |   3193MiB /  4301MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

kubectl exec -it app-3g-v1-1 nvidia-smi
Mon Apr 13 01:36:07 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.01    Driver Version: 418.87.01    CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  On   | 00000000:00:07.0 Off |                    0 |
| N/A   38C    P0    57W / 300W |   3193MiB /  4301MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+
  1. 而登陆到节点后,可以看到该GPU被使用的显存资源为两个容器之和6396MiB。这里可以看到cGPU资源已经起到了按容器隔离的效果。
# nvidia-smi
Mon Apr 13 09:36:43 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.01    Driver Version: 418.87.01    CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  On   | 00000000:00:07.0 Off |                    0 |
| N/A   37C    P0    57W / 300W |   6396MiB / 16130MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      2174      C   cuda_malloc                                 3193MiB |
|    0      2209      C   cuda_malloc                                 3193MiB |
+-----------------------------------------------------------------------------+
  1. 此时登录到容器内试图申请更多的GPU资源时,会直接报出显存分配失败的错误
kubectl exec -it app-3g-v1-1 bash
root@app-3g-v1-1:/# cuda_malloc -size=1024
cgpu_cuda_malloc starting...
Detected 1 CUDA Capable device(s)

Device 0: "Tesla V100-SXM2-16GB"
  CUDA Driver Version / Runtime Version          10.1 / 10.1
  Total amount of global memory:                 4301 MBytes (4509925376 bytes)
Try to malloc 1024 MBytes memory on GPU 0
CUDA error at cgpu_cuda_malloc.cu:119 code=2(cudaErrorMemoryAllocation) "cudaMalloc( (void**)&dev_c, malloc_size)"

通过托管Prometheus监控共享GPU

  1. 实际上用户并不需要到每个容器内执行nvidia-smi,这样做监控一方面效率低,也无法获得资源趋势。用户可以通过登录到ARMS控制台,选择相应的Kubernetes集群,进入GPU App。可以直接看到每个应用的GPU显存用量和占比

image.png

  1. 如果希望从节点维度观测,可以通过GPU Node查看GPU卡的显存使用量。可以看到恰好其显存使用率是两个GPU应用的使用之和为40%。

image.png

  1. 接下来,我们演示如何将一个害群之马关到笼子里,即当某个应用程序的声明使用GPU显存用量超过了资源上限后,cGPU如何确保当其他应用不受影响。

部署一个新的GPU应用,该应用声明使用的GPU显存是4GiB,但是它实际使用的GPU显存为6GiB

apiVersion: apps/v1beta1
kind: StatefulSet

metadata:
  name: app-6g-v1
  labels:
    app: app-6g-v1
spec:
  replicas: 1
  serviceName: "app-6g-v1"
  podManagementPolicy: "Parallel"
  selector: # define how the deployment finds the pods it manages
    matchLabels:
      app: app-6g-v1
  template: # define the pods specifications
    metadata:
      labels:
        app: app-6g-v1
    spec:
      containers:
      - name: app-6g-v1
        image: registry.cn-shanghai.aliyuncs.com/tensorflow-samples/cuda-malloc:6G
        resources:
          limits:
            aliyun.com/gpu-mem: 4

将该应用部署之后可以发现该pod一直处于CrashLoopBackOff, 而之前两个Pod还是正常运行的状态

# kubectl get po
NAME          READY   STATUS             RESTARTS   AGE
app-3g-v1-0   1/1     Running            0          7h35m
app-3g-v1-1   1/1     Running            0          7h35m
app-6g-v1-0   0/1     CrashLoopBackOff   5          3m15s

而该容器的日志报错,也很明确的显示是由于cudaErrorMemoryAllocation造成的

kubectl logs app-6g-v1-0
CUDA error at cgpu_cuda_malloc.cu:119 code=2(cudaErrorMemoryAllocation) "cudaMalloc( (void**)&dev_c, malloc_size)"

而此时其他的容器并没有收到影响,从托管的Prometheus监控中也可以看到之前的容器一直处于平稳运行之中,并没有受到新部署应用的影响。
image.png

总结

通过使用阿里云容器服务的GPU支持,可以提升GPU资源管理的可见性,了解到需要多少的GPU资源可以支撑图像识别,语音识别,在线翻译等业务,如何能用最少的成本满足业务需求;而可以在无需修改现有GPU程序的前提下,保障多个容器共享同一个GPU时,实现彼此互相隔离。帮助用户在享受低成本的同时,保障了应用的可靠性。

相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
26天前
|
安全 API 持续交付
要利用阿里云控制API查询您的阿里云资源
【2月更文挑战第33天】要利用阿里云控制API查询您的阿里云资源
18 3
|
29天前
|
存储 Kubernetes Docker
容器服务ACK常见问题之阿里云控制台进不去了如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
14天前
|
弹性计算
阿里云ECS使用体验
在申请高校学生免费体验阿里云ECS云服务器后的一些使用体验和感受。
|
2月前
|
人工智能 运维 Kubernetes
阿里云容器服务ACK AI助手正式上线带来的便利性
作为开发者想必大家都知道,云原生容器技术的优势,尤其是近两年的随着容器技术的迅猛发展,Kubernetes(K8s)已成为广泛应用于容器编排和管理的领先解决方案,但是K8s的运维复杂度一直是挑战之一。为了应对这一问题,就在最近,阿里云容器服务团队正式发布了ACK AI助手,这是一款旨在通过大模型增强智能诊断的产品,旨在帮助企业和开发者降低Kubernetes(K8s)的运维复杂度。那么本文就来详细讲讲关于这款产品,让我们结合实际案例分享一下K8s的运维经验,探讨ACK AI助手能否有效降低K8s的运维复杂度,并展望ACK AI助手正式版上线后的新功能。
264 2
阿里云容器服务ACK AI助手正式上线带来的便利性
|
2月前
|
监控 安全 关系型数据库
在规划阿里云RDS跨区迁移资源和服务可用性
在规划阿里云RDS跨区迁移资源和服务可用性
260 4
|
2月前
|
弹性计算 API Python
如何利用通义千问查询阿里云资源
本篇文章详细阐述了如何利用LangChain框架构建一款Python工具,该工具能够调用通义千问大模型来查询和获取阿里云资源信息。
115571 48
|
3天前
|
弹性计算 运维 安全
阿里云ecs使用体验
整了台服务器部署项目上线
|
17天前
|
存储 监控 异构计算
【Python】GPU内存监控脚本
【Python】GPU内存监控脚本
|
18天前
|
消息中间件 Kubernetes Kafka
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
14 0
|
24天前
|
弹性计算 缓存 Kubernetes
什么是阿里云弹性容器实例?弹性容器实例优势及应用场景介绍
弹性容器实例是阿里云的云服务器产品,使用弹性容器实例之后,用户无需管理底层 ECS 服务器,只需要提供打包好的镜像,即可运行容器,与阿里云容器服务无缝对接并仅为容器实际运行消耗的资源付费。本文介绍了阿里云弹性容器实例的、功能特性、产品优势及应用场景。
什么是阿里云弹性容器实例?弹性容器实例优势及应用场景介绍

相关产品

  • 容器计算服务