6
5

More than 5 years have passed since last update.

kubernetesのDevice Plugin "intel device plugins for kubernetes" を試す

Last updated at Posted at 2018-12-12

はじめに

Note:
pluginのデモはR640にFPGA1枚刺し環境では動いたのだが,
R740にFPGA2枚刺し環境だとnlb3(コンテナ内の実行ファイルの名前)がFPGAデバイスを見つけられなかった
./nlb3 -B 0x86 みたいにちゃんとデバイス指定をすれば動くのでデモのtest_fpga.shで2枚刺しを想定した呼び出し方をしていないのが問題っぽい
もう一度確認してみたところちゃんと動きました

追記:
openvino_container_for_PAC
このプラグインを用いてOpenVINOのJobをFPGAで動かす方法をgithubにまとめてupしておきました(結構雑ですが)

kubernetesの公式ページにDevice Pluginsがいくつか載っていますが,

dev_examples.png

その中でも「intel device plugins for kubernetes」を動かすまでのエントリです.

環境 (準備物)

今回はこのプラグインを使用してFPGAがスケジューリングされるかを確認したいので,
Intel PACが刺さったPowerEdge R640をk8sノードとして追加し,PACのドライバを入れておきます.
また,デバイスプラグインをコンパイルするためにGoをインストールしておきます.

  • R640 (with Intel PAC)
    • ↑をk8sのノードとして追加
    • Acceleration Stack環境をインストール
    • Go言語環境をインストール

プラグインのインストール

準備ができたらプラグインのインストールを進めていきます.

プラグインを動かすためには下記の3つが必要となります.
CRD (Custom Resource Definition) を使っているらしい.

  1. FPGA device plugin
  2. FPGA admission controller webhook
  3. FPGA prestart CRI-O hook

1. FPGA device plugin

ここでの作業は,FPGAサーバで行う
device pluginの設定は全てのFPGAサーバで行う必要がある(★1 or ★2あたり).
imageの配布もお忘れなく.

ソースコードを入手

$ mkdir -p $GOPATH/src/github.com/intel/
$ cd $GOPATH/src/github.com/intel/
$ git clone https://github.com/intel/intel-device-plugins-for-kubernetes.git

device pluginのビルド

Goでビルドを行うためGo自体のインストールとGOPATHの設定を予めしておく必要がある.

$ cd $GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes
$ make fpga_plugin

kubelet のソケットが /var/lib/kubelet/device-plugins/ ディレクトリに存在するか確認する

$ ls /var/lib/kubelet/device-plugins/kubelet.sock
/var/lib/kubelet/device-plugins/kubelet.sock

device pluginの動作モードを選ぶ

FPGA device pluginは af モードと region モードがあり,どちらかを選択する必要がある.

af モードは予めAFUを書き込んだFPGAを公開するモード.AFU IDをリソースとして登録することができる.
region モードはFPGAのPA(Partial reconfiguration Area)そのものを公開するモード.FPGAのインタフェースIDをリソースとして登録できる.
という認識...間違ってたら直します:sweat:

af にしたい人は★1へ, region にしたい人は★2へお進み下さい.
自分は,demo (test-fpga-region.yaml) を動かしたいので★1に進みました.
(regionと名前がついているが,afリソースを指定していた)

★1(Case1) Run FPGA device plugin in af mode

1.k8sのadmin権限でプラグインを実行する

$ export KUBE_CONF=/var/run/kubernetes/admin.kubeconfig # path to kubeconfig with admin's credentials
$ export NODE_NAME="<node name>" # if the node's name was overridden and differs from hostname
$ sudo -E $GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes/cmd/fpga_plugin/fpga_plugin -mode af -kubeconfig $KUBE_CONF
FPGA device plugin started in af mode
device-plugin start server at: /var/lib/kubelet/device-plugins/fpga.intel.com-af-f7df405cbd7acf7222f144b0b93acd18.sock
device-plugin registered

2.FPGAサーバにデバイスプラグインが登録されたかを確認する

プラグインを導入した時点でnodeのcapacityとallocatableにFPGAリソースが現れ,FPGAの利用可能な数が表示されるようになります.

$ kubectl describe node <node name> | grep fpga.intel.com
 fpga.intel.com/af-f7df405cbd7acf7222f144b0b93acd18:  1
 fpga.intel.com/af-f7df405cbd7acf7222f144b0b93acd18:  1
★2(Case2) Run FPGA device plugin in region mode

1.k8sのadmin権限でプラグインを実行する

