I februar 2022 tilføjede Amazon Web Services understøttelse af NVIDIA GPU-metrics i Amazon CloudWatch, hvilket gør det muligt at skubbe metrics fra Amazon CloudWatch Agent til amazoncloudwatch og overvåg din kode for optimal GPU-udnyttelse. Siden da er denne funktion blevet integreret i mange af vores administrerede Amazon Machine Images (AMI'er), såsom Deep Learning AMI og AWS ParallelCluster AMI. For at opnå målinger på instansniveau for GPU-udnyttelse kan du bruge Packer eller Amazon ImageBuilder til at starte din egen tilpassede AMI og bruge den i forskellige administrerede servicetilbud som f.eks. AWS batch, Amazon Elastic Container Service (Amazon ECS), eller Amazon Elastic Kubernetes Service (Amazon EKS). For mange containerbaserede servicetilbud og arbejdsbelastninger er det dog ideelt at fange udnyttelsesmetrikker på container-, pod- eller navneområdeniveau.
Dette indlæg beskriver, hvordan man opsætter containerbaserede GPU-metrics og giver et eksempel på indsamling af disse metrics fra EKS-pods.
Løsningsoversigt
For at demonstrere containerbaserede GPU-metrikker opretter vi en EKS-klynge med g5.2xlarge
tilfælde; dette vil dog fungere med enhver understøttet NVIDIA accelereret instansfamilie.
Vi implementerer NVIDIA GPU-operatøren for at muliggøre brug af GPU-ressourcer og NVIDIA DCGM eksportør for at aktivere indsamling af GPU-metrics. Derefter udforsker vi to arkitekturer. Den første forbinder metrikken fra NVIDIA DCGM Exporter til CloudWatch via en CloudWatch-agent, som vist i følgende diagram.
Den anden arkitektur (se følgende diagram) forbinder metrikken fra DCGM Exporter til Prometheus, så bruger vi en grafana dashboard for at visualisere disse metrics.
Forudsætninger
For at forenkle gengivelsen af hele stakken fra dette indlæg, bruger vi en beholder, der allerede har installeret alt det nødvendige værktøj (aws cli, eksctl, helm osv.). For at klone containerprojekt fra GitHub, du får brug for git. For at bygge og køre containeren skal du bruge Docker. For at implementere arkitekturen skal du bruge AWS-legitimationsoplysninger. For at aktivere adgang til Kubernetes-tjenester ved hjælp af port-forwarding, skal du også kubectl.
Disse forudsætninger kan installeres på din lokale maskine, EC2 forekomst med DEJLIG DCV eller AWS Cloud9. I dette indlæg vil vi bruge en c5.2xlarge
Cloud9-forekomst med en 40GB
lokal lagervolumen. Når du bruger Cloud9, skal du deaktivere AWS-administrerede midlertidige legitimationsoplysninger ved at besøge Cloud9->Preferences->AWS Settings
som vist på skærmbilledet nedenfor.
Byg og kør aws-do-eks containeren
Åbn en terminal shell i dit foretrukne miljø og kør følgende kommandoer:
git clone https://github.com/aws-samples/aws-do-eks
cd aws-do-eks
./build.sh
./run.sh
./exec.sh
Resultatet er som følger:
Du har nu en skal i et containermiljø, der har alle de nødvendige værktøjer til at udføre opgaverne nedenfor. Vi vil referere til det som "aws-do-eks shell". Du vil køre kommandoerne i de følgende sektioner i denne shell, medmindre andet er specifikt instrueret.
Opret en EKS-klynge med en nodegruppe
Denne gruppe inkluderer en GPU-instansfamilie efter eget valg; i dette eksempel bruger vi g5.2xlarge
instanstype.
aws-do-eks projekt leveres med en samling af klyngekonfigurationer. Du kan indstille din ønskede klyngekonfiguration med en enkelt konfigurationsændring.
- Kør i beholderskallen
./env-config.sh
og indstil derefter CONF=conf/eksctl/yaml/eks-gpu-g5.yaml
- Kør for at bekræfte klyngekonfigurationen
./eks-config.sh
Du bør se følgende klyngemanifest:
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
- For at oprette klyngen skal du køre følgende kommando i containeren
Udgangen er som følger:
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
- For at bekræfte, at din klynge er oprettet, skal du køre følgende kommando
kubectl get nodes -L node.kubernetes.io/instance-type
Outputtet ligner følgende:
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
I dette eksempel har vi en m5.xlarge og en g5.2xlarge instans i vores klynge; derfor ser vi to noder anført i det foregående output.
Under oprettelsesprocessen af klyngen bliver NVIDIA-enhedsplugin'et installeret. Du bliver nødt til at fjerne det efter oprettelse af klynge, fordi vi vil bruge NVIDIA GPU-operatør i stedet.
- Slet plugin'et med følgende kommando
kubectl -n kube-system delete daemonset nvidia-device-plugin-daemonset
Vi får følgende output:
daemonset.apps "nvidia-device-plugin-daemonset" deleted
Installer NVIDIA Helm repo
Installer NVIDIA Helm repo med følgende kommando:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia && helm repo update
Implementer DCGM-eksportøren med NVIDIA GPU-operatøren
Udfør følgende trin for at implementere DCGM-eksportøren:
- Forbered DCGM-eksportørens GPU-metrics-konfiguration
curl https://raw.githubusercontent.com/NVIDIA/dcgm-exporter/main/etc/dcp-metrics-included.csv > dcgm-metrics.csv
Du har mulighed for at redigere dcgm-metrics.csv
fil. Du kan tilføje eller fjerne alle metrics efter behov.
- Opret gpu-operatørens navneområde og DCGM-eksportør ConfigMap
kubectl create namespace gpu-operator && /
kubectl create configmap metrics-config -n gpu-operator --from-file=dcgm-metrics.csv
Udgangen er som følger:
namespace/gpu-operator created
configmap/metrics-config created
- Anvend GPU-operatøren til EKS-klyngen
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
Udgangen er som følger:
NAME: gpu-operator-1684795140
LAST DEPLOYED: Day Month Date HH:mm:ss YYYY
NAMESPACE: gpu-operator
STATUS: deployed
REVISION: 1
TEST SUITE: None
- Bekræft, at DCGM-eksportpod'en kører
kubectl -n gpu-operator get pods | grep dcgm
Udgangen er som følger:
nvidia-dcgm-exporter-lkmfr 1/1 Running 0 1m
Hvis du inspicerer logfilerne, bør du se “Starting webserver”
besked:
kubectl -n gpu-operator logs -f $(kubectl -n gpu-operator get pods | grep dcgm | cut -d ' ' -f 1)
Udgangen er som følger:
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 afslører et Prometheus-metrik-endepunkt, som kan indtages af CloudWatch-agenten. For at se slutpunktet skal du bruge følgende kommando:
kubectl -n gpu-operator get services | grep dcgm
Vi får følgende output:
nvidia-dcgm-exporter ClusterIP 10.100.183.207 <none> 9400/TCP 10m
- For at generere noget GPU-udnyttelse implementerer vi en pod, der kører gpu-brænding binær
kubectl apply -f https://raw.githubusercontent.com/aws-samples/aws-do-eks/main/Container-Root/eks/deployment/gpu-metrics/gpu-burn-deployment.yaml
Udgangen er som følger:
deployment.apps/gpu-burn created
Denne implementering bruger en enkelt GPU til at producere et kontinuerligt mønster med 100 % udnyttelse i 20 sekunder efterfulgt af 0 % udnyttelse i 20 sekunder.
- For at sikre dig, at slutpunktet virker, kan du køre en midlertidig beholder, der bruger curl til at læse indholdet af
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
Vi får følgende output:
# 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
Konfigurer og implementer CloudWatch-agenten
For at konfigurere og implementere CloudWatch-agenten skal du udføre følgende trin:
- Download YAML-filen og rediger den
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
Filen indeholder en cwagent configmap
og en prometheus configmap
. Til dette indlæg redigerer vi begge.
- Rediger
prometheus-eks.yaml
fil
Åbne prometheus-eks.yaml
fil i din foretrukne editor og erstat cwagentconfig.json
afsnit med følgende indhold:
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 } }
- I
prometheus
config-afsnittet, skal du tilføje følgende jobdefinition for DCGM-eksportøren
- 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
- Gem filen og anvend
cwagent-dcgm
konfiguration til din klynge
kubectl apply -f ./prometheus-eks.yaml
Vi får følgende output:
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
- Bekræft, at CloudWatch agent pod kører
kubectl -n amazon-cloudwatch get pods
Vi får følgende output:
NAME READY STATUS RESTARTS AGE
cwagent-prometheus-7dfd69cc46-s4cx7 1/1 Running 0 15m
Visualiser metrics på CloudWatch-konsollen
For at visualisere metrics i CloudWatch skal du udføre følgende trin:
- På CloudWatch-konsollen, under Metrics i navigationsruden skal du vælge Alle målinger
- I Brugerdefinerede navnerum sektion, skal du vælge den nye post for ContainerInsights/Prometheus
For mere information om den ContainerInsights/Prometheus navneområde, se Skrabning af yderligere Prometheus-kilder og import af disse metrics.
- Gå ned til metriske navne, og vælg
DCGM_FI_DEV_GPU_UTIL
- På Grafiske metrikker fane, sæt Periode til 5 sekunder
- Indstil opdateringsintervallet til 10 sekunder
Du vil se de målinger, der er indsamlet fra DCGM-eksportøren, der visualiserer gpu-burn
mønster til og fra hvert 20. sekund.
På Gennemse fanen, kan du se dataene, inklusive podnavnet for hver metrik.
EKS API-metadataene er blevet kombineret med DCGM-metrikdataene, hvilket resulterer i de leverede pod-baserede GPU-metrikker.
Dette afslutter den første tilgang til eksport af DCGM-metrics til CloudWatch via CloudWatch-agenten.
I næste afsnit konfigurerer vi den anden arkitektur, som eksporterer DCGM-metrikken til Prometheus, og vi visualiserer dem med Grafana.
Brug Prometheus og Grafana til at visualisere GPU-metrics fra DCGM
Udfør følgende trin:
- Tilføj Prometheus-fællesskabets styrediagram
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
Dette diagram implementerer både Prometheus og Grafana. Vi er nødt til at foretage nogle redigeringer af diagrammet, før vi kører installationskommandoen.
- Gem diagramkonfigurationsværdierne til en fil i
/tmp
helm inspect values prometheus-community/kube-prometheus-stack > /tmp/kube-prometheus-stack.values
- Rediger char-konfigurationsfilen
Rediger den gemte fil (/tmp/kube-prometheus-stack.values
) og indstil følgende indstilling ved at lede efter indstillingens navn og indstille værdien:
prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false
- Tilføj følgende ConfigMap til
additionalScrapeConfigs
sektion
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
- Implementer Prometheus-stakken med de opdaterede værdier
helm install prometheus-community/kube-prometheus-stack
--create-namespace --namespace prometheus
--generate-name
--values /tmp/kube-prometheus-stack.values
Vi får følgende output:
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.
- Bekræft, at Prometheus pods kører
kubectl get pods -n prometheus
Vi får følgende output:
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 og Grafana bælg er i Running
tilstand.
Dernæst validerer vi, at DCGM-metrikker strømmer ind i Prometheus.
- Port-forward Prometheus UI
Der er forskellige måder at eksponere Prometheus UI, der kører i EKS, for anmodninger, der stammer uden for klyngen. Vi vil bruge kubectl port-forwarding
. Indtil videre har vi udført kommandoer inde i aws-do-eks
beholder. For at få adgang til Prometheus-tjenesten, der kører i klyngen, opretter vi en tunnel fra værten. Her er aws-do-eks
container kører ved at udføre følgende kommando uden for containeren i en ny terminal shell på værten. Vi vil referere til dette som "værtsskal".
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 &
Mens portvideresendelsesprocessen kører, er vi i stand til at få adgang til Prometheus UI fra værten som beskrevet nedenfor.
- Åbn Prometheus UI
- Hvis du bruger Cloud9, skal du navigere til
Preview->Preview Running Application
for at åbne Prometheus UI i en fane inde i Cloud9 IDE, og klik derefter på ikonet i øverste højre hjørne af fanen for at komme ud i et nyt vindue.
- Hvis du er på din lokale vært eller tilsluttet en EC2-instans via fjernskrivebord, skal du åbne en browser og besøge URL'en
http://localhost:8080
.
- Indtast
DCGM
for at se DCGM-målingerne, der strømmer ind i Prometheus
- Type
DCGM_FI_DEV_GPU_UTIL
, vælg Udfør, og naviger derefter til Graf fanen for at se det forventede GPU-brugsmønster
- Stop Prometheus port-videresendelsesprocessen
Kør følgende kommandolinje i din værtsshell:
kill -9 $(ps -aef | grep port-forward | grep -v grep | grep prometheus | awk '{print $2}')
Nu kan vi visualisere DCGM-metrikkene via Grafana Dashboard.
- Hent adgangskoden for at logge ind på Grafana UI
kubectl -n prometheus get secret $(kubectl -n prometheus get secrets | grep grafana | cut -d ' ' -f 1) -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
- Port-forward Grafana tjenesten
Kør følgende kommandolinje i din værtsshell:
kubectl port-forward -n prometheus svc/$(kubectl -n prometheus get svc | grep grafana | cut -d ' ' -f 1) 8080:80 &
- Log ind på Grafana UI
Få adgang til Grafana UI-loginskærmen på samme måde, som du tidligere fik adgang til Prometheus UI. Hvis du bruger Cloud9, skal du vælge Preview->Preview Running Application
, og spring derefter ud i et nyt vindue. Hvis du bruger din lokale vært eller en EC2-instans med fjernskrivebord, besøg URL http://localhost:8080
. Log på med brugernavnet admin og den adgangskode, du hentede tidligere.
- Vælg i navigationsruden Dashboards
- Vælg Ny , Importere
Vi skal importere standard DCGM Grafana-dashboardet beskrevet i NVIDIA DCGM eksportør Dashboard.
- I marken
import via grafana.com
, gå ind 12239
Og vælg Load
- Vælg Prometheus som datakilde
- Vælg Importere
Du vil se et dashboard, der ligner det i det følgende skærmbillede.
For at demonstrere, at disse målinger er pod-baserede, vil vi ændre GPU-udnyttelse rude i dette dashboard.
- Vælg ruden og indstillingsmenuen (tre prikker)
- Udvid Indstillinger sektion og rediger Legend felt
- Erstat værdien der med
Pod {{pod}}
, Og vælg derefter Gem
Legenden viser nu gpu-burn
podnavn knyttet til den viste GPU-udnyttelse.
- Stop port-videresendelse af Grafana UI-tjenesten
Kør følgende i din værtsshell:
kill -9 $(ps -aef | grep port-forward | grep -v grep | grep prometheus | awk '{print $2}')
I dette indlæg demonstrerede vi brugen af open source Prometheus og Grafana implementeret til EKS-klyngen. Hvis det ønskes, kan denne udrulning erstattes med Amazon Managed Service for Prometheus , Amazon administrerede Grafana.
Ryd op
For at rydde op i de ressourcer, du har oprettet, skal du køre følgende script fra aws-do-eks
beholderskal:
Konklusion
I dette indlæg brugte vi NVIDIA DCGM Exporter til at indsamle GPU-metrics og visualisere dem med enten CloudWatch eller Prometheus og Grafana. Vi inviterer dig til at bruge de her demonstrerede arkitekturer til at aktivere GPU-udnyttelsesovervågning med NVIDIA DCGM i dit eget AWS-miljø.
Yderligere ressourcer
Om forfatterne
Amr Ragab er tidligere Principal Solutions Architect, EC2 Accelerated Computing hos AWS. Han er dedikeret til at hjælpe kunder med at køre beregningsmæssige arbejdsbelastninger i stor skala. I sin fritid kan han godt lide at rejse og finde nye måder at integrere teknologi i dagligdagen.
Alex Iankoulski er Principal Solutions Architect, Self-managed Machine Learning hos AWS. Han er en fuld stack software- og infrastrukturingeniør, der kan lide at udføre dybt, praktisk arbejde. I sin rolle fokuserer han på at hjælpe kunder med containerisering og orkestrering af ML- og AI-arbejdsbelastninger på containerdrevne AWS-tjenester. Han er også forfatter til open source lave rammer og en Docker-kaptajn, der elsker at anvende containerteknologier til at accelerere innovationstempoet og samtidig løse verdens største udfordringer. I løbet af de sidste 10 år har Alex arbejdet på at demokratisere AI og ML, bekæmpe klimaændringer og gøre rejser sikrere, sundhedspleje bedre og energismartere.
Keita Watanabe er Senior Solutions Architect of Frameworks ML Solutions hos Amazon Web Services, hvor han hjælper med at udvikle branchens bedste cloud-baserede Self-managed Machine Learning-løsninger. Hans baggrund er i Machine Learning forskning og udvikling. Før han kom til AWS, arbejdede Keita i e-handelsindustrien. Keita har en ph.d. i naturvidenskab fra University of Tokyo.
- SEO Powered Content & PR Distribution. Bliv forstærket i dag.
- PlatoData.Network Vertical Generative Ai. Styrk dig selv. Adgang her.
- PlatoAiStream. Web3 intelligens. Viden forstærket. Adgang her.
- PlatoESG. Automotive/elbiler, Kulstof, CleanTech, Energi, Miljø, Solenergi, Affaldshåndtering. Adgang her.
- PlatoHealth. Bioteknologiske og kliniske forsøgs intelligens. Adgang her.
- ChartPrime. Løft dit handelsspil med ChartPrime. Adgang her.
- BlockOffsets. Modernisering af miljømæssig offset-ejerskab. Adgang her.
- Kilde: https://aws.amazon.com/blogs/machine-learning/enable-pod-based-gpu-metrics-in-amazon-cloudwatch/