В феврале 2022 года Amazon Web Services добавила поддержка показателей NVIDIA GPU в Amazon CloudWatch, что позволяет передавать метрики из Агент Amazon CloudWatch в Amazon CloudWatch и отслеживайте свой код для оптимального использования графического процессора. С тех пор эта функция была интегрирована во многие наши управляемые образы компьютеров Amazon (AMI), например AMI глубокого обучения и AWS ParallelCluster AMI. Чтобы получить показатели использования графического процессора на уровне экземпляра, вы можете использовать Packer или Amazon ImageBuilder для загрузки собственного пользовательского AMI и использования его в различных предложениях управляемых услуг, таких как Пакет AWS, Amazon Elastic Контейнерный Сервис (Amazon ECS) или Амазон Эластик Кубернетес Сервис (Амазонка ЭКС). Однако для многих предложений услуг и рабочих нагрузок на основе контейнеров идеально собирать показатели использования на уровне контейнера, модуля или пространства имен.
В этом посте подробно описано, как настроить метрики графического процессора на основе контейнера, и приведен пример сбора этих метрик из модулей EKS.
Обзор решения
Чтобы продемонстрировать метрики графического процессора на основе контейнера, мы создаем кластер EKS с g5.2xlarge
случаи; однако это будет работать с любым поддерживаемым семейством ускоренных экземпляров NVIDIA.
Мы развертываем оператор NVIDIA GPU, чтобы обеспечить возможность использования ресурсов графического процессора и Экспортер NVIDIA DCGM чтобы включить сбор метрик графического процессора. Затем мы исследуем две архитектуры. Первый связывает метрики из NVIDIA DCGM Exporter с CloudWatch через агент CloudWatch, как показано на следующей диаграмме.
Вторая архитектура (см. следующую схему) соединяет метрики из DCGM Exporter с Прометей, то мы используем графана панель мониторинга для визуализации этих показателей.
Предпосылки
Чтобы упростить воспроизведение всего стека из этого поста, мы используем контейнер, в котором уже установлен весь необходимый инструментарий (aws cli, eksctl, helm и т. д.). Чтобы клонировать контейнерный проект с GitHub, тебе понадобится мерзавец. Для сборки и запуска контейнера вам понадобится Docker. Для развертывания архитектуры вам понадобится Учетные данные AWS. Чтобы включить доступ к сервисам Kubernetes с помощью переадресации портов, вам также потребуется кубектл.
Эти необходимые компоненты можно установить на ваш локальный компьютер, EC2 экземпляр НИЦЦА DCVили Облако AWS9. В этом посте мы будем использовать c5.2xlarge
Экземпляр Cloud9 с 40GB
объем локального хранилища. При использовании Cloud9 отключите временные учетные данные, управляемые AWS, посетив Cloud9->Preferences->AWS Settings
как показано на скриншоте ниже.
Создайте и запустите контейнер aws-do-eks.
Откройте оболочку терминала в предпочитаемой вами среде и выполните следующие команды:
git clone https://github.com/aws-samples/aws-do-eks
cd aws-do-eks
./build.sh
./run.sh
./exec.sh
Результат такой:
Теперь у вас есть оболочка в контейнерной среде, в которой есть все инструменты, необходимые для выполнения приведенных ниже задач. Мы будем называть его «оболочкой aws-do-eks». Вы будете выполнять команды из следующих разделов в этой оболочке, если не указано иное.
Создайте кластер EKS с группой узлов.
В эту группу входит семейство экземпляров графического процессора по вашему выбору; в этом примере мы используем g5.2xlarge
тип экземпляра.
Ассоциация проект aws-do-eks поставляется с коллекцией конфигураций кластера. Вы можете установить желаемую конфигурацию кластера одним изменением конфигурации.
- В оболочке контейнера запустите
./env-config.sh
а затем установить CONF=conf/eksctl/yaml/eks-gpu-g5.yaml
- Чтобы проверить конфигурацию кластера, запустите
./eks-config.sh
Вы должны увидеть следующий манифест кластера:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata: name: do-eks-yaml-g5 version: "1.25" region: us-east-1
availabilityZones: - us-east-1a - us-east-1b - us-east-1c - us-east-1d
managedNodeGroups: - name: sys instanceType: m5.xlarge desiredCapacity: 1 iam: withAddonPolicies: autoScaler: true cloudWatch: true - name: g5 instanceType: g5.2xlarge instancePrefix: g5-2xl privateNetworking: true efaEnabled: false minSize: 0 desiredCapacity: 1 maxSize: 10 volumeSize: 80 iam: withAddonPolicies: cloudWatch: true
iam: withOIDC: true
- Чтобы создать кластер, выполните следующую команду в контейнере
Вывод следующий:
root@e5ecb162812f:/eks# ./eks-create.sh /eks/impl/eksctl/yaml /eks ./eks-create.sh Mon May 22 20:50:59 UTC 2023
Creating cluster using /eks/conf/eksctl/yaml/eks-gpu-g5.yaml ... eksctl create cluster -f /eks/conf/eksctl/yaml/eks-gpu-g5.yaml 2023-05-22 20:50:59 [ℹ] eksctl version 0.133.0
2023-05-22 20:50:59 [ℹ] using region us-east-1
2023-05-22 20:50:59 [ℹ] subnets for us-east-1a - public:192.168.0.0/19 private:192.168.128.0/19
2023-05-22 20:50:59 [ℹ] subnets for us-east-1b - public:192.168.32.0/19 private:192.168.160.0/19
2023-05-22 20:50:59 [ℹ] subnets for us-east-1c - public:192.168.64.0/19 private:192.168.192.0/19
2023-05-22 20:50:59 [ℹ] subnets for us-east-1d - public:192.168.96.0/19 private:192.168.224.0/19
2023-05-22 20:50:59 [ℹ] nodegroup "sys" will use "" [AmazonLinux2/1.25]
2023-05-22 20:50:59 [ℹ] nodegroup "g5" will use "" [AmazonLinux2/1.25]
2023-05-22 20:50:59 [ℹ] using Kubernetes version 1.25
2023-05-22 20:50:59 [ℹ] creating EKS cluster "do-eks-yaml-g5" in "us-east-1" region with managed nodes
2023-05-22 20:50:59 [ℹ] 2 nodegroups (g5, sys) were included (based on the include/exclude rules)
2023-05-22 20:50:59 [ℹ] will create a CloudFormation stack for cluster itself and 0 nodegroup stack(s)
2023-05-22 20:50:59 [ℹ] will create a CloudFormation stack for cluster itself and 2 managed nodegroup stack(s)
2023-05-22 20:50:59 [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=us-east-1 --cluster=do-eks-yaml-g5'
2023-05-22 20:50:59 [ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "do-eks-yaml-g5" in "us-east-1"
2023-05-22 20:50:59 [ℹ] CloudWatch logging will not be enabled for cluster "do-eks-yaml-g5" in "us-east-1"
2023-05-22 20:50:59 [ℹ] you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=us-east-1 --cluster=do-eks-yaml-g5'
2023-05-22 20:50:59 [ℹ] 2 sequential tasks: { create cluster control plane "do-eks-yaml-g5", 2 sequential sub-tasks: { 4 sequential sub-tasks: { wait for control plane to become ready, associate IAM OIDC provider, 2 sequential sub-tasks: { create IAM role for serviceaccount "kube-system/aws-node", create serviceaccount "kube-system/aws-node", }, restart daemonset "kube-system/aws-node", }, 2 parallel sub-tasks: { create managed nodegroup "sys", create managed nodegroup "g5", }, } }
2023-05-22 20:50:59 [ℹ] building cluster stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:51:00 [ℹ] deploying stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:51:30 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:52:00 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:53:01 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:54:01 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:55:01 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:56:02 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:57:02 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:58:02 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 20:59:02 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 21:00:03 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 21:01:03 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 21:02:03 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 21:03:04 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-cluster"
2023-05-22 21:05:07 [ℹ] building iamserviceaccount stack "eksctl-do-eks-yaml-g5-addon-iamserviceaccount-kube-system-aws-node"
2023-05-22 21:05:10 [ℹ] deploying stack "eksctl-do-eks-yaml-g5-addon-iamserviceaccount-kube-system-aws-node"
2023-05-22 21:05:10 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-addon-iamserviceaccount-kube-system-aws-node"
2023-05-22 21:05:40 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-addon-iamserviceaccount-kube-system-aws-node"
2023-05-22 21:05:40 [ℹ] serviceaccount "kube-system/aws-node" already exists
2023-05-22 21:05:41 [ℹ] updated serviceaccount "kube-system/aws-node"
2023-05-22 21:05:41 [ℹ] daemonset "kube-system/aws-node" restarted
2023-05-22 21:05:41 [ℹ] building managed nodegroup stack "eksctl-do-eks-yaml-g5-nodegroup-sys"
2023-05-22 21:05:41 [ℹ] building managed nodegroup stack "eksctl-do-eks-yaml-g5-nodegroup-g5"
2023-05-22 21:05:42 [ℹ] deploying stack "eksctl-do-eks-yaml-g5-nodegroup-sys"
2023-05-22 21:05:42 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-sys"
2023-05-22 21:05:42 [ℹ] deploying stack "eksctl-do-eks-yaml-g5-nodegroup-g5"
2023-05-22 21:05:42 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-g5"
2023-05-22 21:06:12 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-sys"
2023-05-22 21:06:12 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-g5"
2023-05-22 21:06:55 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-sys"
2023-05-22 21:07:11 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-g5"
2023-05-22 21:08:29 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-g5"
2023-05-22 21:08:45 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-sys"
2023-05-22 21:09:52 [ℹ] waiting for CloudFormation stack "eksctl-do-eks-yaml-g5-nodegroup-g5"
2023-05-22 21:09:53 [ℹ] waiting for the control plane to become ready
2023-05-22 21:09:53 [✔] saved kubeconfig as "/root/.kube/config"
2023-05-22 21:09:53 [ℹ] 1 task: { install Nvidia device plugin }
W0522 21:09:54.155837 1668 warnings.go:70] spec.template.metadata.annotations[scheduler.alpha.kubernetes.io/critical-pod]: non-functional in v1.16+; use the "priorityClassName" field instead
2023-05-22 21:09:54 [ℹ] created "kube-system:DaemonSet.apps/nvidia-device-plugin-daemonset"
2023-05-22 21:09:54 [ℹ] as you are using the EKS-Optimized Accelerated AMI with a GPU-enabled instance type, the Nvidia Kubernetes device plugin was automatically installed. to skip installing it, use --install-nvidia-plugin=false.
2023-05-22 21:09:54 [✔] all EKS cluster resources for "do-eks-yaml-g5" have been created
2023-05-22 21:09:54 [ℹ] nodegroup "sys" has 1 node(s)
2023-05-22 21:09:54 [ℹ] node "ip-192-168-18-137.ec2.internal" is ready
2023-05-22 21:09:54 [ℹ] waiting for at least 1 node(s) to become ready in "sys"
2023-05-22 21:09:54 [ℹ] nodegroup "sys" has 1 node(s)
2023-05-22 21:09:54 [ℹ] node "ip-192-168-18-137.ec2.internal" is ready
2023-05-22 21:09:55 [ℹ] kubectl command should work with "/root/.kube/config", try 'kubectl get nodes'
2023-05-22 21:09:55 [✔] EKS cluster "do-eks-yaml-g5" in "us-east-1" region is ready Mon May 22 21:09:55 UTC 2023
Done creating cluster using /eks/conf/eksctl/yaml/eks-gpu-g5.yaml /eks
- Чтобы убедиться, что ваш кластер создан успешно, выполните следующую команду
kubectl get nodes -L node.kubernetes.io/instance-type
Вывод аналогичен следующему:
NAME STATUS ROLES AGE VERSION INSTANCE_TYPE
ip-192-168-18-137.ec2.internal Ready <none> 47m v1.25.9-eks-0a21954 m5.xlarge
ip-192-168-214-241.ec2.internal Ready <none> 46m v1.25.9-eks-0a21954 g5.2xlarge
В этом примере в нашем кластере есть один экземпляр m5.xlarge и один экземпляр g5.2xlarge; поэтому мы видим два узла, перечисленные в предыдущем выводе.
В процессе создания кластера будет установлен плагин устройства NVIDIA. Вам нужно будет удалить его после создания кластера, поскольку мы будем использовать Оператор графического процессора NVIDIA .
- Удалите плагин с помощью следующей команды
kubectl -n kube-system delete daemonset nvidia-device-plugin-daemonset
Получаем такой вывод:
daemonset.apps "nvidia-device-plugin-daemonset" deleted
Установите репозиторий NVIDIA Helm.
Установите репозиторий NVIDIA Helm с помощью следующей команды:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia && helm repo update
Разверните экспортер DCGM с помощью оператора NVIDIA GPU.
Чтобы развернуть экспортер DCGM, выполните следующие действия:
- Подготовьте конфигурацию метрик графического процессора экспортера DCGM.
curl https://raw.githubusercontent.com/NVIDIA/dcgm-exporter/main/etc/dcp-metrics-included.csv > dcgm-metrics.csv
У вас есть возможность редактировать dcgm-metrics.csv
файл. При необходимости вы можете добавить или удалить любые показатели.
- Создайте пространство имен gpu-operator и экспортер DCGM ConfigMap.
kubectl create namespace gpu-operator && /
kubectl create configmap metrics-config -n gpu-operator --from-file=dcgm-metrics.csv
Вывод следующий:
namespace/gpu-operator created
configmap/metrics-config created
- Примените оператор GPU к кластеру EKS.
helm install --wait --generate-name -n gpu-operator --create-namespace nvidia/gpu-operator --set dcgmExporter.config.name=metrics-config --set dcgmExporter.env[0].name=DCGM_EXPORTER_COLLECTORS --set dcgmExporter.env[0].value=/etc/dcgm-exporter/dcgm-metrics.csv --set toolkit.enabled=false
Вывод следующий:
NAME: gpu-operator-1684795140
LAST DEPLOYED: Day Month Date HH:mm:ss YYYY
NAMESPACE: gpu-operator
STATUS: deployed
REVISION: 1
TEST SUITE: None
- Убедитесь, что модуль экспорта DCGM запущен.
kubectl -n gpu-operator get pods | grep dcgm
Вывод следующий:
nvidia-dcgm-exporter-lkmfr 1/1 Running 0 1m
Если вы просмотрите журналы, вы должны увидеть “Starting webserver”
сообщение:
kubectl -n gpu-operator logs -f $(kubectl -n gpu-operator get pods | grep dcgm | cut -d ' ' -f 1)
Вывод следующий:
Defaulted container "nvidia-dcgm-exporter" out of: nvidia-dcgm-exporter, toolkit-validation (init)
time="2023-05-22T22:40:08Z" level=info msg="Starting dcgm-exporter"
time="2023-05-22T22:40:08Z" level=info msg="DCGM successfully initialized!"
time="2023-05-22T22:40:08Z" level=info msg="Collecting DCP Metrics"
time="2023-05-22T22:40:08Z" level=info msg="No configmap data specified, falling back to metric file /etc/dcgm-exporter/dcgm-metrics.csv"
time="2023-05-22T22:40:08Z" level=info msg="Initializing system entities of type: GPU"
time="2023-05-22T22:40:09Z" level=info msg="Initializing system entities of type: NvSwitch"
time="2023-05-22T22:40:09Z" level=info msg="Not collecting switch metrics: no switches to monitor"
time="2023-05-22T22:40:09Z" level=info msg="Initializing system entities of type: NvLink"
time="2023-05-22T22:40:09Z" level=info msg="Not collecting link metrics: no switches to monitor"
time="2023-05-22T22:40:09Z" level=info msg="Kubernetes metrics collection enabled!"
time="2023-05-22T22:40:09Z" level=info msg="Pipeline starting"
time="2023-05-22T22:40:09Z" level=info msg="Starting webserver"
NVIDIA DCGM Exporter предоставляет конечную точку метрик Prometheus, которую может использовать агент CloudWatch. Чтобы увидеть конечную точку, используйте следующую команду:
kubectl -n gpu-operator get services | grep dcgm
Получаем такой вывод:
nvidia-dcgm-exporter ClusterIP 10.100.183.207 <none> 9400/TCP 10m
- Чтобы обеспечить некоторую загрузку графического процессора, мы развертываем модуль, который запускает GPU-запись двоичный
kubectl apply -f https://raw.githubusercontent.com/aws-samples/aws-do-eks/main/Container-Root/eks/deployment/gpu-metrics/gpu-burn-deployment.yaml
Вывод следующий:
deployment.apps/gpu-burn created
В этом развертывании используется один графический процессор для создания непрерывного шаблона 100 % использования в течение 20 секунд, а затем 0 % использования в течение 20 секунд.
- Чтобы убедиться, что конечная точка работает, вы можете запустить временный контейнер, который использует Curl для чтения содержимого
http://nvidia-dcgm-exporter:9400/metrics
kubectl -n gpu-operator run -it --rm curl --restart='Never' --image=curlimages/curl --command -- curl http://nvidia-dcgm-exporter:9400/metrics
Получаем такой вывод:
# HELP DCGM_FI_DEV_SM_CLOCK SM clock frequency (in MHz).
# TYPE DCGM_FI_DEV_SM_CLOCK gauge
DCGM_FI_DEV_SM_CLOCK{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 1455
# HELP DCGM_FI_DEV_MEM_CLOCK Memory clock frequency (in MHz).
# TYPE DCGM_FI_DEV_MEM_CLOCK gauge
DCGM_FI_DEV_MEM_CLOCK{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 6250
# HELP DCGM_FI_DEV_GPU_TEMP GPU temperature (in C).
# TYPE DCGM_FI_DEV_GPU_TEMP gauge
DCGM_FI_DEV_GPU_TEMP{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 65
# HELP DCGM_FI_DEV_POWER_USAGE Power draw (in W).
# TYPE DCGM_FI_DEV_POWER_USAGE gauge
DCGM_FI_DEV_POWER_USAGE{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 299.437000
# HELP DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION Total energy consumption since boot (in mJ).
# TYPE DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION counter
DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 15782796862
# HELP DCGM_FI_DEV_PCIE_REPLAY_COUNTER Total number of PCIe retries.
# TYPE DCGM_FI_DEV_PCIE_REPLAY_COUNTER counter
DCGM_FI_DEV_PCIE_REPLAY_COUNTER{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_GPU_UTIL GPU utilization (in %).
# TYPE DCGM_FI_DEV_GPU_UTIL gauge
DCGM_FI_DEV_GPU_UTIL{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 100
# HELP DCGM_FI_DEV_MEM_COPY_UTIL Memory utilization (in %).
# TYPE DCGM_FI_DEV_MEM_COPY_UTIL gauge
DCGM_FI_DEV_MEM_COPY_UTIL{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 38
# HELP DCGM_FI_DEV_ENC_UTIL Encoder utilization (in %).
# TYPE DCGM_FI_DEV_ENC_UTIL gauge
DCGM_FI_DEV_ENC_UTIL{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_DEC_UTIL Decoder utilization (in %).
# TYPE DCGM_FI_DEV_DEC_UTIL gauge
DCGM_FI_DEV_DEC_UTIL{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_XID_ERRORS Value of the last XID error encountered.
# TYPE DCGM_FI_DEV_XID_ERRORS gauge
DCGM_FI_DEV_XID_ERRORS{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_FB_FREE Framebuffer memory free (in MiB).
# TYPE DCGM_FI_DEV_FB_FREE gauge
DCGM_FI_DEV_FB_FREE{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 2230
# HELP DCGM_FI_DEV_FB_USED Framebuffer memory used (in MiB).
# TYPE DCGM_FI_DEV_FB_USED gauge
DCGM_FI_DEV_FB_USED{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 20501
# HELP DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL Total number of NVLink bandwidth counters for all lanes.
# TYPE DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL counter
DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_VGPU_LICENSE_STATUS vGPU License status
# TYPE DCGM_FI_DEV_VGPU_LICENSE_STATUS gauge
DCGM_FI_DEV_VGPU_LICENSE_STATUS{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_UNCORRECTABLE_REMAPPED_ROWS Number of remapped rows for uncorrectable errors
# TYPE DCGM_FI_DEV_UNCORRECTABLE_REMAPPED_ROWS counter
DCGM_FI_DEV_UNCORRECTABLE_REMAPPED_ROWS{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_CORRECTABLE_REMAPPED_ROWS Number of remapped rows for correctable errors
# TYPE DCGM_FI_DEV_CORRECTABLE_REMAPPED_ROWS counter
DCGM_FI_DEV_CORRECTABLE_REMAPPED_ROWS{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_DEV_ROW_REMAP_FAILURE Whether remapping of rows has failed
# TYPE DCGM_FI_DEV_ROW_REMAP_FAILURE gauge
DCGM_FI_DEV_ROW_REMAP_FAILURE{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0
# HELP DCGM_FI_PROF_GR_ENGINE_ACTIVE Ratio of time the graphics engine is active (in %).
# TYPE DCGM_FI_PROF_GR_ENGINE_ACTIVE gauge
DCGM_FI_PROF_GR_ENGINE_ACTIVE{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0.808369
# HELP DCGM_FI_PROF_PIPE_TENSOR_ACTIVE Ratio of cycles the tensor (HMMA) pipe is active (in %).
# TYPE DCGM_FI_PROF_PIPE_TENSOR_ACTIVE gauge
DCGM_FI_PROF_PIPE_TENSOR_ACTIVE{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0.000000
# HELP DCGM_FI_PROF_DRAM_ACTIVE Ratio of cycles the device memory interface is active sending or receiving data (in %).
# TYPE DCGM_FI_PROF_DRAM_ACTIVE gauge
DCGM_FI_PROF_DRAM_ACTIVE{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 0.315787
# HELP DCGM_FI_PROF_PCIE_TX_BYTES The rate of data transmitted over the PCIe bus - including both protocol headers and data payloads - in bytes per second.
# TYPE DCGM_FI_PROF_PCIE_TX_BYTES gauge
DCGM_FI_PROF_PCIE_TX_BYTES{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 3985328
# HELP DCGM_FI_PROF_PCIE_RX_BYTES The rate of data received over the PCIe bus - including both protocol headers and data payloads - in bytes per second.
# TYPE DCGM_FI_PROF_PCIE_RX_BYTES gauge
DCGM_FI_PROF_PCIE_RX_BYTES{gpu="0",UUID="GPU-ff76466b-22fc-f7a9-abe2-ce3ac453b8b3",device="nvidia0",modelName="NVIDIA A10G",Hostname="nvidia-dcgm-exporter-48cwd",DCGM_FI_DRIVER_VERSION="470.182.03",container="main",namespace="kube-system",pod="gpu-burn-c68d8c774-ltg9s"} 21715174
pod "curl" deleted
Настройка и развертывание агента CloudWatch
Чтобы настроить и развернуть агент CloudWatch, выполните следующие действия:
- Загрузите файл YAML и отредактируйте его.
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/k8s/1.3.15/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-eks.yaml
Файл содержит cwagent configmap
и еще один prometheus configmap
. В этом посте мы редактируем оба.
- Редактировать
prometheus-eks.yaml
файл
Откройте приложение prometheus-eks.yaml
файл в вашем любимом редакторе и замените cwagentconfig.json
раздел следующего содержания:
apiVersion: v1
data: # cwagent json config cwagentconfig.json: | { "logs": { "metrics_collected": { "prometheus": { "prometheus_config_path": "/etc/prometheusconfig/prometheus.yaml", "emf_processor": { "metric_declaration": [ { "source_labels": ["Service"], "label_matcher": ".*dcgm.*", "dimensions": [["Service","Namespace","ClusterName","job","pod"]], "metric_selectors": [ "^DCGM_FI_DEV_GPU_UTIL$", "^DCGM_FI_DEV_DEC_UTIL$", "^DCGM_FI_DEV_ENC_UTIL$", "^DCGM_FI_DEV_MEM_CLOCK$", "^DCGM_FI_DEV_MEM_COPY_UTIL$", "^DCGM_FI_DEV_POWER_USAGE$", "^DCGM_FI_DEV_ROW_REMAP_FAILURE$", "^DCGM_FI_DEV_SM_CLOCK$", "^DCGM_FI_DEV_XID_ERRORS$", "^DCGM_FI_PROF_DRAM_ACTIVE$", "^DCGM_FI_PROF_GR_ENGINE_ACTIVE$", "^DCGM_FI_PROF_PCIE_RX_BYTES$", "^DCGM_FI_PROF_PCIE_TX_BYTES$", "^DCGM_FI_PROF_PIPE_TENSOR_ACTIVE$" ] } ] } } }, "force_flush_interval": 5 } }
- В
prometheus
раздел конфигурации добавьте следующее определение задания для экспортера DCGM.
- job_name: 'kubernetes-pod-dcgm-exporter' sample_limit: 10000 metrics_path: /api/v1/metrics/prometheus kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_container_name] action: keep regex: '^DCGM.*$' - source_labels: [__address__] action: replace regex: ([^:]+)(?::d+)? replacement: ${1}:9400 target_label: __address__ - action: labelmap regex: __meta_kubernetes_pod_label_(.+) - action: replace source_labels: - __meta_kubernetes_namespace target_label: Namespace - source_labels: [__meta_kubernetes_pod] action: replace target_label: pod - action: replace source_labels: - __meta_kubernetes_pod_container_name target_label: container_name - action: replace source_labels: - __meta_kubernetes_pod_controller_name target_label: pod_controller_name - action: replace source_labels: - __meta_kubernetes_pod_controller_kind target_label: pod_controller_kind - action: replace source_labels: - __meta_kubernetes_pod_phase target_label: pod_phase - action: replace source_labels: - __meta_kubernetes_pod_node_name target_label: NodeName
- Сохраните файл и примените
cwagent-dcgm
конфигурация для вашего кластера
kubectl apply -f ./prometheus-eks.yaml
Получаем такой вывод:
namespace/amazon-cloudwatch created
configmap/prometheus-cwagentconfig created
configmap/prometheus-config created
serviceaccount/cwagent-prometheus created
clusterrole.rbac.authorization.k8s.io/cwagent-prometheus-role created
clusterrolebinding.rbac.authorization.k8s.io/cwagent-prometheus-role-binding created
deployment.apps/cwagent-prometheus created
- Убедитесь, что модуль агента CloudWatch запущен.
kubectl -n amazon-cloudwatch get pods
Получаем такой вывод:
NAME READY STATUS RESTARTS AGE
cwagent-prometheus-7dfd69cc46-s4cx7 1/1 Running 0 15m
Визуализируйте метрики в консоли CloudWatch
Чтобы визуализировать метрики в CloudWatch, выполните следующие действия:
- На консоли CloudWatch, под Метрика на панели навигации выберите Все показатели
- В Пользовательские пространства имен раздел, выберите новую запись для ContainerInsights/Прометей
Для получения более подробной информации о ContainerInsights/Прометей пространство имен, см. Удаление дополнительных источников Prometheus и импорт этих метрик.
- Разверните названия метрик и выберите
DCGM_FI_DEV_GPU_UTIL
- На Графические показатели вкладка, набор период в 5 секунд
- Установите интервал обновления 10 секунд.
Вы увидите показатели, полученные от экспортера DCGM, которые визуализируют gpu-burn
шаблон включается и выключается каждые 20 секунд.
На ЛИСТАТЬ СПИСКИ на вкладке вы можете просмотреть данные, включая имя модуля для каждой метрики.
Метаданные EKS API были объединены с данными метрик DCGM, в результате чего были предоставлены метрики графического процессора на основе модуля.
На этом завершается первый подход к экспорту метрик DCGM в CloudWatch через агент CloudWatch.
В следующем разделе мы настроим вторую архитектуру, которая экспортирует метрики DCGM в Prometheus, и визуализируем их с помощью Grafana.
Используйте Prometheus и Grafana для визуализации показателей графического процессора из DCGM.
Выполните следующие шаги:
- Добавьте диаграмму управления сообществом Prometheus.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
На этой диаграмме используются как Prometheus, так и Grafana. Нам нужно внести некоторые изменения в диаграмму перед запуском команды установки.
- Сохраните значения конфигурации диаграммы в файл в формате
/tmp
helm inspect values prometheus-community/kube-prometheus-stack > /tmp/kube-prometheus-stack.values
- Отредактируйте файл конфигурации char
Отредактируйте сохраненный файл (/tmp/kube-prometheus-stack.values
) и установите следующий параметр, найдя имя параметра и задав значение:
prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false
- Добавьте следующий ConfigMap в
additionalScrapeConfigs
.
additionalScrapeConfigs:
- job_name: gpu-metrics scrape_interval: 1s metrics_path: /metrics scheme: http kubernetes_sd_configs: - role: endpoints namespaces: names: - gpu-operator relabel_configs: - source_labels: [__meta_kubernetes_pod_node_name] action: replace target_label: kubernetes_node
- Разверните стек Prometheus с обновленными значениями.
helm install prometheus-community/kube-prometheus-stack
--create-namespace --namespace prometheus
--generate-name
--values /tmp/kube-prometheus-stack.values
Получаем такой вывод:
NAME: kube-prometheus-stack-1684965548
LAST DEPLOYED: Wed May 24 21:59:14 2023
NAMESPACE: prometheus
STATUS: deployed
REVISION: 1
NOTES:
kube-prometheus-stack has been installed. Check its status by running: kubectl --namespace prometheus get pods -l "release=kube-prometheus-stack-1684965548" Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.
- Убедитесь, что модули Prometheus работают.
kubectl get pods -n prometheus
Получаем такой вывод:
NAME READY STATUS RESTARTS AGE
alertmanager-kube-prometheus-stack-1684-alertmanager-0 2/2 Running 0 6m55s
kube-prometheus-stack-1684-operator-6c87649878-j7v55 1/1 Running 0 6m58s
kube-prometheus-stack-1684965548-grafana-dcd7b4c96-bzm8p 3/3 Running 0 6m58s
kube-prometheus-stack-1684965548-kube-state-metrics-7d856dptlj5 1/1 Running 0 6m58s
kube-prometheus-stack-1684965548-prometheus-node-exporter-2fbl5 1/1 Running 0 6m58s
kube-prometheus-stack-1684965548-prometheus-node-exporter-m7zmv 1/1 Running 0 6m58s
prometheus-kube-prometheus-stack-1684-prometheus-0 2/2 Running 0 6m55s
Модули Prometheus и Grafana находятся в Running
состоянии.
Далее мы проверяем, что метрики DCGM передаются в Prometheus.
- Перенос пользовательского интерфейса Prometheus
Существуют разные способы предоставить пользовательский интерфейс Prometheus, работающий в EKS, для запросов, исходящих за пределами кластера. Мы будем использовать kubectl port-forwarding
. До сих пор мы выполняли команды внутри aws-do-eks
контейнер. Для доступа к сервису Prometheus, работающему в кластере, мы создадим туннель от хоста. Здесь aws-do-eks
контейнер запускается путем выполнения следующей команды вне контейнера, в новой терминальной оболочке на хосте. Мы будем называть это «оболочкой хоста».
kubectl -n prometheus port-forward svc/$(kubectl -n prometheus get svc | grep prometheus | grep -v alertmanager | grep -v operator | grep -v grafana | grep -v metrics | grep -v exporter | grep -v operated | cut -d ' ' -f 1) 8080:9090 &
Пока выполняется процесс переадресации портов, мы можем получить доступ к пользовательскому интерфейсу Prometheus с хоста, как описано ниже.
- Откройте пользовательский интерфейс Прометея
- Если вы используете Cloud9, перейдите к
Preview->Preview Running Application
чтобы открыть пользовательский интерфейс Prometheus на вкладке внутри Cloud9 IDE, затем нажмите кнопку в правом верхнем углу вкладки, чтобы открыться в новом окне.
- Если вы находитесь на локальном хосте или подключены к экземпляру EC2 через удаленный рабочий стол, откройте браузер и перейдите по URL-адресу.
http://localhost:8080
.
- Enter
DCGM
чтобы увидеть метрики DCGM, которые передаются в Prometheus
- Выберите
DCGM_FI_DEV_GPU_UTIL
, выберите Выполнить, а затем перейдите к График вкладка, чтобы увидеть ожидаемую схему использования графического процессора.
- Остановите процесс переадресации портов Prometheus.
Запустите следующую командную строку в оболочке хоста:
kill -9 $(ps -aef | grep port-forward | grep -v grep | grep prometheus | awk '{print $2}')
Теперь мы можем визуализировать метрики DCGM через панель Grafana Dashboard.
- Получите пароль для входа в пользовательский интерфейс Grafana.
kubectl -n prometheus get secret $(kubectl -n prometheus get secrets | grep grafana | cut -d ' ' -f 1) -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
- Переадресация службы Grafana
Запустите следующую командную строку в оболочке хоста:
kubectl port-forward -n prometheus svc/$(kubectl -n prometheus get svc | grep grafana | cut -d ' ' -f 1) 8080:80 &
- Войдите в пользовательский интерфейс Grafana
Получите доступ к экрану входа в пользовательский интерфейс Grafana так же, как вы ранее обращались к пользовательскому интерфейсу Prometheus. Если вы используете Cloud9, выберите Preview->Preview Running Application
, а затем появится в новом окне. Если вы используете локальный хост или экземпляр EC2 с удаленным рабочим столом, посетите URL-адрес. http://localhost:8080
. Войдите в систему, используя имя пользователя admin и пароль, который вы получили ранее.
- На панели навигации выберите Dashboards
- Выберите Новые и Импортировать
Мы собираемся импортировать панель управления DCGM Grafana по умолчанию, описанную в разделе Панель экспорта NVIDIA DCGM.
- В поле
import via grafana.com
, войти 12239
, а затем выбрать нагрузка
- Выберите Прометей в качестве источника данных
- Выберите Импортировать
Вы увидите панель управления, похожую на ту, что показана на следующем снимке экрана.
Чтобы продемонстрировать, что эти метрики основаны на модулях, мы собираемся изменить Использование графического процессора на этой информационной панели.
- Выберите панель и меню параметров (три точки).
- Развернуть Опции раздел и отредактируйте Легенда поле
- Замените там значение на
Pod {{pod}}
, а затем выберите Сохранить
Легенда теперь показывает gpu-burn
имя модуля, связанное с отображаемым использованием графического процессора.
- Остановить переадресацию портов службы пользовательского интерфейса Grafana.
Запустите следующее в оболочке хоста:
kill -9 $(ps -aef | grep port-forward | grep -v grep | grep prometheus | awk '{print $2}')
В этом посте мы продемонстрировали использование Prometheus и Grafana с открытым исходным кодом, развернутых в кластере EKS. При желании это развертывание можно заменить на Управляемый сервис Amazon для Prometheus и Графана под управлением Amazon.
Убирать
Чтобы очистить созданные вами ресурсы, запустите следующий скрипт из aws-do-eks
оболочка контейнера:
Заключение
В этом посте мы использовали NVIDIA DCGM Exporter для сбора показателей графического процессора и их визуализации с помощью CloudWatch или Prometheus и Grafana. Мы приглашаем вас использовать продемонстрированные здесь архитектуры, чтобы обеспечить мониторинг использования графического процессора с помощью NVIDIA DCGM в вашей собственной среде AWS.
Дополнительные ресурсы
Об авторах
Амр Рагаб — бывший главный архитектор решений EC2 Accelerated Computing в AWS. Он стремится помогать клиентам выполнять масштабные вычислительные нагрузки. В свободное время он любит путешествовать и находить новые способы интеграции технологий в повседневную жизнь.
Алекс Янкульский — главный архитектор решений в сфере самостоятельного машинного обучения в AWS. Он инженер по комплексному программному обеспечению и инфраструктуре, который любит выполнять глубокую практическую работу. В своей роли он занимается оказанием помощи клиентам в контейнеризации и оркестрации рабочих нагрузок машинного обучения и искусственного интеллекта в сервисах AWS на базе контейнеров. Он также является автором открытого исходного кода сделать структуру и капитан Docker, который любит применять контейнерные технологии для ускорения темпов инноваций и решения крупнейших мировых проблем. В течение последних 10 лет Алекс работал над демократизацией искусственного интеллекта и машинного обучения, борьбой с изменением климата, повышением безопасности путешествий, улучшением здравоохранения и рациональностью использования энергии.
Кейта Ватанабэ является старшим архитектором решений Frameworks ML Solutions в Amazon Web Services, где он помогает разрабатывать лучшие в отрасли облачные решения для самостоятельного машинного обучения. Его опыт работы связан с исследованиями и разработками в области машинного обучения. До прихода в AWS Кейта работал в сфере электронной коммерции. Кейта имеет докторскую степень. Доктор наук Токийского университета.
- SEO-контент и PR-распределение. Получите усиление сегодня.
- PlatoData.Network Вертикальный генеративный ИИ. Расширьте возможности себя. Доступ здесь.
- ПлатонАйСтрим. Интеллект Web3. Расширение знаний. Доступ здесь.
- ПлатонЭСГ. Автомобили / электромобили, Углерод, чистые технологии, Энергия, Окружающая среда, Солнечная, Управление отходами. Доступ здесь.
- ПлатонЗдоровье. Биотехнологии и клинические исследования. Доступ здесь.
- ЧартПрайм. Улучшите свою торговую игру с ChartPrime. Доступ здесь.
- Смещения блоков. Модернизация права собственности на экологические компенсации. Доступ здесь.
- Источник: https://aws.amazon.com/blogs/machine-learning/enable-pod-based-gpu-metrics-in-amazon-cloudwatch/