Kubernetes 에서 GPU 를 사용하는 Container 를 운영하려면, 어떻게 해야 할까요?




Kubernetes 에서 NVIDIA GPU Container 실행하기


기존에 Docker 에서 GPU Container 를 실행시키는 것은 간단했습니다.

그리고 GPU Resource 를 몇 개를 쓸 것인가 하는 것은 Docker-Compose 나 Environment Variable 을 사용했습니다.

Kubernetes 에서는 Docker-Compose 를 사용하는것이 아니기 때문에, 이런 부분에 대해서 다시 고민을 해야 합니다.




Worker Node 에서의 설정




기존에 Docker에서 GPU 를 사용하는 방법에 대해서 포스팅 했습니다.

요약을 해 보자면, 당연히 Docker 를 설치해야 하고, 이후에 nvidia-docker2 를 설치했습니다.

http://crystalcube.co.kr/196?category=834418


그리고나서 GPU Container 를 실행하기 위해서 --runtime=nvidia 와 같이 옵션을 주거나, docker 대신 nvidia-docker 를 사용해서 Container 를 올렸습니다.


그러나 Kubernetes 에서 실행하려면 방법이 좀 다릅니다.

먼저 GPU 를 지원하는 Worker Node 에서 docker 의 기본 runtime 을 nvidia 로 고정시켜 주어야 합니다.

정상적으로 nvidia-docker2 를 설치했다면, 아래 경로에 daemon.json 이라는 파일이 보일 것입니다.


# ls -alF /etc/docker/daemon.json

-rw-r--r--. 1 root root 169 Sep  5 18:25 /etc/docker/daemon.json



파일을 열어서 아래처럼 수정해 줍니다.

"default-runtime": "nvidia", 한 줄을 추가시켜 주었습니다.


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

수정이 되었으면, 중요한 작업이 있습니다.

바로 docker daemon 을 재시작 하는 것입니다. 재시작 하지 않으면 반영이 안됩니다.


$ sudo systemctl restart docker



이것으로 Worker Node 에서 해야 할 설정은 끝이 났습니다. :)






Master Node 에서의 설정




Master Node 에서는 kubernetes-device-plugin 을 설치해 주어야 합니다.

공식 설치관련 주소는 아래와 같습니다.

https://github.com/NVIDIA/k8s-device-plugin



아래 명령을 통해서 Master Node 에 플러그인을 설치해 줍니다.


$ kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.11/nvidia-device-plugin.yml


설치가 끝나고나면, kube-system 네임스페이스에 nvidia-device-plugin 의 pod 가 올라가 있는 것을 볼 수 있습니다.




이것으로 모든 준비가 끝이 났습니다. :)






GPU Container 올리기




당연히 해당 Container 를 Deployment 할때는, 셀렉터를 통해서 GPU 가 가능한 node 만 골라서 deploy 해야 합니다.

그렇게 하지 않더라도 resource 제약을 걸면, DeploymentController 가 알아서 각 노드에 설치를 시도하고, 실패하면 여차저차 어찌됬든 GPU 가 설치된 노드를 찾긴 하는 것 같습니다.

사실 찾는다는 표현보다는 여기저기 시도하다보니까 찾아진거겠지요.

아무튼 레이블과 Selector 를 통해서 GPU 노드를 잘 관리해 줍니다.


GPU Container 를 올리는 방법은 별다를게 없습니다. 그냥 올리면 됩니다 :)


그런데, Container 에서 사용할 수 있는 GPU 의 리소스는 어떻게 제어할 수 있을까요?

현재 nvidia-device-plugin v 1.11 버전에서는 limits 를 통해 사용할 GPU 갯수만 지정할 수 있습니다.

GPU 의 메모리를 지정할 수 없으며, request 도 사용할 수 없습니다. 오로지 갯수만 지정 가능합니다.


그래서 GPU 가 2개가 있는 Node 의 경우, gpu limit 를 1로 지정한 Container 를 최대 2개까지만 올릴 수 있게 됩니다.

Node 에 GPU 가 2개 인데, 2개 이상의 Container 를 올리려면, limit 지정을 하지 않으면 됩니다. :)

요컨데 limit  를 지정하면, 해당 갯수의 GPU 를 오롯이 해당 Container 에게 주게 됩니다.


아래처럼 resources 에서 limit 를 통해 지정 가능합니다.


apiVersion: v1
kind: Pod
metadata:
  name: cuda-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: cuda-vector-add
      # https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
      image: "k8s.gcr.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1 # requesting 1 GPU