Raspberry PiでWebサーバ(冗長構成)を構築

SCSK 岩井です。

今回はRaspberry Piを2台使ってWebサーバの冗長化を行ってみたいと思います。
ただWebサーバを冗長化するだけではなく、WebサイトとLED点灯/消灯を連動させてみたいと思います。
ちょっとだけそれっぽくなる予定です。

 

下準備

使用するRaspberry Piは以下のものです。

【Raspberry Pi 5】
CPU: Broadcom BCM2712 quad-core Arm Cortex A76 processor @ 2.4GHz
Memory: 8GB
OS: Bookworm

【Raspberry Pi 3 Model B+】
CPU: Broadcom BCM2837B0, Cortex-A53 (ARMv8) 64-bit SoC @ 1.4GHz
Memory: 1GB
OS: Bookworm

 

この2台にflask(簡易的なWebアプリフレームワーク)をインストールしてWeb経由操作でLED点灯/消灯する構成を組んでみます。

【追加で用意するもの】
LED(赤)×1
LED(黄)×1
抵抗(330Ω)×2
ジャンパーケーブル×4
ブレッドボード×1
Webサーバアクセス用PC

 

ライブラリのインストール

ラズパイに必要なライブラリ(Flask、GPIO(Rasberry Pi 3)、gpiozero(Rasberry Pi 5))をインストールします。
Raspberry Pi 5はGPIOが使えなくなってしまったので代わりにgpiozeroをインストールします。

 # Raspberry Pi 5の場合
 sudo apt update
 sudo apt install python3-flask
 sudo apt install gpiozero
 # Raspberry Pi 3の場合
 sudo apt update
 sudo apt install python3-flask
 sudo apt install python3-rpi.gpio 

 

Pythonスクリプトの作成

PythonでFlaskアプリケーションを作成します。
ファイル名はapp.pyにしてみました。
Web画面上にLED点灯用とLED消灯用のリンクを張って、LEDを着けたり消したりできるようにします。
まずはviを起動します。

 # Raspberry Pi 3/Raspberry Pi 5共通
 sudo vi app.py

以下のコードを記述してファイルを保存します。Raspberry Pi 5はgpiozeroライブラリ、Raspberry Pi 3は
GPIOライブラリなのでコードが異なります。同じ画面を作成していますが、Raspberry Pi 5はWebアクセスされると「Unit 1」、
Raspberry Pi 3はWebアクセスされると「Unit 2」と表示されるようにしています。

 # Raspberry Pi 5の場合
 from flask import Flask
 from gpiozero import LED    
 
 app = Flask(__name__)
  
 # GPIO 17を制御するLEDオブジェクトの作成
  
 led = LED(17)
  
 @app.route('/') 
 def index():
 return '''
  
 <h1>LED Control(Unit 1)</h1>
 <p><a href="/led/on">Turn LED ON</a></p>
 <p><a href="/led/off">Turn LED OFF</a></p>
 '''
  
 @app.route('/led/on')
 def led_on():
 led.on() # LEDを点灯
 return '<h1>LED is ON</h1><p><a href="/">Back to home</a></p>'
  
 @app.route('/led/off')
 def led_off():
 led.off() # LEDを消灯
 return '<h1>LED is OFF</h1><p><a href="/">Back to home</a></p>'
  
 if __name__ == '__main__':
 app.run(host='0.0.0.0', port=5000)
 # Raspberry Pi 3の場合
 from flask import Flask
 import RPi.GPIO as GPIO
 
 app = Flask(__name__)
 
 # GPIOピンの設定
 LED_PIN = 17
 GPIO.setmode(GPIO.BCM)
 GPIO.setup(LED_PIN, GPIO.OUT)
 
 @app.route('/')
 def index():
 return '''
 <h1>LED Control(Unit 2)</h1>
 <p><a href="/led/on">Turn LED ON</a></p>
 <p><a href="/led/off">Turn LED OFF</a></p>
 '''
  
 @app.route('/led/on')
 def led_on():
 GPIO.output(LED_PIN, GPIO.HIGH)
 return '<h1>LED is ON</h1><p><a href="/">Back to Home</a></p>'
 
 @app.route('/led/off')
 def led_off():
 GPIO.output(LED_PIN, GPIO.LOW)
 return '<h1>LED is OFF</h1><p><a href="/">Back to Home</a></p>'
 
 if __name__ == '__main__':
 try:
 app.run(host='0.0.0.0', port=5000)
 finally:
 GPIO.cleanup()

 

LEDとRaspberry Piを接続する

ブレッドボードにLEDと抵抗を接続します。
Raspberry Pi 5用とRaspberry Pi 3用に2セット回路を作ります。
イメージはこんなカンジで。(左側がRaspberry Pi 3用、右側がRaspberry Pi 5用)

次に回路とRaspberry Pi 5、Raspberry Pi 3を接続します。
なお、コードの中にあったGPIO 17は17ピンではなく、11ピンのGPIO17 です。
17ピンに刺すと3.3vの電圧がかかりっぱなしになるので、
ただLEDが光ってるだけの状態になります。(Webアプリと連動しません)
10分悩みました。
11ピンのGPIO17に+側(LED側のケーブル)、14ピンのGroundに-側(抵抗側のケーブル)を接続します。

