2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【備忘録】ラズパイをAnsibleでクラスタ化する

Posted at

#サンプルコード
https://github.com/akihiro0000/raspi-k8s

#目次
1.アーキテクチャ、開発フロー
2.Ansibleにとは
2.Ansibleによる諸々設定
3.Ansibleによるクラスタ作成
#アーキテクチャ、開発フロー

###必要備品
ラズパイ2つをルーターに繋げます

  • raspi×2(master、worker)
  • ルーター×1
  • SIM×1
  • ハブ×1
  • 有線LANケーブル×3
  • SDカード×2

#Ansibleとは

  • Simple、Powerful、Agentlessという3つの特徴を掲げるPython製のインフラ構築自動化ツール
  • 先行製品として有名なPuppetやChef等で実現できることを踏襲
  • 構成管理ツールとも呼ばれ、「機器のあるべき姿(構成)をファイルで管理する」ためのものである
  • 冪等性(同じ操作を何度繰り返しても、同じ結果が得られる性質)あり

###特徴

  • Simple
    • Playbookと呼ばれるファイルに環境構築に関する設定情報をYAMLにより定義します。
  • Powerful
    • OSSコミュニティの活動が活発であり、日々開発がされている、様々な機器を操作するためのモジュールを使用することができます。
  • Agentless
    • 構築対象となるサーバ、機器に対してAgentをインストールする必要がないため、余計な管理負荷、セキュリティリスクを負わなくて済みます。

###Chef,Puppetとの違い

image.png
※以下サイトの図を参考にさせていただきました。
https://www.scsk.jp/product/oss/tec_guide/ansible/1_ansible1_1.html

#Ansibleによる諸々設定
###本記事向けファイル構造
本来はrole内にdefault等様々な設定方法があるそうですが、今回はroleの身を用います。

.
├── ansible.cfg
├── inventory
│   └── inventory.ini
├── k8s_provisioning.yml
├── raspbian_provisioning.yml
└── roles
    ├── apt
    │   └── tasks
    │       └── main.yml
    ├── k8s
    │   └── provisioning
    │       ├── defaults
    │       │   └── main.yml
    │       └── tasks
    │           ├── install_k8s_packages.yml
    │           ├── main.yml
    │           ├── master-provisioning.yml
    │           ├── memory_setup.yml
    │           ├── store_info_to_join.yml
    │           └── workers-provisioning.yml
    └── ras
        └── tasks
            └── main.yml

###疎通確認

ansible -i inventory/inventory.ini workers  -m ping

###実行

ansible-playbook  -i inventory/inventory.ini raspbian_provisioning.yml
ansible-playbook  -i inventory/inventory.ini k8s_provisioning.yml

結果として以下のようにクラスタができていればok

>$$sudo kubectl get nodes

NAME     STATUS   ROLES                  AGE     VERSION
ras000   Ready    control-plane,master   8m31s   v1.21.2
ras001   Ready    <none>                 7m2s    v1.21.2
>$$sudo kubectl get pods --all-namespaces

NAMESPACE     NAME                             READY   STATUS    RESTARTS   AGE
kube-system   coredns-558bd4d5db-t6d6m         1/1     Running   0          9m18s
kube-system   coredns-558bd4d5db-wfxm8         1/1     Running   0          9m18s
kube-system   etcd-ras000                      1/1     Running   0          9m23s
kube-system   kube-apiserver-ras000            1/1     Running   0          9m23s
kube-system   kube-controller-manager-ras000   1/1     Running   0          9m23s
kube-system   kube-flannel-ds-arm-nq7ps        1/1     Running   0          8m8s
kube-system   kube-flannel-ds-arm-qm4dp        1/1     Running   0          9m18s
kube-system   kube-proxy-rzspj                 1/1     Running   0          9m18s
kube-system   kube-proxy-vp598                 1/1     Running   0          8m8s
kube-system   kube-scheduler-ras000            1/1     Running   0          9m23s

