#サンプルコード
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との違い
※以下サイトの図を参考にさせていただきました。
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作成の大まかなフロー
- フォルダ階層をイメージし、大枠を作成する
- 今回の場合は「RasberryPiの初期設定」「kubernetesのプロビジョニング」の2つコンポーネントで構築する。凝縮度&結合度を考慮する。
- 参考:https://www.affordd.jp/koha_hp/KeyWords/KW.Coupling.html
- InventoryにプロビジョニングしたいIPを記載
- ansibleの設定はansible.cfgに記載
- Rolesでplaybookを整理する
- role内のtaskにメイン実行関数、defaultsに定数を入れる
###参考資料
-
SDカードをターミナルでフォーマット
https://qiita.com/ikemura23/items/f3dfc0311d50bc34aa25 -
Raspberry PiのプロビジョニングをAnsibleで行う
https://hassiweb-programming.blogspot.com/2019/08/kubernetes-install-on-raspberrypi.html -
MACにansibleをinstallする
https://weblabo.oscasierra.net/ansible-homebrew-install-1/ -
Ansibleの疎通確認にはsshpassのインストールが必須らしい
https://qiita.com/suganum/items/59bbf0972c65b4b682c0
https://qiita.com/rysk_lunch/items/bb817964fc3fbe6d177c -
ansible.cfgのwarningを消す
https://dev.classmethod.jp/articles/ansible-interpreter-warning/ -
ansibleのトラブルシューティング
https://docs.ansible.com/ansible-tower/3.1.4/html_ja/administration/troubleshooting.html -
playbookの書き方
https://kurokawanushi.hatenablog.com/entry/2019/03/03/190000 -
playbookに「become:yes」をつけるとroot権限で実行できる
https://dekitakotono.blogspot.com/2019/04/become-sudo-su.html -
ラズパイプロビジョニング例1
https://github.com/hassiweb/k8s-install-on-rpi/tree/master/ansible/roles/k8s -
ラズパイプロビジョニング例2
https://github.com/giuaig/ansible-raspi-config/blob/master/raspi-config.yml -
kubenetesのクラスタには同じホストネームを持つnodeが存在してはいけない
- raspi-configでそれぞれのエッジデバイスが異なるホストネームになるように設定する
-
ラズパイが起動した時にスクリプトを自動実行させる
https://raspberrypi-japan.com/run-startup-program-3/
#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"}
・・・
###参考資料
- apt-utils isn't installed 警告をなくす
https://mokuzine.net/ubuntu-apt-util-warn/
#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
###参考
- ① "/dev/i2c-1"にsudoなしでも入り込めるようにする
https://remoteroom.jp/diary/2020-11-19/ - ② "/dev/i2c-1"にsudoなしでも入り込めるようにする。以下を入れる
securityContext:
privileged: true