【Raspberry Pi 5のピン配置】

Raspberry Pi 5 Pinouts including GPIO for the 40 Pin Header – element14 Community

【Raspberry Pi 3のピン配置】

Raspberry Pi 3 Model B GPIO 40 Pin Block Pinout – element14 Community

 

Webサーバの起動(Pythonスクリプトの実行)

各Raspberry Piのコンソールで、Webサーバを起動します。
まずはIPアドレス確認から。

 # Raspberry Pi 5/Raspberry Pi 3共通
 ip addr

次に各Raspberry PiでWebサーバを起動します。

 # Raspberry Pi 5/Raspberry Pi 3共通
 python3 app.py

 

WebブラウザからアクセスとLED操作

Webサイトアクセス用PCでブラウザを2つ起動し、それぞれ以下のURLにアクセスします。

http://Raspberry Pi 5のIPアドレス:5000

http://Raspberry Pi 3のIPアドレス:5000

次にブラウザ上の「Turn LED ON」のリンクをクリックします。

  

  

LED点灯。やりました。

「Back to Home」のリンクをクリックして前の画面に戻ります。
今度は「Turn LED OFF」のリンクをクリックします。

LED消灯。(写真撮り忘れました)

 

nginxのインストールとプロキシ設定

nginxを使用してFlaskアプリへのリクエストをプロキシできるようにするため、各Raspberry Piにnginxをインストールします。

 # Raspberry Pi 5/Raspberry Pi 3共通
 sudo apt install nginx

プロキシを有効化するため、nginxの設定を変更します。

 # Raspberry Pi 5/Raspberry Pi 3共通
 sudo vi /etc/nginx/sites-available/default

設定内容は以下のとおり。

 # Raspberry Pi 5/Raspberry Pi 3共通
 server {
     listen 80;
     server_name localhost;
 
     location / {
         proxy_pass http://127.0.0.1:5000;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
     }
 }

 

Keepalivedのインストールと設定

keepalivedインストールしてWebサイト(Flaskアプリ)の冗長化構成を組んでみます。
各Raspberry Piにkeepalivedをインストールします。

 # Raspberry Pi 5/Raspberry Pi 3共通
 sudo apt update
 sudo apt install keepalived

次に各Raspberry Piでkeepalivedの設定ファイルを編集します。

 # Raspberry Pi 5/Raspberry Pi 3共通
 sudo vi /etc/keepalived/keepalived.conf

Raspberry Pi 5をMaster、Raspberry Pi 3をBackupとします。
仮想IPアドレス(virtual_ipaddress)は192.168.11.110、Master側を優先させるため、priorityを100とします。
なお、interfaceは仮想IPアドレスを持たせるネットワークインターフェイスを指定します。

 # Raspberry Pi 5(Master)
 vrrp_instance VI_1 {
     state MASTER
     interface eth0
     virtual_router_id 51
      priority 100
     advert_int 1
     authentication {
         auth_type PASS
         auth_pass mypass
     }
     virtual_ipaddress {
         192.168.11.110
     }
 }

Backup側の仮想IPアドレス(virtual_ipaddress)はMaster側と同様の192.168.11.110、priorityを90とします。

 # Raspberry Pi 3(Backup)
 vrrp_instance VI_1 {
     state BACKUP
     interface eth0
     virtual_router_id 51
     priority 90
     advert_int 1
     authentication {
         auth_type PASS
         auth_pass mypass
     }
     virtual_ipaddress {
         192.168.11.110
     }
 }

各Raspberry Piでkeepalivedを再起動します。

 # Raspberry Pi 5/Raspberry Pi 3共通
 sudo systemctl restart keepalived

 

動作確認

Webサイトアクセス用PC上のブラウザで仮想IPアドレスのURLにアクセスします。

http://192.168.11.110/

Unit 1の表記があり、Master側(Raspberry Pi 5)のWebサイトにアクセスしていることがわかります。


Raspberry Pi 5に接続したLEDの点灯/消灯も問題なくできます。

ここで、Raspberry Pi5をシャットダウンします。
その後上記URLにアクセスするとUnit 2の表記があり、Backup側(Rapberry Pi 3)のWebサイトにアクセスしています。

Raspberry Pi 3に接続したLEDの点灯/消灯も問題なくできます。

これでWebサイトを冗長化することができました。
GPIO側も冗長構成とする必要がありますが、片系に障害が発生してもサービスを継続させることができるようになります。
今回はLEDを取り付けましたが、カメラやセンサーなどを取り付けてみるのも面白そうです。以下の続きの記事で実施してみました。

 

著者について

インフラPL/PMを担当しています。

岩井義文をフォローする

クラウドに強いによるエンジニアブログです。

SCSKでは、自社クラウドと3大メガクラウドの強みを活かし、ハイブリッドクラウド/マルチクラウドのソリューションを展開しています。業界の深い理解をもとに、お客様の業務要件に最適なアーキテクチャをご提案いたします。サービスサイトでは、お客様のDX推進をワンストップで支援するサービスの詳細や導入事例を紹介しています。

その他技術ナレッジ
シェアする
タイトルとURLをコピーしました