k8s with Nvidia GPU node

cloud2000·2023년 10월 16일

이전에 nvidia V100 GPU를 포함한 k8s cluster를 구축하고 테스트 한 적이 있는데, 이번에 새로 구성할 필요가 있어 변경된 사항을 정리하고 테스트 해 본다.

이전에는 https://nvidia.github.io/nvidia-docker 에서 설치문서를 확인했으나 현재 해당 페이지에 가보면 https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html 를 참조하도록 되어 있다.

이제 최신 문서인 NVIDIA Container Toolkit를 활용하여 설치해 보자.

  1. nvidia GPU hareware를 아래 명령으로 확인할 수 있다.
lshw -C display
  1. nvidia-driver 설치
  • 우분투에서 apt search 명령으로 설치 가능한 nvidia-driver를 조회하고 최신 버전을 설치한다.
apt search nvidia-driver

apt update
apt upgrade
apt install nvidia-driver-510 nvidia-dkms-510

// 시스템을 reboot하여 GPU 를 인식하게 한다.
sudo reboot
  • 아래 명령(nvidia-smi, nvidia System Management Interface)으로 GPU 장치 관리와 모니터링을 할 수 있다.
nvidia-smi
  1. CRI를 containerd로 사용
  • kubernetes v1.20 이후 부터는 CRI로 docker가 deprecated되었음으로 containerd를 CRI로 사용할 떄의 설치과정을 알아본다.
  • 먼저, nvidia-container-toolkit 설치하고 containerd의 설정에 nvidia-container-runtime을 추가한다. 이후 k8s에 nvidia device plugin을 설치하여 GPU를 사용하는 pod가 해당 node에 스케줄되도록 구성한다.

4.1. nvidia container toolkit 서치
root 계정으로 nvidia container toolkit을 설치한다.

$ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-tookit-keyring.gpp \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \
&& apt-get update

$ apt-get install -y nvidia-container-toolkit
cat <<EOF > /etc/yum.repo.d/nvidia-container-toolkit.repo
[nvidia-container-toolkit]
name=nvidia-container-toolkit
baseurl=https://nvidia.github.io/libnvidia-container/stable/rpm/$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://nvidia.github.io/libnvidia-container/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt

[nvidia-container-toolkit-experimental]
name=nvidia-container-toolkit-experimental
baseurl=https://nvidia.github.io/libnvidia-container/experimental/rpm/$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=0
gpgkey=https://nvidia.github.io/libnvidia-container/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt

4.2. containerd 구성파일에 nvidia-container-runtime 구성
nvidia-ctk 명령을 사용하면 편리하게 구성을 추가할 수 있다.

vi /etc/containerd/config.toml
nvidia-ctk runtime configure --runtime=containerd

systemctl restart containerd

4.3 containerd에서 gpu 사용확인

$ sudo ctr image pull docker.io/nvidia/cuda:11.0.3-base-ubuntu20.04
$ sudo ctr run --rm -t \
    --runc-binary=/usr/bin/nvidia-container-runtime \
    --env NVIDIA_VISIBLE_DEVICES=all \
    docker.io/nvidia/cuda:11.0.3-base-ubuntu20.04 \
    cuda-11.0.3-base-ubuntu20.04 nvidia-smi

4.4. kubernetes에서 nvidia device plugin 데몬셋 설치

k8s nvidia plugin은 다음과 같은 역할을 수행한다.

  • 클러스터의 각 노드들에 달려있는 gpu수를 파악
  • gpu의 상태를 지속적으로 트래킹
  • k8s클러스터 내 container가 gpu를 사용할수 있도록 함

https://github.com/NVIDIA/k8s-device-plugin 을 참고하면 간단히 daemonset을 배포하여 설치할 수도 있고, helm을 통해서 다양한 커스텀이 가능하다.

먼저 GPU node에 label을 아래와 같이 지정한다.

kubectl label nodes [gpu가 장착된 노드명 1] gpu=nvidia

Nvidia device plugin daemonset을 배포한다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nvidia-device-plugin-daemonset
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: nvidia-device-plugin-ds
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        name: nvidia-device-plugin-ds
    spec:
+      nodeSelector:
+          gpu: nvidia
      tolerations:
      - key: nvidia.com/gpu
        operator: Exists
        effect: NoSchedule
      # Mark this pod as a critical add-on; when enabled, the critical add-on
      # scheduler reserves resources for critical add-on pods so that they can
      # be rescheduled after a failure.
      # See https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/
      priorityClassName: "system-node-critical"
      containers:
      - image: nvcr.io/nvidia/k8s-device-plugin:v0.12.3
        name: nvidia-device-plugin-ctr
        env:
          - name: FAIL_ON_INIT_ERROR
            value: "false"
        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
  • RuntimeClass 생성
$ nvidia-runtime-class.yml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  # The name the RuntimeClass will be referenced by.
  # RuntimeClass is a non-namespaced resource.
  name: "nvidia"
# The name of the corresponding CRI configuration
handler: "nvidia"

kubectl apply -f nvidia-runtime-class.yml

4.5 테스트

apiVersion: v1
kind: Pod
metadata:
  name: gpu
spec:
  restartPolicy: Never
  runtimeClassName: "nvidia" # nvidia runtime 사용
  nodeSelector: 
    gpu: nvidia # gpu가 장착된 node에만 배포
  containers:
    - name: gpu
      image: "nvidia/cuda:11.4.1-base-ubuntu20.04"
      command: [ "/bin/bash", "-c", "--" ]
      args: [ "while true; do sleep 30; done;" ]
      
kubectl apply -f test-gpu-pod.yml
kubectl exec -it gpu -- nvidia-smi
Wed Sep 28 03:03:22 2022       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.85.02    Driver Version: 510.85.02    CUDA Version: 11.6     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  Off  | 00000000:03:00.0 Off |                  N/A |
| N/A   39C    P8    N/A /  N/A |      4MiB /  4096MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+
profile
클라우드쟁이

0개의 댓글