###playbook作成の大まかなフロー

  • フォルダ階層をイメージし、大枠を作成する
  • InventoryにプロビジョニングしたいIPを記載
  • ansibleの設定はansible.cfgに記載
  • Rolesでplaybookを整理する
    • role内のtaskにメイン実行関数、defaultsに定数を入れる

###参考資料

#scd30センサーデータ取得ファイル、Dockerfile作成

from scd30_i2c import SCD30
import time
import pytz
from datetime import datetime
import os


#set scd30 sensor
try:
    scd30 = SCD30()

    scd30.set_measurement_interval(10)
    scd30.start_periodic_measurement()

    time.sleep(2)
except TimeoutError as e:
    print(e)
    os.system('exit')
    pass


while True:
    # if scd30 isn't ready, wait 0.2sec
    try:
        if scd30.get_data_ready():
            m = scd30.read_measurement()
            if m is not None:
                tim = '"timestamp":"'+datetime.now(pytz.timezone('Asia/Tokyo')).strftime('%Y-%m-%d %H:%M:%S.%f')+'"'
                temp = '"' + "temp(degree)" + '"' + ":" + '"' + str(round(m[1]-3.5,3)) + '"'
                hum = '"' + "humid(%)" + '"' + ":" + '"' + str(round(m[2],3)) + '"'
                co2 = '"' + "co2(ppm)" + '"' + ":" + '"' + str(round(m[0],3)) + '"'
                mylist = [tim,temp,hum,co2]
                mystr = '{' + ','.join(map(str,mylist))+'}'
                if str(round(m[1],3))!="nan":
                    print(mystr)
                    time.sleep(1)
                else:
                    print("value is nan")
                    time.sleep(1)
        else:
            time.sleep(0.2)
    except OSError as e:
        print(e)
        pass
FROM debian:buster

ENV DEBCONF_NOWARNINGS=yes

RUN apt update && apt upgrade -y \
    curl cron python3 python3-pip python3-dev python -V git wget vim python3-numpy i2c-tools

RUN pip3 install scd30-i2c pytz

RUN git clone --depth 1 https://github.com/akihiro0000/raspi-k8s.git

WORKDIR /raspi-k8s/src

CMD ["python3","sdc30.py"]

以下でi2c通信を許可した状態でコンテナをrun

docker run  --device /dev/gpiomem  --device /dev/i2c-1 --device /dev/ttyACM0 --privileged -e TZ=Asia/Tokyo -it akihirodive/raspi-k8s:v1.0

出力

{"timestamp":"2021-07-03 22:57:30.753356","temp(degree)":"21.623","humid(%)":"59.055","co2(ppm)":"583.996"}
{"timestamp":"2021-07-03 22:57:40.654920","temp(degree)":"21.609","humid(%)":"58.885","co2(ppm)":"583.399"}
{"timestamp":"2021-07-03 22:57:51.792402","temp(degree)":"21.609","humid(%)":"58.971","co2(ppm)":"583.271"}
・・・

###参考資料

#scd30センサーデータ取得yamlファイル作成

apiVersion: apps/v1
kind: Deployment
metadata:
  name: scd30
spec:
  selector:
    matchLabels:
       role: app
  replicas: 2
  template:
    metadata:
      labels:
         role: app
    spec:
      containers:
      - name: scd30-container
        volumeMounts:
        - mountPath: /dev/i2c-1
          name: i2c
        securityContext:
          privileged: true
        image: akihirodive/raspi-k8s:v1.0 
        imagePullPolicy: Always
        ports:
        - containerPort: 1000
          hostPort: 1000
      volumes:
      - name: i2c
        hostPath:
          path: /dev/i2c-1

以下コードでpodをworker nodeに立てる

sudo kubectl apply -f <yaml名>.yaml

出力

>>sudo kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
scd30-59dfdcfb46-rgk2d   0/1     Pending   0          6m11s
scd30-59dfdcfb46-vpzxl   1/1     Running   0          6m11s

###参考

securityContext:
          privileged: true
2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?