仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

コンテナーでLチカしてみる

今日は誰に役立つかわからないネタです。

Pi-Stopを複数借りることができたので、OSCのラズパイクラスターのデモ用にKubernetes上のPodでアプリを動かすとLEDがピカピカいうのを試してみたいなと思い、試してみることにしました。

用意するもの

  • microSD
  • Raspberry Pi 3以降
  • Raspbian buster Lite
  • Pi-Stop

手順

  • microSDにRaspbian Lite busterを書き込みます。
  • Pi-Stopを差し込みます(今回はGnd:6、Green:8、Amber:10、Red:12)。
  • 電源を入れて、Raspbianを起動します。
  • こんなファイルを作って、Pythonスクリプトファイルとして保存します(pika2.py)。
from gpiozero import LED
from time import sleep

green = LED(14)
yellow = LED(15)
red = LED(18)

for t in range(0,5):
  green.on()
  sleep(5)
  green.off()
  yellow.on()
  sleep(2)
  yellow.off()
  red.on()
  sleep(5)
  red.off()

これはPython3でもPython2でも動作します。Pythonモジュールとしてpython-gpiozero(Python3の場合はpython3-gpiozero)をインストールします。 今回はgpiozeroを使いました。

gpiozero.readthedocs.io

  • 次のように実行すると、LEDをピカピカできます。ちなみにGPIOを叩くにはroot権限が必要なので、sudo -iとかでroot権限に切り替えてから実行してください。
# python pika2.py

では、これをDockerのコンテナーやKubernetes Pod上でピカピカさせてみましょう(誰得)。

Dockerコンテナーでピカピカさせる

  • Raspbian busterにはdocker.ioというパッケージが用意されており、比較的新しいバージョンのDocker CEをaptコマンドでインストールできます。
% sudo apt update && sudo apt install docker.io -y
  • Raspbianはarmhfアーキテクチャーです。ARMのイメージが必要なので、今回はraspbian/stretchを使います。
% sudo docker image pull raspbian/stretch
  • コンテナーを作成します。 --privileged=trueか、--device /dev/gpiomemを設定するのを忘れないでください。 -vオプションでpika2.pyを保存したディレクトリーを指定しています。

-v /home/pi/test:/rootはホストの/home/pi/testパスをコンテナーの/rootにマウントするように指定しています。-wオプションはworkdirを指定しています。これは多くのDockerイメージは/が初期のパスとしてログインされるためです。cd /rootと手動で移動する必要がなくなります。

% sudo docker container run --name=cont1 --device /dev/gpiomem -v /home/pi/test:/root -w /root -it raspbian/stretch bash
  • コンテナーでPythonのgpiozeroモジュールをインストールして、スクリプトを実行します。ピカピカします。
# apt update && apt install python-gpiozero -y
# python pika2.py

Kubernetesでピカピカさせる

Raspberry PiにKubernetesを構築するのはかなり大変です。私が持っているのはRaspberry Pi 3なので、CPUコアは4コアあっていいのですが、メモリーは1GBしかないためです。国内でもRaspberry Pi 4が使えるようになれば、ここら辺は軽減できるかもしれませんね。

というわけで、今回はk3sを使ってKubernetesを動かします。

  • 先ずはk3sでKubernetesを動かします。
# curl -sfL https://get.k3s.io | sh -
  • 動作完了までは少々時間がかかるので、待っている間にこんなYAMLを書きます。
apiVersion: v1
kind: Pod
metadata:
  name: ledpika
spec:
  containers:
    - name: ledpika
      image: raspbian/stretch
      volumeMounts:
      - mountPath: /root
        name: my-volume     
      securityContext:
        privileged: true
  volumes:
  - name: my-volume
    hostPath:
      path: /home/pi/test

Podを作成してシェルに入ります。

# kubectl create -f testpod.yml
# kubectl exec -it ledpika bash

Pod内で実行します。ピカピカします。

# apt update && apt install python-gpiozero -y && python pika2.py

Kubernetes Podでもピカピカが成功しました。 というわけで、「コンテナーでLチカしてみる」でした。

イメージを作りました

KubernetesのYAMLをいっぱい書くのすら面倒になったので、RaspbianとPythonのコードを仕込んだイメージを作ってみました(本当は社内で「Dockerイメージでも作ったら?」と言われたのが理由です)。

hub.docker.com

これを使ってDockerコンテナーで利用するには、次のコマンドを実行してください。ピカピカします。

# docker run --device /dev/gpiomem -it ytooyama/rpi-pika2:latest

これを使ってKubernetes Podを作るには、次のYAMLを書いてkubectl create -fしてください。

apiVersion: v1
kind: Pod
metadata:
  name: ledpika
spec:
  containers:
    - name: ledpika
      image: ytooyama/rpi-pika2:latest
      securityContext:
        privileged: true

Podを作ります。

# kubectl create -f pika2.yml

そうすると、ピカピカを5回繰り返してクラッシュし、再起動され...を繰り返します。 しばらくピカピカします(Podをdeleteして終了してください)。

NAME      READY   STATUS             RESTARTS   AGE
ledpika   0/1     CrashLoopBackOff   3          6m13s
ledpika   1/1     Running            4          6m23s
ledpika   0/1     Completed          4          7m25s
ledpika   0/1     CrashLoopBackOff   4          7m39s

10/24 追記

Workerを増やした場合はDeployment APIを使ったほうがいいと思いますので、サンプルのYAMLを貼り付けておきます。 このようなファイルを作り、kubectl apply -fでPodを作ってください。

YAMLファイルのreplicas: 1のところを増やして、kubectl apply -f...を実行するか、起動後にkubectl scale deployment ledpika --replicas=x(xにレプリカ数を入力)を実行するとスケールします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ledpika
spec:
  replicas: 1
  selector:
     matchLabels:
       app: ledpika
  template:
    metadata:
      labels:
        app: ledpika
    spec:
      containers:
      - name: ledpika
        image: ytooyama/rpi-pika2:latest
        securityContext:
          privileged: true