k8s-device-plugin使用指南
k8s-device-plugin概述
我们提供了Kubernetes设备插件stc-k8s-device-plugin,方便您在无需修改Kubernetes核心代码情况下,即可实现包含NPU设备的通用解决方案。部署stc-k8s-device-plugin后,在创建Pod时Kubernetes集群会自动申请使用NPU设备,并跟踪NPU设备的健康状况。
使用k8s-device-plugin申请NPU设备
前提条件
-
安装Kubernetes,支持1.18、1.22、1.23和1.24版本,推荐使用1.18版本。
-
部署Kubernetes集群。
-
在主机上部署异构环境。
说明:目前在主机上有两种方式部署异构环境。采取整包安装方式部署,所有配套软件都将安装在主机侧上。采取Docker安装方式部署,HPE驱动模块安装在主机上,其他模块安装在容器中。安装方式将影响后续创建Pod的方式。
-
获取stc-k8s-device-plugin的工具包。
部署设备插件
-
登录Kubernetes集群的master节点。
-
解压stc-k8s-device-plugin工具包并进入插件目录。以工具包名称为stc-k8s-device-plugin-1.0.1.tgz为例:
$ tar -xvzf stc-k8s-device-plugin-1.0.1.tgz
$ cd stc-k8s-device-plugin-1.0.1
$ ls
Dockerfile go.mod go.sum main.go pod README.md stc-device-plugin.yaml -
构建设备插件镜像。目前提供两种方式:
-
基于插件目录下的Dockerfile构建设备插件镜像,Dockerfile的详细内容,请参见文件示例章节。以为设备插件镜像添加标签stc/k8s-device-plugin为例,示例命令如下:
$ docker build -t stc/k8s-device-plugin . -
基于离线镜像包导入设备插件镜像。以导入stc-k8s-device-plugin-1_0_1.tar镜像包为例,示例命令如下:
$ docker load -i stc-k8s-device-plugin-1_0_1.tar
说明:联系技术支持获取离线镜像包。
-
-
查看构建或导入好的设备插件镜像,即标签为stc/k8s-device-plugin的镜像。
$ docker images | grep k8s-device-plugin
REPOSITORY TAG IMAGE ID CREATED SIZE
stc/k8s-device-plugin latest f8edbe727b00 2 minutes ago 827MB 3.4.3-0 303ce5db0e90 3 years ago 288MB -
基于插件目录下的YAML文件在Kubernetes集群中部署设备插件,YAML文件的详细内容,请参见文件示例章节。
说明:部署插件时采用创建DaemonSet的方式,新增节点上的NPU设备会自动加入资源池。
$ kubectl apply -f stc-device-plugin.yaml
daemonset.apps/stc-device-plugin-daemonset created -
检查部署结果。如果插件部署成功,查看pod时会出现名称以
stc-device-plugin-daemonset开头的DaemonSet,且状态为Running。以master节点的主机名称为k8smasterdemo为例:$ kubectl get pods -n kube-system | grep stc-device-plugin
NAME READY STATUS RESTARTS AGE
stc-device-plugin-daemonset-hlpgt 1/1 Running 0 7s
创建Pod并申请NPU设备
本章节演示如何在创建Pod时申请NPU设备,并在Pod中使用已部署的异构环境。
说明:在创建Pod时,Pod镜像的OS和VM的OS需保持一致,否则可能因glibc、gcc等基础软件不匹配出现异常。
以基于Ubuntu 22.04的Pod为例:
-
进入插件目录stc-k8s-device-plugin-1.0.1。
-
使用示例配置创建一个Pod。
-
构建Pod镜像,目前根据HPE安装方式的不同,可分为映射场景和非映射场景。
-
若HPE采取整包方式安装,所有配套软件都安装在主机上。构建Pod镜像,可采用映射的方式获取HPE相关库。示例如下,Dockerfile的详细内容,请参见文件示例章节。
$ docker build -t stc/k8s-pod-example pod/ -
若HPE驱动模块安装在主机上,其他模块安装在容器中。构建Pod镜像,可采用非映射的方式,需要将HPE相关库安装在Pod中。构建Pod镜像示例如下,Dockerfile的详细内容,请参见文件示例章节。
$ DOCKER_BUILDKIT=1 docker build -f Dockerfile -t stc/k8s-pod-example --build-arg URI=http://example.com --target dev .
-
-
查看构建好的Pod镜像,即标签为stc/k8s-pod-example的镜像。
$ docker images | grep k8s-pod-example
REPOSITORY TAG IMAGE ID CREATED SIZE
stc/k8s-pod-example latest 35dac764fd1f 1 minutes ago 114MB -
基于pod目录下YAML文件创建一个名为stc-example-pod的Pod,YAML文件的详细内容,请参见文件示例章节。
$ kubectl apply -f pod/example.yaml
-
-
检查Pod的运行状态,确定状态为Running。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
stc-example-pod 1/1 Running 0 10s -
在Pod中验证NPU设备可用。
-
通过容器的Shell访问。以Bash为例,打开一个Bash终端后输入Shell命令即可。该示例过程中Kubernetes集群会将控制台输入发送到stc-example-pod中第一个容器的Shell,并将输出返回到控制台。如果成功访问到设备,会返回NPC的response。
注意:采用映射方式构建的Pod,example文件下的文件在主机侧编译后,在Pod中可直接运行。采用非映射方式构建的Pod,example文件下的文件需先在Pod中编译后才能运行。
$ kubectl exec -it stc-example-pod -- bash
root@stc-example-pod:/# cd /usr/local/hpe/example
root@stc-example-pod:/usr/local/hpe/example# ./hello_world
host call hello_world on device......
hello world from device -
您也可以通过kubectl命令访问。如果成功访问到设备,会返回NPC的response。
$ kubectl exec stc-example-pod -- /usr/local/hpe/example/hello_world
host call hello_world on device......
hello world from device
-
文件示例
Dockerfile(构建设备插件镜像)
FROM ubuntu:bionic
RUN apt-get update \
&& apt-get install -y vim \
&& apt-get install -y coreutils \
&& apt-get install -y bash \
&& apt-get install -y wget
RUN wget -nv -O - https://storage.googleapis.com/golang/go1.16.4.linux-amd64.tar.gz \
| tar -C /usr/local -xz
ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
WORKDIR /gosrc/k8s-device-plugin
COPY * ./
RUN go version
RUN go env -w GOPROXY=https://goproxy.cn
RUN go env -w GOSUMDB=off
RUN go build
RUN cp k8s-device-plugin /usr/bin/
CMD ["k8s-device-plugin"]
stc-device-plugin.yaml(在Kubernetes集群中部署设备插件)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: stc-device-plugin-daemonset
namespace: kube-system
spec:
selector:
matchLabels:
name: stc-device-plugin-ds
template:
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
labels:
name: stc-device-plugin-ds
spec:
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- key: streamcomputing.com/npu
operator: Exists
effect: NoSchedule
containers:
- image: stc/k8s-device-plugin
imagePullPolicy: IfNotPresent
name: stc-device-plugin-ctr
securityContext:
privileged: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
- name: dev
mountPath: /dev
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
- name: dev
hostPath:
path: /dev
Dockerfile(构建Pod镜像采用映射方式获取HPE相关库)
FROM ubuntu:22.04
ENV LD_LIBRARY_PATH /usr/local/hpe/lib:$LD_LIBRARY_PATH
RUN ln -s /usr/local/hpe/bin/clang++ /usr/bin/stc-clang++
RUN ln -s /usr/local/hpe/bin/stcc /usr/bin/stcc
RUN ln -s /usr/local/hpe/bin/lld /usr/bin/stc-ld.lld
Dockerfile(构建Pod镜像采用非映射方式获取HPE相关库)
以在Ubuntu 22.04上构建STCRP1.9.0版本为例:
FROM scratch AS base
COPY pip.conf /mnt/pip.conf
COPY jupyter_notebook_config.json /mnt/jupyter_notebook_config.json
COPY tini /mnt/tini
#FROM harbor.streamcomputing.com/devops/ubuntu:22.04 AS final
FROM harbor.streamcomputing.com/nvidia/tritonserver:24.05-py3-base AS final
ENV PYTHONIOENCODING=UTF-8
ENV RISCV=/usr/local/hpe
ENV TZ=Asia/Shanghai
ARG URI
ARG HPE_REPO=hpe-repo-ubuntu2204-1-9-local_1.9.3_amd64.deb
ARG MLTC_install_file=mltc-1.3.0-cp310-cp310-linux_x86_64.whl
ARG STCNQ_install_file=stcnq-1.0.0-py3-none-any.whl
ARG STC_LLM_MLTC_install_file=stc_llm_mltc-1.3.0-py3-none-any.whl
ARG STCNC_install_file=stcnc-1.0.1-py3-none-any.whl
ARG HPE_PYTHON_install_file=hpe_python-1.4.0-cp310-cp310-linux_x86_64.whl
ENV PASSWORD=666666
WORKDIR /workspace
RUN --mount=type=bind,from=base,source=/mnt,target=/mnt,rw \
sed -i "s/archive\.ubuntu\.com/mirrors.tuna.tsinghua.edu.cn/g; s/security\.ubuntu\.com/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list \
&& mkdir -p ~/.pip && cp /mnt/pip.conf ~/.pip/pip.conf \
&& apt-get update \
&& apt install -y wget && wget http://apt.streamcomputing.com/docker_sources_mirror.sh -O docker_sources_mirror.sh && bash docker_sources_mirror.sh \
&& apt-get install -y wget gpg-agent gnupg ca-certificates sudo make cmake gcc g++ libopenblas-dev libopenmpi3 libnuma-dev --no-install-recommends \
&& wget ${URI}/${HPE_REPO} -O /tmp/hpe.deb \
&& dpkg -i /tmp/hpe.deb \
&& sudo cp /var/hpe-repo-*-local/hpe-*.gpg /usr/share/keyrings/ \
&& apt-get update \
&& apt-get install hpe-simple -y \
&& pip3 install ${URI}/${MLTC_install_file} ${URI}/${STC_LLM_MLTC_install_file} ${URI}/${HPE_PYTHON_install_file} \
&& pip3 install ${URI}/${STCNQ_install_file} ${URI}/${STCNC_install_file} \
&& pip3 install sentencepiece onnx onnxruntime jupyterlab opencv-python \
&& apt-get install vim tree openssh-server unzip gdb -y \
&& echo 'root:666666' | chpasswd \
&& echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config \
&& mkdir -p /run/sshd \
&& pip3 install jupyter jupyterlab qgrid ipywidgets \
ipython \
ipython-sql \
jupyterlab-git \
jupyterlab-lsp \
python-lsp-server[all] \
jupyterlab-language-pack-zh-CN \
# && pip install torch==2.0.1+cpu torchvision==0.15.2+cpu --extra-index-url https://download.pytorch.org/whl/cpu \
&& cp /mnt/jupyter_notebook_config.json /jupyter_notebook_config.json \
&& cp /mnt/tini /usr/bin/tini \
&& chmod +x /usr/bin/tini \
&& rm -rf /root/.cache /tmp/hpe.deb /var/lib/apt/lists/*
EXPOSE 8888 22 8080
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["jupyter", "lab", "--port=8888", "--no-browser", "--allow-root", "--ip=0.0.0.0", "--config=/jupyter_notebook_config.json"]
example.yaml(创建Pod)
Pod名为stc-example-pod,目前仅支持以一个NPU为最小粒度申请,并限制申请一个NPU设备。
# example of a POD running sleep 100000 and allocated 1 NPU device
apiVersion: v1
kind: Pod
metadata:
name: stc-example-pod
spec:
# restartPolicy: OnFailure
containers:
- image: stc/k8s-pod-example
imagePullPolicy: IfNotPresent
name: stc-example-ctr
command: ["sleep"]
args: ["100000"]
volumeMounts:
- name: hpelink
mountPath: /usr/local/hpe
resources:
limits:
streamcomputing.com/npu: 1
volumes:
- name: hpelink
hostPath:
path: /usr/local/hpe