$ export KUBE_CONF=/var/run/kubernetes/admin.kubeconfig # path to kubeconfig with admin's credentials
$ export NODE_NAME="<node name>" # if the node's name was overridden and differs from hostname
$ sudo -E $GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes/cmd/fpga_plugin/fpga_plugin -mode region -kubeconfig $KUBE_CONF
FPGA device plugin started in region mode
device-plugin start server at: /var/lib/kubelet/device-plugins/fpga.intel.com-region-ce48969398f05f33946d560708be108a.sock
device-plugin registered
Check if FPGA device plugin is registered on master:

2.FPGAサーバにデバイスプラグインが登録されたかを確認する

$ kubectl describe node <node name> | grep fpga.intel.com
 fpga.intel.com/region-ce48969398f05f33946d560708be108a:  1
 fpga.intel.com/region-ce48969398f05f33946d560708be108a:  1

3.region の場合はnodeにアノテーション設定する

kubectl annotate node mynode "fpga.intel.com/device-plugin-mode=region

Deploy FPGA device plugin as DaemonSet

1.プラグイン用のサービスアカウントを作成する

$ kubectl create -f deployments/fpga_plugin/fpga_plugin_service_account.yaml
serviceaccount/intel-fpga-plugin-controller created
clusterrole.rbac.authorization.k8s.io/node-getter created
clusterrolebinding.rbac.authorization.k8s.io/get-nodes created

2.デーモンセットの作成

$ kubectl create -f deployments/fpga_plugin/fpga_plugin.yaml
daemonset.apps/intel-fpga-plugin created

3.イメージの作成

$ make intel-fpga-plugin

このイメージはデフォルトで af モードとして動作するので, region モードで動かしたいときは,先程のアノテーション設定が必要.

2. FPGA admission controller webhook

webhookイメージの作成

$ export SRC=$GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes
$ cd $SRC
$ make intel-fpga-admissionwebhook
$ docker images
REPOSITORY                    TAG                                        IMAGE ID            CREATED          SIZE
intel-fpga-admissionwebhook   089ab82d18cceed0217e36a1600d9462018f44d5   267bd3a2524f        7 sec ago        25.2MB
intel-fpga-admissionwebhook   devel                                      267bd3a2524f        7 sec ago        37.7MB

webhooサービスのデプロイ

cfssljq が必要らしいのでインストールしてない人は先にインストールしてから scripts/webhook-deploy.sh 実行しましょう.

$ cd $SRC
$ ./scripts/webhook-deploy.sh
Create secret including signed key/cert pair for the webhook
Creating certs in /tmp/tmp.Ebb77GBKqm
certificatesigningrequest.certificates.k8s.io/intel-fpga-webhook-svc.default created
NAME                             AGE       REQUESTOR      CONDITION
intel-fpga-webhook-svc.default   0s        system:admin   Pending
certificatesigningrequest.certificates.k8s.io/intel-fpga-webhook-svc.default approved
secret/intel-fpga-webhook-certs created
Removing /tmp/tmp.Ebb77GBKqm
Create FPGA CRDs
customresourcedefinition.apiextensions.k8s.io/acceleratorfunctions.fpga.intel.com created
customresourcedefinition.apiextensions.k8s.io/fpgaregions.fpga.intel.com created
acceleratorfunction.fpga.intel.com/arria10-nlb0 created
acceleratorfunction.fpga.intel.com/arria10-nlb3 created
fpgaregion.fpga.intel.com/arria10 created
clusterrole.rbac.authorization.k8s.io/fpga-reader created
clusterrolebinding.rbac.authorization.k8s.io/default-fpga-reader created
Create webhook deployment
deployment.extensions/intel-fpga-webhook-deployment created
Create webhook service
service/intel-fpga-webhook-svc created
Register webhook
mutatingwebhookconfiguration.admissionregistration.k8s.io/fpga-mutator-webhook-cfg created

CRDのリソース定義については af./deployment/fpga_admissionwebhook/af-crd.yaml
region./deployment/fpga_admissionwebhook/region-crd.yaml にあります.
また, AFU ID/Interface ID のマッピングにはmappings-collection.yaml を使います.

例えば,podが要求するリソースに fpga.intel.com/arria10-nlb3 と書くと,
fpga.intel.com/af-f7df405cbd7acf7222f144b0b93acd18 に翻訳され,
fpga.intel.com/af-f7df405cbd7acf7222f144b0b93acd18 をAllocatableにもつノードにpodが立てられます.

図に起こすとこんな感じ.
map.png

3. FPGA prestart CRI-O hook

CRI-O hookのビルド

$ cd $GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes
$ make fpga_crihook

'Acceleration Stack for Runtime' のダウンロード

a10_gx_pac_ias_1_1_pv_rte_installer.tar.gzココからダウンロードして $GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes/deployments/fpga_plugin ディレクトリに保存する

CRI hookとその依存関係など含む init コンテナをビルド

