AWS上のkubernetesでGPUを使う
ということで、今日は、AWS上のk8sでGPUを使ってみましょう。
事前に用意するもの
- kubernetes cluster (1.9.3で確認)
- kops (1.8.1で確認)
AMIの作成
099720109477/ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20180222 (ami-06d9a360)のイメージを使ってEC2を用意します。イメージを作るだけなのでt2.microでもいいのですが、確認のためにp2.xlargeインスタンスを用意しましょう。あ、ストレージは16GBぐらいにしておくと安全です。8GBでは足りません。
ssh ubuntu@<ip address>して、以下のスクリプトを実行します。手作業で実行したのをscript形式にしたので、そのまま実行したらこけるかもしれませんので、適宜修正してください。
注意点は dockerのバージョンです。docker-ceではk8sが対応しておらずkopsがnodeの設定をできないので、docker-engine 1.13.1を指定します。また、nvidia-docker2のバージョン指定も気をつけます。install時に"nvidia-docker2=2.0.3+docker1.13.1-1"とdockerのバージョンも含めて指定してあげる必要があります。
とはいえ、そろそろdocker-ceでも動くようにはなるので、近いうちにバージョンの問題はなくなる可能性が高いです。
#!/usr/bin/bash
sudo apt-get update && sudo apt-get install -y build-essential
# install NVIDIA driver
wget http://jp.download.nvidia.com/XFree86/Linux-x86_64/390.25/NVIDIA-Linux-x86_64-390.25.run
sudo sh NVIDIA-Linux-x86_64-390.25.run --silent
# install CUDA toolkit
wget https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux
sudo sh cuda_9.1.85_387.26_linux --silent --toolkit --no-man-page
# install nvidia-docker and docker-engine 1.13.1
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/debian9/amd64/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common
echo 'deb https://apt.dockerproject.org/repo ubuntu-xenial main' | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update
sudo apt-get install -y "docker-engine=1.13.1-0~ubuntu-xenial"
sudo apt-get install -y "nvidia-docker2=2.0.3+docker1.13.1-1" "nvidia-container-runtime=2.0.0+docker1.13.1-1"
# add `-s=overlay2` to docker
sudo sed -i -e 's/fd:\/\//fd:\/\/ -s=overlay2/g' /lib/systemd/system/docker.service
# set default docker runtime to default using nvidia runtime
sudo tee /etc/docker/daemon.json <<EOF
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
EOF
# restart
sudo pkill -SIGHUP dockerd
sudo systemctl restart docker.service
最後に
sudo docker run --rm nvidia/cuda nvidia-smi
してnvidia-dockerではなく、dockerコマンドでnvidia-smiが動くかどうか確認しましょう。確認がすんだら、docker pullされたnvidia/cudaのdocker イメージを消してAMIを作成しておきます。
GPUインスタンスの立ち上げ
準備したAMIをkops用のspec.imageに記述しつつ、kops用のresourceファイルを用意します。注意して欲しいところはspec.kubelet.featureGates.DevicePluginsを指定することです。これがないと、後のDeviceDriverがGPUを認識してくれません。
(念の為書いておくと、kops get ig nodes -oyamlすると、現在のnode設定をyamlで書き出してくれるのでそれを修正していきます)
apiVersion: kops/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: null
labels:
kops.k8s.io/cluster: gpu.alpaca.k8s.local
name: gpu
spec:
image: ami-1234569
kubelet:
featureGates:
DevicePlugins: "true"
machineType: p2.xlarge
maxPrice: "1.0"
maxSize: 1
minSize: 1
nodeLabels:
kops.k8s.io/instancegroup: gpu
role: Node
subnets:
- ap-northeast-1a
その後、
% kops create -f stg-gpu-nodes.yml
% kops update cluster gpu.alpaca.k8s.local --yes
でGPUインスタンスが立ち上がります。
DevicePluginのインストール
さて、次にKubernetesからGPUを扱うようにするために、Device Pluginを入れます。
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.9/nvidia-device-plugin.yml
daemon set として各nodeにインストールされます。
kubectl get nodes -oyaml | grep gpuとすると、nvidia.com/gpu: "1"と出てきたら成功です。(順番は関係ないとは思いますが、もしかしたら、再度gpu-nodeを作りなおしたほうがいいのかもしれません)
使ってみる
適当なpodを立ち上げてnvidia-smiを実行してみます。
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
namespace: stg
spec:
nodeSelector:
kops.k8s.io/instancegroup: gpu
containers:
- name: cuda-container
image: nvidia/cuda
resources:
limits:
nvidia.com/gpu: 1 # requesting 1 GPUs
command:
- "nvidia-smi"
無事実行できれば成功です。
参考文献
- Setting up a GPU Enabled Kubernetes for Deep Learning-https://itnext.io/setting-up-a-gpu-enabled-kubernetes-for-deep-learning-aef8e198931b
- pachyderm doc Utilizing GPUs-http://docs.pachyderm.io/en/latest/cookbook/gpus.html