クラスタ インストール
大規模ワークロード向けに PlantPulse をマスター + ワーカー ノード クラスタで構成する方法です。シングル ノードで開始してから、スループットが限界に達したときに段階的に拡張できます。
マルチ ノード構成 2 つ — 目的が異なります
構成 目的 ドキュメント ① MASTER / WORKER クラスタ インフラ(Cassandra·Kafka·Spark)を水平スケーリング — 同じレイヤを複数ノードに分散 このドキュメント ② DATALAKE / APP 2ノード分離 保存/処理レイヤとコンソール/バッチレイヤを異なるマシンに分離(垂直分離) — ノード別メモリ削減·負荷分離 2ノード分離インストール スループット不足でインフラを増やすなら ①、1 台のメモリ不足またはバッチ負荷をコンソールから分離したいなら ② を使用します。これらは相互排他的ではなく、
PP_MODE(クラスタリング)とPP_TIER(レイヤ ゲートウェイ)は独立しています。
いつクラスタにスケーリングするのか
| 環境規模 | 推奨構成 | 備考 |
|---|---|---|
| タグ ~5,000 | シングル マスター | クラスタ不要 |
| タグ 5,000 ~ 50,000 | マスター + 1~2 ワーカ | 分析 / メッセージング分散 |
| タグ 50,000+ | マスター + 3+ ワーカ | 本格分散運用 |
クラスタ トポロジ
ハードウェア要件
各ワーカ ノード仕様の推奨値:
| 項目 | 最小 | 標準 | 大規模 |
|---|---|---|---|
| CPU | 16 vCPU | 32 vCPU | 48 vCPU |
| メモリ | 64 GB | 128 GB | 200+ GB |
| データ ディスク | 200 GB NVMe | 1 TB NVMe | 4 TB NVMe |
| ネットワーク | 1 Gbps | 10 Gbps | 10 Gbps |
ノード間ネットワーク: クラスタ ノード間は10 Gbps 以上を推奨します。Cassandra repair、Kafka レプリケーション、Spark shuffle トラフィックが大きいです。
前提条件
マスター ノードとすべてのワーカ ノードで以下が完了している必要があります。
- システム要件を満たす
- ホスト名 / 固定 IP / DNS 設定
- 時間同期 (chronyd) — ノード間の時差 100ms 以下が必須
- OS チューニング (limits / sysctl / swap off)
- ノード間プライベート ネットワーク通信可能 (RFC 1918 または Tailscale)
- クラスタ内部ポート許可 (Cassandra 7000/7001/9042、Kafka 9092/9093、Spark 7077/8081 など)
/etc/hosts 設定 (すべてのノード同一)
# /etc/hosts — 마스터 / 워커 모든 노드에 동일하게
192.168.0.41 plantpulse-master plantpulse-master.local
192.168.0.101 plantpulse-worker-1 plantpulse-worker-1.local
192.168.0.102 plantpulse-worker-2 plantpulse-worker-2.local
192.168.0.103 plantpulse-worker-3 plantpulse-worker-3.local
Docker クラスタ (推奨パス)
Docker/ワンライン インストール環境では、ワーカをcompose オーバーレイで起動します。マスター ノードに基本スタックが起動している状態でbin/worker-add.shがワーカを 1 つずつ追加します。シークレット·証明書は以下の手順に従い、サイドカー ファイルでノード間にコピーされるため、値を手作業で転記する必要はありません。
ワーカ リストの正本 — compose/workers.roster
どのワーカが存在するかの正本はcompose/workers.rosterファイル 1 つです。1 行に<id> <ip>形式であり、シングル ノード インストールの場合は空白が正常です。
# compose/workers.roster
1 10.99.0.101
| 項目 | 意味 |
|---|---|
id | PP_WORKER_ID。コンテナ名(plantpulse-worker-<id>)とボリューム名(pw-<id>-*)のサフィックス |
ip | pp-net(10.99.0.0/24)上の固定アドレス。.1がゲートウェイ、.100がデータレイクであるため、.101から使用します |
compose/docker-compose.worker.ymlはこのファイルで生成され(bin/gen-worker-compose.sh)、bin/env.shもこのファイルからワーカ IP とノード リストを導出します。そのため compose·運用スクリプト·シークレット ローテーション ガードが異なるワーカ セットを見る事態が生じません。
docker-compose.worker.ymlは生成物です。手作業で編集すると CI のgen-worker-compose.sh --checkが失敗します。ワーカを増減させるのは、roster に行を追加したり削除したりするのではなく、以下のworker-add.sh / worker-decommission.sh + worker-remove.shで行います — ワーカは Cassandra トークン レンジと PostgreSQL レプリケーション スロットを保持しているため、リストだけを変更して作成または削除することはできません。
ワーカ関連環境変数 (bin/env.sh)
| 変数 | デフォルト値 | 説明 |
|---|---|---|
DOCKER_PW_NAME | plantpulse-worker | ワーカ コンテナ名プレフィックス (plantpulse-worker-1 …) |
DOCKER_PW_MEMORY | DOCKER_DATALAKE_MEMORYと同じ値(80G、ホストが小さい場合は RAM の 90%) | ワーカ コンテナ メモリ上限 |
DOCKER_PW_IP_<n> · PP_WORKER_NODES | roster から導出 | 手作業では入力しません |
ワーカはデータレイク マスターと同じイメージを使用するため(2026-08-31 統合)、そのイメージにビルトインされた JVM サイズもそのまま従います — Cassandra 単独で-Xms16G/-Xmx16Gを要求します。ホスト サイズに比例させた取得方法は誤りです。必要な量はホストではなく、サービス構成により決まります。
2026-08-31 実測:旧 12g デフォルト値のワーカが Cassandra がリングに接触する前に OOMKilled されました。コンテナはOOMKilled=trueで終了しましたが、join は発生しておらずhealth: startingを維持していました。
ワーカ追加
cd /opt/kopens/plantpulse-platform-docker
bin/worker-add.sh # 빈 id·빈 주소 자동 선택
bin/worker-add.sh 3 # id 지정
bin/worker-add.sh 3 10.99.0.103 # id·주소 지정
worker-add.shが順序通り実行します。
- roster に登録 (既存の id は«追加»ではないため拒否されます)
- オーバーレイ compose 再生成
- ボリューム作成 → イメージ pull →
up -d - リング参加確認 — マスターの
nodetoolで直接検証
ワーカは Cassandra トークン レンジ、Spark ワーカ登録、PostgreSQL レプリケーション スロット、Redis レプリケーション リンクを共に保持しています。コンテナ自体の準備確認は«マスターに到達するか»のみを確認するため、リング参加に失敗したワーカも成功したワーカと同じ正常状態として報告されます。
2026-08-31 実測: Cassandra が OOMKilled されたワーカがリングは 1 ノードのままでhealth: startingを維持していました。そのためworker-add.shはリング自体を照会します。
ワーカ運用
cd /opt/kopens/plantpulse-platform-docker
# 진입 (워커는 기본 스택의 서비스가 아니라 shell.sh 로는 잡히지 않습니다)
docker exec -ti plantpulse-worker-3 /bin/bash
# 정지 — compose 동사 그대로
docker compose -f compose/docker-compose.yml -f compose/docker-compose.worker.yml \
--profile worker-3 stop plantpulse-worker-3
# 이미지 갱신 (이미 도는 워커. 추가 시점의 pull 은 worker-add.sh 안에 들어 있습니다)
docker compose -f compose/docker-compose.yml -f compose/docker-compose.worker.yml \
--profile worker-3 pull plantpulse-worker-3
docker compose -f compose/docker-compose.yml -f compose/docker-compose.worker.yml \
--profile worker-3 up -d plantpulse-worker-3
ワーカ削除 — 必ずこの順序
bin/worker-decommission.sh 3 # 데이터 이관 + 링 이탈 확인 + 복제 슬롯 정리
bin/worker-remove.sh # 그 다음에 컨테이너 제거
docker rmは削除ではなく「放置」ですCassandra はそのノードのトークン レンジと host id を DN として保持しています。RF=3 ならば QUORUM がそのまま成立するため、アラートは何も表示されません。 そしてマスターはそのワーカの PostgreSQL 物理 レプリケーション スロットを引き続き保持し、ディスクが満杯になるまで WAL を固定します。
worker-remove.shはコンテナが動作している場合拒否し、worker-decommission.shを最初に呼び出すよう案内します。
worker-run.sh · worker-stop.sh · worker-update.sh · worker-bash.shの 4 つは**削除されました。**手作業でワーカ サービス リストを管理することを前提に作成されたものであり、roster 生成方式に変更する際に名前を変更しただけでなく削除されました。代替はそれぞれworker-add.sh(pull 含む) · compose 動作 · compose pull + up -d · docker execです。
シークレット サイドカー コピー (手作業コピー禁止)
マスターで生成されたサービス シークレットは/etc/kopens/plantpulse-platform.envサイドカー ファイルにあります。このファイルをワーカ ノードにコピーすると、ワーカは同じ認証情報でリング参加します — パスワードを 1 つずつ転記しないでください(2ノード分離ドキュメントの参加バンドルと同じパターン)。
# 마스터 노드에서 각 워커로
scp /etc/kopens/plantpulse-platform.env root@<worker-ip>:/etc/kopens/
共有 CA コピー → 自動シード
ノード間 TLS 信頼は共有クラスタ CA により成立します。マスターの/etc/kopens/ca/をワーカにコピーすると、コンテナ起動時にpp-securityボリュームに自動シードされるため、証明書を手作業で配置する必要がありません。
# 마스터 노드에서 각 워커로 (컨테이너 경로 기준 자동 seed)
scp -r /etc/kopens/ca root@<worker-ip>:/etc/kopens/
platform.node.envはノード別識別ファイルであり、コピーしないでください。コピー対象は上記 2 項目(plantpulse-platform.env、ca/)のみです。
クラスタ検証 (Docker 環境)
# Cassandra 링 — 모든 노드가 UN (Up Normal) 이어야 합니다
docker exec plantpulse-datalake \
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node status
# Spark — 워커가 ALIVE 인지
# 브라우저에서 http://<마스터IP>:4440/ 의 Workers 탭
ネイティブ(バイナリ) クラスタ手順
以下はバイナリ インストールで構築された既存システムのために保持されている手順です。現在の出荷版はDocker Compose パスのみのため、新規構築には使用しないでください。
1. マスター ノード インストール
マスター ノードはシングル ノード インストール手順と同じです。
1.1 マスター インストール
# 마스터 노드에서
mkdir -p /opt/kopens
cd /opt/kopens
tar -xzvf plantpulse-platform-2026.05.tgz
cd /opt/kopens/plantpulse-platform/tools
./setup.sh
# 노드 모드 입력: MASTER
# HOST IP: 192.168.0.41
# SERVICE IP: 192.168.0.41 (외부 노출 IP)
1.2 env.local.sh 調整 (クラスタ オプション)
env.shは配布により上書きされる SSOT (デフォルト正本)であるため、直接編集しないでください。 マシン固有値は同じディレクトリのenv.local.shにオーバーライドとして記述します(env.shが最初で source されるため常に優先適用されます)。詳細な原理は バイナリ インストール §4を参照。
vi /opt/kopens/plantpulse-platform/plantpulse-startup/env.local.sh
# 마스터 노드
export PP_MODE=MASTER
export PP_HOST_IP=192.168.0.41
export PP_SERVICE_IP=192.168.0.41
export PP_MASTER_IP=192.168.0.41
export PP_PUBLIC_IP=192.168.0.41
# 클러스터 자원
export PP_CLUSTER_CORES=64 # 마스터 + 워커 코어 합 (Spark 사용)
export PP_CLUSTER_MEMORY_BY_CORE=2G
# TLS SAN 에 모든 노드 IP / 도메인 포함
export PP_TLS_SAN_IPS="192.168.0.41,192.168.0.101,192.168.0.102,192.168.0.103,127.0.0.1"
export PP_TLS_SAN_DNS="plantpulse-master,plantpulse-worker-1,plantpulse-worker-2,plantpulse-worker-3,localhost"
export PP_TLS_NODE_NAMES="master worker-1 worker-2 worker-3"
1.3 マスター 起動
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./configure.sh
./prepare-ssl.sh
./start-daemon.sh
./status.sh
2. ワーカ ノード追加
2.1 ワーカ インストール
各ワーカ ノードで同一の手順でインストールします。
# 워커 노드 (예: 192.168.0.101) 에서
mkdir -p /opt/kopens
cd /opt/kopens
tar -xzvf plantpulse-platform-2026.05.tgz
cd /opt/kopens/plantpulse-platform/tools
./setup.sh
# 노드 모드 입력: WORKER
# HOST IP: 192.168.0.101
# SERVICE IP: 192.168.0.101
# MASTER IP: 192.168.0.41
2.2 ワーカ env.local.sh 調整 (ノード固有値のみ)
ノード別の IP などマシン固有値のみenv.local.shに記述します(env.sh 直接編集 ✗)。
vi /opt/kopens/plantpulse-platform/plantpulse-startup/env.local.sh
# 워커 노드
export PP_MODE=WORKER
export PP_HOST_IP=192.168.0.101 # 이 워커의 IP
export PP_SERVICE_IP=192.168.0.101
export PP_MASTER_IP=192.168.0.41 # 마스터의 IP
export PP_PUBLIC_IP=192.168.0.101
パスワード/キーストア パスワードはここに手作業で転記しません — 以下のシークレット サイドカーでノード間同期します。
2.3 シークレット サイドカー コピー
サービス シークレットはマスターの/etc/kopens/plantpulse-platform.envサイドカー ファイルにあります。このファイルをワーカにコピーすると、ワーカは同じ認証情報でリング参加します(2ノード分離ドキュメントの参加バンドルと同じパターン)。パスワードを 1 つずつ転記しないでください。
# 마스터에서 워커로 (env.sh 보다 먼저 source 되는 사이드카)
scp /etc/kopens/plantpulse-platform.env root@192.168.0.101:/etc/kopens/
2.4 共有 CA コピー → 自動シード
ノード間 TLS 信頼は共有クラスタ CA により成立します。マスターの/etc/kopens/ca/をワーカにコピーするとコンテナパス基準で自動シードされるため、証明書を手作業で配置する必要がありません。
# 마스터에서 워커로 (공유 CA — 크로스노드 TLS 신뢰)
scp -r /etc/kopens/ca root@192.168.0.101:/etc/kopens/
platform.node.envはノード別識別ファイルであり、コピーしないでください。
2.5 ワーカ 起動
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./configure.sh
./start-daemon.sh
./status.sh
ワーカ ノードのstatus.sh出力で以下が RUNNING なら正常です。
- Cassandra (:9042)
- Kafka (:9092)
- Spark Worker (:8081)
参考: ワーカ ノードは server / cep / batch などアプリケーション モジュールは実行しません。インフラ / 分散処理コンポーネントのみがクラスタリングされます。
3. クラスタ検証
3.1 Cassandra クラスタ
# 마스터에서
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./pd node status
期待される出力 (例):
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns Host ID Rack
UN 192.168.0.41 45.2 GiB 256 ? <uuid> rack1
UN 192.168.0.101 44.8 GiB 256 ? <uuid> rack1
UN 192.168.0.102 45.5 GiB 256 ? <uuid> rack1
UN(Up Normal)がすべてのノードに表示されれば正常です。
3.2 Kafka クラスタ
cd /opt/kopens/plantpulse-platform/plantpulse-messaging/kafka/bin
./kafka-broker-api-versions.sh --bootstrap-server 192.168.0.41:9092 | head
ブローカが 3 個として表示されれば正常です。
3.3 Spark クラスタ
ブラウザでマスターの Spark UI にアクセス:
http://192.168.0.41:4440/
Workersタブですべてのワーカが ALIVE 状態であることを確認します。
4. クラスタ運用
ワーカ追加 (動的拡張)
既に稼働中のクラスタにワーカ ノードを追加する手順:
ワーカ 削除
# 1. 워커를 안전하게 비우기 (Cassandra)
ssh root@192.168.0.103 \
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node drain
# 2. 마스터에서 노드 제거
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./pd node remove
# 호스트 ID 입력
# 3. 워커 정지 후 제거
ssh root@192.168.0.103 \
/opt/kopens/plantpulse-platform/plantpulse-startup/stop.sh
ノード 交換
故障ノードを新しいノードに置き換える場合は 管理者: ノード交換手順を参照してください。重要なのは同じ IP / ホスト名を維持しながら新ノードをブートし、bootstrapモードでデータをプルすることです。
5. クラスタ バックアップ
マスター ノードのplantpulse-backupが全クラスタを管理します。
cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin
# Cassandra: 모든 노드에서 snapshot 수집
./backup.sh --cassandra
# PostgreSQL: 마스터에서만
./backup.sh --postgres
バックアップと復旧を参照。
よく発生する問題
| 症状 | 原因 | 対応 |
|---|---|---|
| ワーカ join されない | seed ノード未設定 | cassandra.yamlのseedsにマスター IP が含まれていることを確認 |
| Cassandra トークン不均衡 | 不適切な join | pd node cleanup + トークン再割り当て |
| Kafka レプリケーション不足 | ブローカ ダウン | kafka-topics.sh --describe + レプリケーション係数チェック |
| Spark Worker 登録されない | ファイアウォール 7077 ブロック | プライベート ネットワーク 7077、8081 双方向許可 |
| 証明書 Mismatch | keystore 同期忘れ | マスターでprepare-ssl.sh再実行 + ワーカ再配布 |
| 時間不一致 | NTP 未設定 | chronyc tracking確認、100ms 以下を維持 |
クラスタ 削除
# 각 워커에서
ssh root@<WORKER_IP> /opt/kopens/plantpulse-platform/plantpulse-startup/stop.sh
ssh root@<WORKER_IP> rm -rf /opt/kopens/plantpulse-platform
# 마스터에서
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./stop.sh
rm -rf /opt/kopens/plantpulse-platform
# 데이터 디스크는 별도 정책으로 관리 (필요 시 백업 후 삭제)