$ cd $GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes/deployments/fpga_plugin
$ ./build-initcontainer-image.sh
...
$ docker images
REPOSITORY                    TAG                                        IMAGE ID            CREATED             SIZE
intel-fpga-initcontainer      devel                                      8d9c9adca145        6 days ago          19MB
intel-fpga-initcontainer      e30f8763c7209577fbaa720addd80271214e8bec   8d9c9adca145        6 days ago          19MB

4. check plugin

プラグインが正しくインストールされたかを確認します.
うまく動いていない場合,動作に必要なimageがノードに配布されているかを確認しましょう.

kubectl get all

うまく動いていれば, pod/intel-fpga-plugin-xxxxxxxx/intel-fpga-webhook-xxxx のステータスがrunningやavailableになっているはずです.

$ k get all --all-namespaces

## POD
NAMESPACE     NAME                                                 READY   STATUS      RESTARTS   AGE
default       pod/intel-fpga-webhook-deployment-7688655c78-9q4kp   1/1     Running     3          6d6h
kube-system   pod/intel-fpga-plugin-zlzn9                          1/1     Running     0          5d21h
...

## Service
NAMESPACE     NAME                             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
default       service/intel-fpga-webhook-svc   ClusterIP   10.109.230.217   <none>        443/TCP         6d6h
...

## deployment
NAMESPACE     NAME                                            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
default       deployment.apps/intel-fpga-webhook-deployment   1         1         1            1           6d6h
...

## replicaset
NAMESPACE     NAME                                                       DESIRED   CURRENT   READY   AGE
default       replicaset.apps/intel-fpga-webhook-deployment-7688655c78   1         1         1       6d6h

kubectl describe

FPGAノードの状態確認

$ k describe no r640-2
Name:               r640-2
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/hostname=r640-2
Annotations:        flannel.alpha.coreos.com/backend-data: {"VtepMAC":"**:**:**:**:**:**"}
                    flannel.alpha.coreos.com/backend-type: vxlan
                    flannel.alpha.coreos.com/kube-subnet-manager: true
                    flannel.alpha.coreos.com/public-ip: *.*.*.*
                    fpga.intel.com/device-plugin-mode: region
                    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Wed, 28 Nov 2018 16:48:15 +0900
Taints:             <none>
Unschedulable:      false
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  OutOfDisk        False   Wed, 05 Dec 2018 17:02:18 +0900   Sat, 01 Dec 2018 12:15:51 +0900   KubeletHasSufficientDisk     kubelet has sufficient disk space available
  MemoryPressure   False   Wed, 05 Dec 2018 17:02:18 +0900   Sat, 01 Dec 2018 12:15:51 +0900   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Wed, 05 Dec 2018 17:02:18 +0900   Sat, 01 Dec 2018 12:15:51 +0900   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Wed, 05 Dec 2018 17:02:18 +0900   Wed, 28 Nov 2018 16:48:15 +0900   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Wed, 05 Dec 2018 17:02:18 +0900   Sat, 01 Dec 2018 12:15:51 +0900   KubeletReady                 kubelet is posting ready status
Addresses:
  InternalIP:  *.*.*.*
  Hostname:    r640-2
Capacity:
 cpu:                                                     16
 ephemeral-storage:                                       51171Mi
 fpga.intel.com/af-d8424dc4a4a3c413f89e433683f9040b:      0
 fpga.intel.com/af-f7df405cbd7acf7222f144b0b93acd18:      0
 fpga.intel.com/region-9926ab6d6c925a68aabca7d84c545738:  1
 hugepages-1Gi:                                           0
 hugepages-2Mi:                                           40Mi
 memory:                                                  131484456Ki
 pods:                                                    110
Allocatable:
 cpu:                                                     16
 ephemeral-storage:                                       48291014167
 fpga.intel.com/af-d8424dc4a4a3c413f89e433683f9040b:      0
 fpga.intel.com/af-f7df405cbd7acf7222f144b0b93acd18:      0
 fpga.intel.com/region-9926ab6d6c925a68aabca7d84c545738:  1
 hugepages-1Gi:                                           0
 hugepages-2Mi:                                           40Mi
 memory:                                                  131341096Ki
 pods:                                                    110
System Info:
 Machine ID:                 *
 System UUID:                *
 Boot ID:                    *
 Kernel Version:             3.10.0-693.el7.x86_64
 OS Image:                   CentOS Linux 7 (Core)
 Operating System:           linux
 Architecture:               amd64
 Container Runtime Version:  docker://18.9.0
 Kubelet Version:            v1.12.3
 Kube-Proxy Version:         v1.12.3
