前回はJetson NanoでK3sを用いたKubernetesクラスターを動かしてみました。
今回はラズパイ4とJetson Nanoの混在したクラスターを作ってみたいと思います。
構成について
ラズパイ側は
ラズパイはRaspberry Pi 4 8GBモデルを用意しました。K3s自体は512MBのメモリーを実装したラズパイで動作しますので、Raspberry Pi 4の2GBモデルでも4GBモデルでも同じように動作すると思います。今回は手元にあったのが8GBモデルだったということと、クラスターを組んだ後、そのノードもWorkerノードとして使う前提だったのでメモリが多めのものを使うことにしました。メモリー2GB未満だといろいろきついと思います。
OSはRaspberry Pi OS 64bitを最新のバージョンにアップデートします。 2020/07/27時点のイメージで起動した場合、Linux Kernel 5.4ベースの最新版に更新されます。 また、cgroupの設定も事前に行っておきます(未確認ですが、Raspberry Pi 3Bではcgroupの設定がうまくいかないようです。バグかも?)。
cgroupの設定は、 /boot/cmdline.txt
の末尾に cgroup_memory=1 cgroup_enable=memory
を書いて再起動するだけです。
今回はCRIとしてDockerを使いたいため、Dockerをインストールしておきます。
~$ sudo apt update && sudo apt install docker.io
Jetson Nano側は
Jetson Nanoは以下の手順に従い、セットアップします。OSは「Jetson Nano Developer Kit SD Card Image」を使い、最新のアップデートを適用します。 2020/07/27時点のイメージで起動した場合、Linux Kernel 4.9のUbuntu 18.04.4ベースです。
使い始める前にシステムアップデートして再起動してからセットアップすることをおすすめします。
各ノードのIPアドレスを設定します。
「Jetson Nano Developer Kit SD Card Image」を使った場合はDockerやGPUを使うための色々なライブラリーはセットアップ済みです。
前回の記事同様に、デフォルトランタイムを nvidiaにする設定だけ行っておきます。
~$ sudo docker info | grep Runtime Runtimes: nvidia runc Default Runtime: runc ~$ sudo vi /etc/docker/daemon.json { "default-runtime": "nvidia", <-追記 "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } } } ~$ sudo systemctl restart docker ~$ sudo docker info | grep Runtime Runtimes: nvidia runc Default Runtime: nvidia
ところで混在できて何が嬉しいのか
全てのアプリケーションの実行にGPUが必要ないが、GPUを使ったコンテナーアプリケーションを実行したい時にGPUユニットが載ったマシンで動かしたい。 GPUクラスターと非GPUクラスターを別々に持つ必要がないので管理コストも半分。 そんなメリットがあります。
Raspberry Pi側の設定
Raspberry Piは今回はMasterノード兼Workerノードとして使います。 以下のようにセットアップを行います。
~$ curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--docker" sh -s -
コマンドを実行して、クラスターが正常に実行されていることを確認します。
~$ sudo kubectl get no NAME STATUS ROLES AGE VERSION raspi4 Ready master 117m v1.18.6+k3s1
クラスターが起動したら、トークンキーを確認します。
~$ sudo cat /var/lib/rancher/k3s/server/node-token K10022ca9e54ffa73dedd71dfd3983603adc7befcfb517a6ccbc356b7578316edca::server:1188c86cc84aeceedf48d9523f0948ae
Jetson Nano
Jetson Nanoは今回はWorkerノードとして使います。 以下のようにセットアップを行います。
~$ curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--docker" K3S_URL=https://192.168.1.71:6443 K3S_TOKEN=K10022ca9e54ffa73dedd71dfd3983603adc7befcfb517a6ccbc356b7578316edca::server:1188c86cc84aeceedf48d9523f0948ae sh -
コマンドを実行して、クラスターにJetsonが追加されていることを確認します。
[7/28 注記] 上記スクリーンショットではDebian 10となっていますが、Raspberry Pi OS 10 64bit版です。Raspberry Pi OS 10の32bit版はRaspbianベースですが、64bit版はDebian 10 arm64ベースであるため、Debian 10と認識されます。
Masterノードで実行
次のようなYAMLを用意します。
nodeSelector
でホスト名として kubectl get node
で表示される名前を指定します。
apiVersion: apps/v1 kind: Deployment metadata: name: nginxapp1 spec: replicas: 1 selector: matchLabels: app: nginxapp1 template: metadata: labels: app: nginxapp1 spec: containers: - name: nginxapp1 image: nginx:alpine ports: - containerPort: 80 nodeSelector: kubernetes.io/hostname: jetson1
Podが作成できることを確認します。
~$ sudo kubectl create -f nginx.yaml deployment.apps/nginxapp1 created ~$ sudo kubectl get -f nginx.yaml NAME READY UP-TO-DATE AVAILABLE AGE nginxapp1 1/1 1 1 5s
次に、以下のYAMLを作成して、サービスを定義します。
apiVersion: v1 kind: Service metadata: name: nginxapp1-nodeport labels: app: nginxapp1 spec: type: NodePort ports: - port: 80 targetPort: 80 nodePort: 30080 selector: app: nginxapp1
Serviceが作成できることを確認します。
~$ sudo kubectl create -f nginx-svc.yaml service/nginxapp1-nodeport created ~$ sudo kubectl get -f nginx-svc.yaml NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginxapp1-nodeport NodePort 10.43.139.49 <none> 80:30080/TCP 14s
NGINXアプリケーションにアクセスできることを確認します。
~$ sudo kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginxapp1-6489c458b8-xwsxx 1/1 Running 0 4m27s 10.42.1.7 jetson1 <none> <none> ~$ curl --head http://192.168.1.71:30080 HTTP/1.1 200 OK Server: nginx/1.19.1 Date: Mon, 27 Jul 2020 04:59:29 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Fri, 10 Jul 2020 20:32:43 GMT Connection: keep-alive ETag: "5f08d06b-264" Accept-Ranges: bytes