聲明
本文所有內容基於Docker,k8s集群由rancher提供的rke工具搭建(后文中稱為rancher版本k8s,也適用於使用RancherUI搭建的集群),GPU共享技術采用了阿里GPU Sharing。使用了其他容器技術的本文不一定適用,或者使用了kubeadm進行k8s搭建的可能有部分不適用,kubeadm搭建的k8s在部署GPU Sharing時網上可查的資料和官網資料都很多,而rancher版本的k8s和原生kubernetes有所差別,后面會夾帶一些具體說明。
准備工作
++如果你已經有了Rancher版本的K8S集群,則直接從「k8s集群搭建」開始看++
安裝docker和nvidia-docker2
安裝Docker,直接執行官方安裝腳本安裝:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
安裝完成后,使用Docker version
查看版本,目前安裝的話一般為20.10版本,能成功查詢版本說明安裝成功。
安裝之后,執行以下命令設置docker自啟動:
systemctl start docker
systemctl enable docker
nvidia-docker2安裝參見上一篇文章《Ubuntu實現K8S調度NVIDIA GPU小記》安裝nvidia-docker安裝部分。
在安裝完之后,我們需要修改docker默認的運行時,使其支持nvidia的調度,編輯/etc/docker/daemon.json
配置(不存在則新建):
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
},
"default-runtime": "nvidia",
"exec-opts": ["native.cgroupdriver=systemd"]
}
其中:runtimes
參數是定義運行時,這里定義了一個名為nvidia的運行時環境,default-runtime
表示指定默認的運行時為剛剛定義的nvidia
。
最后一句"exec-opts": ["native.cgroupdriver=systemd"]
的作用是,因為K8S的文件驅動為cgroupfs,而docker的文件驅動為systemd,兩者不同會導致鏡像無法啟動,因此需要將K8S文件驅動也指定為systemd。
GPU驅動
GPU驅動安裝和簡單調度參見上一篇文章《Ubuntu實現K8S調度NVIDIA GPU小記》英偉達驅動部分。
下載rke工具
下載rke之前,需要確定你是否需要指定版本的k8s集群或者指定版本的rancher,在github中rancher倉庫中,可以在對應的rancher版本中查看到其支持的k8s版本和所需的rke工具版本,相反,你確定了需要的k8s版本也可以反推rancher版本和rke版本。
我這里的需求是使用rancher2.3.8,對應的rke版本為1.0.9,rke-1.0.9對應的k8s版本如下:
這里我k8s版本采用的是v1.17.6-rancher2-1
版本。
確定了各種工具版本之后,下載對應的工具,此處鏈接根據需求更換,不是一成不變的:
# 下載rke
wget https://github.com/rancher/rke/releases/download/v1.0.9/rke_linux-amd64
# 配置rke
mv rke_linux-amd64 rke
chmod 755 rke
mv rke /usr/local/bin/
#驗證
rke --version
k8s集群搭建
rke需要根據yaml文件來進行集群的創建,我這里使用的是單節點,首先來創建rke集群文件目錄:
mkdir rke-config
cd rke-config
以下是rke集群文件的內容,使用vim 進行編輯,vim cluster.yml
,如果你有現有的集群,就對你的集群yaml進行編輯,在services下添加scheduler節點的所有內容即可(也適用於直接使用rancher創建的集群,只不過是通過rancher-ui進行操作):
nodes:
- address: 192.168.1.102
user: root
role:
- controlplane
- etcd
- worker
services:
scheduler:
extra_args:
address: 0.0.0.0
kubeconfig: /etc/kubernetes/ssl/kubecfg-kube-scheduler.yaml
leader-elect: 'true'
policy-config-file: /etc/kubernetes/ssl/scheduler-policy-config.json
profiling: 'false'
v: '2'
kubernetes_version: "v1.17.6-rancher2-1"
cluster_name: "aliyun"
nodes配置節點是配置集群的主機,此處為單節點,因此角色需要包含control、etcd和worker三種。services下的scheduler節點是指定調度的相關配置,這里就是一個rancher版本k8s和原生k8s不一樣的地方,原生k8s中,kube-scheduler作為一個可執行文件存在,而在rancher中是一個容器,scheduler節點部分的內容可以通過docker inspect kube-scheduler
查看到,這里只需要復制過來並添加policy-config-file: /etc/kubernetes/ssl/scheduler-policy-config.json
即可。
我們從github上獲取scheduler-policy-config.json,放到/etc/kubernetes/ssl/下,如果有多個master節點,則每個master節點都需要執行:
cd /etc/kubernetes/ssl/
curl -O https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/config/scheduler-policy-config.json
然后,構建集群,需要進入到上一步創建的cluster.yml的目錄下:
rke up
如果提示docker版本不支持,則添加參數忽略版本即可:
rke up --ignore-docker-version
待執行完畢,此時集群就搭建好了,之后進行如下配置:
mkdir ~/.kube
# kube_config_cluster.yml文件為rke up創建集群時在當前目錄生成
cp kube_config_cluster.yml ~/.kube
mv ~/.kube/kube_config_cluster.yml ~/.kube/config
接下來安裝kubectl來管理集群:
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
# 配置kubectl
chmod 755 ./kubectl
mv ./kubectl /usr/local/bin/kubectl
# 查看版本
kubectl version
使用kubectl查看pod:
# 查看pod
kubectl get pods
自此,k8s集群搭建完畢,接下來做GPU共享配置
GPU Sharing部署
- 部署GPU共享調度插件gpushare-schd-extender:
cd /tmp/
curl -O https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/config/gpushare-schd-extender.yaml
# 因為是使用單節點,因此需要能夠在master上進行調度,所以需要在gpushare-schd-extender.yaml中將
# nodeSelector:
# node-role.kubernetes.io/master: ""
# 這兩句刪除,使k8s能夠在master上進行調度
kubectl create -f gpushare-schd-extender.yaml
- 部署設備插件gpushare-device-plugin
如果你的集群不是新搭建的,之前如果已經安裝了nvidia-device-plugin,需要將其刪除,rancher版本的k8s可以使用kubectl get pods看到nvidia-device-plugin相應的pod,刪除即可。然后部署設備插件gpushare-device-plugin:
cd /tmp/
wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-rbac.yaml
kubectl create -f device-plugin-rbac.yaml
wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-device-plugin/master/device-plugin-ds.yaml
# 默認情況下,GPU顯存以GiB為單位,若需要使用MiB為單位,需要在這個文件中,將--memory-unit=GiB修改為--memory-unit=MiB
kubectl create -f device-plugin-ds.yaml
- 為GPU節點打標簽
為了將GPU程序調度到帶有GPU的服務器,需要給服務打標簽gpushare=true
:
# 查看所有節點
kubectl get nodes
# 選取GPU節點打標
kubectl label node <target_node> gpushare=true
# 例如我這里主機名為master,則打標語句為:
# kubectl label node master gpushare=true
- 更新kubectl可執行程序:
wget https://github.com/AliyunContainerService/gpushare-device-plugin/releases/download/v0.3.0/kubectl-inspect-gpushare
chmod u+x kubectl-inspect-gpushare
mv kubectl-inspect-gpushare /usr/local/bin
然后執行kubectl inspect gpushare
,若能看到GPU信息,則代表安裝成功:
可以看到,此時GPU顯存總數為7981MiB,使用為0。
測試
接下來進行測試,我們獲取阿里雲的示例程序:
wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/samples/1.yaml
wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/samples/2.yaml
wget https://raw.githubusercontent.com/AliyunContainerService/gpushare-scheduler-extender/master/samples/3.yaml
這四個文件分別是四個需要調度GPU的示例容器的yaml,直接使用kubectl create -f x.yaml
啟動即可,這些文件中調度的GPU都是以G為單位的,這里我修改了調度數值,調度數值的參數名為:aliyun.com/gpu-mem
,第一個為128,第二個是256,第三個是512,逐個啟動,觀察GPU占用率:
啟動第一個:
啟動第二個:
啟動第三個:
至此,rancher版本k8s配置GPU共享成功。