PodCIDR:                     10.244.2.0/24
Non-terminated Pods:         (3 in total)
  Namespace                  Name                           CPU Requests  CPU Limits  Memory Requests  Memory Limits
  ---------                  ----                           ------------  ----------  ---------------  -------------
  kube-system                intel-fpga-plugin-bhswp        0 (0%)        0 (0%)      0 (0%)           0 (0%)
  kube-system                kube-flannel-ds-amd64-4cdnl    100m (0%)     100m (0%)   50Mi (0%)        50Mi (0%)
  kube-system                kube-proxy-4v7x8               0 (0%)        0 (0%)      0 (0%)           0 (0%)
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource                                                Requests   Limits
  --------                                                --------   ------
  cpu                                                     100m (0%)  100m (0%)
  memory                                                  50Mi (0%)  50Mi (0%)
  fpga.intel.com/af-d8424dc4a4a3c413f89e433683f9040b      0          0
  fpga.intel.com/af-f7df405cbd7acf7222f144b0b93acd18      0          0
  fpga.intel.com/region-9926ab6d6c925a68aabca7d84c545738  0          0
Events:                                                   <none>


Running demo

Run demo

ここでは NLB (ネイティブループバック) のAFUが書き込まれたAFリソースを指定してうごかすデモを行います.

※実際には test-fpga-region.yml というファイルですが,
リポジトリ内は ymlyaml が混在していたので,Qiitaでは yaml で統一してます.

cd $GOPATH/src/github.com/intel/intel-device-plugins-for-kubernetes/demo
kubectl apply -f test-fpga-region.yaml

Check Status

実行後, Completed となっていればスケジューリングは正しく動いています.

$ kubectl get po
NAME                                             READY   STATUS      RESTARTS   AGE
test-fpga-region                                 0/1     Completed   0          81m

Check log

また,コンテナの標準出力を確認して,問題なくFPGAが動いているかも確認.

$ kubectl logs test-fpga-region
Running nlb3

Cachelines Read_Count Write_Count Cache_Rd_Hit Cache_Wr_Hit Cache_Rd_Miss Cache_Wr_Miss   Eviction 'Clocks(@200 MHz)'   Rd_Bandwidth   Wr_Bandwidth
         1          1           0            0            0             0             0          0              142     0.090 GB/s     0.000 GB/s

VH0_Rd_Count VH0_Wr_Count VH1_Rd_Count VH1_Wr_Count VL0_Rd_Count VL0_Wr_Count
           1            1            0            0            0            0

nlb3 succeeded as expected
Running nlb0 sample
Error: device enumeration failed.
Please make sure that the driver is loaded and that a bitstream for
AFU id: D8424DC4-A4A3-C413-F89E-433683F9040B is programmed.
nlb0 failed as expected
SUCCESS

もし以下のようにnlb3が実行できないと怒られたらPACに書き込まれているbitstreamを確認する.

kubectl logs test-fpga-region
Running nlb3
Error: device enumeration failed.
Please make sure that the driver is loaded and that a bitstream for
AFU id: F7DF405C-BD7A-CF72-22F1-44B0B93ACD18 is programmed.
nlb3 failed
FAILURE: unexpeced nlb3 failure

bitstream の書き換え

以下は,AFU IDの確認方法と,nlb3の書き込み方法です.

$ cat /sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id
d8424dc4a4a3c413f89e433683f9040b
$ sudo fpgaconf $OPAE_PLATFORM_ROOT/hw/samples/nlb_mode_3/bin/nlb_mode_3.gbs
$ cat /sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id
f7df405cbd7acf7222f144b0b93acd18

おわりに

今回はk8sでFPGAをスケジューリングを試してみましたが,
今度はOpenVINOのコンテナイメージを用意していろいろ試したいなーと思います.

以下model optimizerをk8s上で動かしたという内容
https://ai.intel.com/openvino-model-server-boosts-ai-inference-operations/

Appendix. AFU ID

filename afuid
hello_afu.gbs 850adcc2-6ceb-4b22-9722-d43375b61c66
hello_intr_afu.gbs 850adcc2-6ceb-4b22-9722-d43375b61c66
hello_mem_afu.gbs 35f9452b-25c2-434c-93d5-6f8c60db361c
dma_afu.gbs 331DB30C-9885-41EA-9081-F88B8F655CAA
streaming_dma_afu.gbs eb59bf9d-b211-4a4e-b3e3-753ce68634ba
eth_e2e_e10.gbs 05189fe4-0676-dd24-b74f-291af34e1783
eth_e2e_e40.gbs 26b40788-034b-4389-b3c1-51a1b62ed6c2
nlb_mode_0.gbs d8424dc4-a4a3-c413-f89e-433683f9040b
nlb_mode_3.gbs f7df405c-bd7a-cf72-22f1-44b0b93acd18
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5