Chuyển đến nội dung chính

レッスン 4: インフラストラクチャの準備

ハードウェア要件、ネットワーク/ファイアウォール構成、3 つの VM/サーバーのセットアップ、HA クラスターの時刻同期に関する詳細な手順。

目的_

このレッスンの後、次のことを学びます:_

  • _Patroni クラスターのハードウェア要件とソフトウェア要件を理解する_
  • ネットワークとファイアウォールを構成する
  • 3 つの VM/サーバーをセットアップする(VirtualBox/VMware/クラウド)
  • SSH キーベースの認証をセットアップ
  • NTP/chrony と時刻を同期

1。ハードウェア要件とソフトウェア_

ラボ アーキテクチャ

3 つのノードのクラスターをセットアップします。

アーキテクチャ ラボ

ハードウェア要件 (ごとノード)

最小値 (ラボ/開発):

  • CPU: 2 コア_
  • RAM_: 4 GB
  • ディスク: 20 GB (OS) + 20 GB (PostgreSQL データ)
  • ネットワーク: 1 Gbps

推奨(実稼働):

  • CPU: 4 ~ 8 コア
  • RAM: 8 ~ 32 GB (環境によって異なります)ワークロード)_
  • ディスク:
    • OS: 50 GB SSD
    • PostgreSQL データ: 100+ GB NVMe SSD
    • WAL: 別個のディスク (オプション、パフォーマンス)
  • ネットワーク_: 10 Gbps、冗長 NIC_

ストレージ推奨事項:

/dev/sda  → OS (Ubuntu 22.04)
/dev/sdb  → PostgreSQL data (/var/lib/postgresql)
/dev/sdc  → WAL files (/var/lib/postgresql/pg_wal) [optional]

ソフトウェア要件

オペレーティング システム:

  • Ubuntu 22.04 LTS (推奨)_
  • Rocky Linux 9 / AlmaLinux 9
  • Debian 12_

ソフトウェアスタック:_

Component           Version      Purpose
─────────────────────────────────────────────────
PostgreSQL          18.x  Database
Patroni             3.x          HA orchestration
etcd                3.5.x        DCS
Python              3.9+         Patroni runtime
HAProxy (optional)  2.8+         Load balancer
PgBouncer (optional) 1.21+       Connection pooler

ネットワーク要件

レイテンシー:

  • PostgreSQL ノード間: < 10 ミリ秒 (同じデータセンター)
  • etcd ノード間: < 5 ミリ秒 (重要!)_
  • クライアントからデータベースまで: <; 50ms_

帯域幅:_

  • レプリケーション:書き込み負荷に依存
  • etcd:低帯域幅ですが低遅延重要_

開くポート:

サービス_ポートプロトコル_目的
PostgreSQL5432_TCP_データベース接続_
Patroni REST API8008_TCP_ヘルスチェック、管理_
etcd クライアント2379TCPクライアントから etcd通信
etcdピア2380TCPetcdクラスタ通信
SSH22_TCPリモート管理

2.ネットワークとファイアウォールの構成

IP 計画

ノードの割り当て_:_

Hostname    IP Address    Role
─────────────────────────────────────
pg-node1    10.0.1.11     PostgreSQL + Patroni + etcd
pg-node2    10.0.1.12     PostgreSQL + Patroni + etcd
pg-node3    10.0.1.13     PostgreSQL + Patroni + etcd

オプションコンポーネント:

haproxy     10.0.1.10     Load balancer (VIP)
monitoring  10.0.1.20     Prometheus + Grafana

ホスト名の構成

各ノード:

# Set hostname
sudo hostnamectl set-hostname pg-node1  # Change for each node

Edit /etc/hosts

sudo tee -a /etc/hosts << EOF 10.0.1.11 pg-node1 10.0.1.12 pg-node2 10.0.1.13 pg-node3 EOF

Verify

hostname -f ping -c 2 pg-node2 ping -c 2 pg-node3

ファイアウォール構成(UFW)

Ubuntu 上:

# Enable UFW
sudo ufw enable

Allow SSH

sudo ufw allow 22/tcp

PostgreSQL

sudo ufw allow from 10.0.1.0/24 to any port 5432

Patroni REST API

sudo ufw allow from 10.0.1.0/24 to any port 8008

etcd client port

sudo ufw allow from 10.0.1.0/24 to any port 2379

etcd peer port

sudo ufw allow from 10.0.1.0/24 to any port 2380

Verify rules

sudo ufw status numbered

期待される出力:

Status: active

 To                         Action      From
 --                         ------      ----

[ 1] 22/tcp ALLOW IN Anywhere [ 2] 5432 ALLOW IN 10.0.1.0/24 [ 3] 8008 ALLOW IN 10.0.1.0/24 [ 4] 2379 ALLOW IN 10.0.1.0/24 [ 5] 2380 ALLOW IN 10.0.1.0/24

ファイアウォール構成(ファイアウォール)

Rocky Linux / AlmaLinux 上:

# Enable firewalld
sudo systemctl enable --now firewalld

Add services

sudo firewall-cmd --permanent --add-service=postgresql sudo firewall-cmd --permanent --add-port=8008/tcp sudo firewall-cmd --permanent --add-port=2379/tcp sudo firewall-cmd --permanent --add-port=2380/tcp

Allow from specific subnet

sudo firewall-cmd --permanent --add-rich-rule=' rule family="ipv4" source address="10.0.1.0/24" port protocol="tcp" port="5432" accept'

Reload

sudo firewall-cmd --reload

Verify

sudo firewall-cmd --list-all

ネットワーク パフォーマンス テスト

間のレイテンシをテストするノード_:

# Install tools
sudo apt install -y iputils-ping netcat-openbsd iperf3

Test ping latency

ping -c 10 pg-node2

Expected: < 1ms same datacenter, < 10ms same region

Test TCP connectivity

nc -zv pg-node2 5432 nc -zv pg-node2 2379

Test bandwidth (on receiver node2)

iperf3 -s

From sender node1

iperf3 -c pg-node2 -t 10

Expected: > 500 Mbps on 1Gbps network

3。 3 つの VM/サーバーのセットアップ

オプション 1: VirtualBox (ローカル開発)

VM テンプレートの作成:

# Download Ubuntu 22.04 ISO
wget https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso

VirtualBox CLI

VBoxManage createvm --name "pg-node1" --ostype Ubuntu_64 --register

VBoxManage modifyvm "pg-node1"
--memory 4096
--cpus 2
--nic1 bridged
--bridgeadapter1 en0
--boot1 disk

VBoxManage createhd --filename ~/VirtualBox\ VMs/pg-node1/pg-node1.vdi --size 40960

VBoxManage storagectl "pg-node1" --name "SATA Controller" --add sata --controller IntelAHCI VBoxManage storageattach "pg-node1" --storagectl "SATA Controller" --port 0 --device 0
--type hdd --medium ~/VirtualBox\ VMs/pg-node1/pg-node1.vdi

Install OS, then clone for other nodes

VBoxManage clonevm "pg-node1" --name "pg-node2" --register VBoxManage clonevm "pg-node1" --name "pg-node3" --register

構成network:_

# Edit /etc/netplan/00-installer-config.yaml
network:
ethernets:
enp0s3:
addresses:
- 10.0.1.11/24
routes:
- to: default
via: 10.0.1.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
version: 2

Apply

sudo netplan apply

オプション 2: VMware Workstation

VM の作成___: 1. 新しい仮想マシン → カスタム 2. ハードウェア互換性: Workstation 17.x 3. インストール元: ISO イメージ(Ubuntu 22.04) 4. ゲスト OS: Linux → Ubuntu 64 ビット 5. VM 名: pg-node1 6. プロセッサ: 2 コア 7. メモリ: 4096 MB 8. ネットワーク: ポート転送を備えたブリッジまたは NAT 9. ディスク: 40 GB、単一ファイル 10. 完了してインストールOS

他のノードのクローン:

  • VMを右クリック→「管理」→「クローン」
  • リンククローンまたは完全を作成クローン_
  • VM 名とネットワーク設定の変更

インストール後の手順 (すべてのプラットフォーム)

更新システム_:

# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y

Rocky Linux/AlmaLinux

sudo dnf update -y

Install essential tools

sudo apt install -y
curl
wget
vim
git
net-tools
htop
iotop
sysstat
build-essential

Diセーブル スワップ (データベースに推奨):

# Check current swap
free -h

Disable swap

sudo swapoff -a

Remove from /etc/fstab

sudo sed -i '/swap/d' /etc/fstab

Verify

free -h

システム制限を設定:

# Edit /etc/security/limits.conf
sudo tee -a /etc/security/limits.conf << EOF
postgres soft nofile 65536
postgres hard nofile 65536
postgres soft nproc 8192
postgres hard nproc 8192
EOF

Edit /etc/sysctl.conf

sudo tee -a /etc/sysctl.conf << EOF

PostgreSQL optimizations

vm.swappiness = 1 vm.overcommit_memory = 2 vm.dirty_background_ratio = 5 vm.dirty_ratio = 10 net.ipv4.tcp_keepalive_time = 200 net.ipv4.tcp_keepalive_intvl = 200 net.ipv4.tcp_keepalive_probes = 5 EOF

Apply

sudo sysctl -p

4。 SSH キーベースの認証_

SSH キーの生成

ローカルマシン/ジャンプサーバー上:

# Generate SSH key pair
ssh-keygen -t ed25519 -C "patroni-cluster" -f ~/.ssh/patroni_cluster

Output:

~/.ssh/patroni_cluster (private key)

~/.ssh/patroni_cluster.pub (public key)

Set permissions

chmod 600 ~/.ssh/patroni_cluster chmod 644 ~/.ssh/patroni_cluster.pub

キーをすべてにコピーノード

# Copy to each node
ssh-copy-id -i ~/.ssh/patroni_cluster.pub [email protected]
ssh-copy-id -i ~/.ssh/patroni_cluster.pub [email protected]
ssh-copy-id -i ~/.ssh/patroni_cluster.pub [email protected]

Or manually

for node in pg-node1 pg-node2 pg-node3; do cat ~/.ssh/patroni_cluster.pub | ssh ubuntu@$node
"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" done

SSH クライアントの構成

ユーザーに関する編集

各ノードノード_:

# As postgres user (after PostgreSQL installation)
sudo -u postgres ssh-keygen -t ed25519 -N "" -f /var/lib/postgresql/.ssh/id_ed25519

Copy public key to other nodes

for node in pg-node1 pg-node2 pg-node3; do sudo -u postgres ssh-copy-id -i /var/lib/postgresql/.ssh/id_ed25519.pub postgres@$node done

5。時刻同期 (NTP/chrony)

時刻同期が重要な理由

重要:

  • 分散システムは一貫したシステムに依存します。時間_
  • etcd はリーダーの選出にタイムスタンプを使用
  • PostgreSQL WAL にはタイムスタンプが含まれます_
  • 監視とデバッグには正確な時間が必要_

_許容可能ドリフト: < 500 ミリ秒 (理想的には 100 ミリ秒未満)

Ubuntu/Debian:

# Install chrony
sudo apt install -y chrony

Edit /etc/chrony/chrony.conf

sudo vim /etc/chrony/chrony.conf

H TMLTAG_335構成:

# Use public NTP servers
pool ntp.ubuntu.com iburst maxsources 4
pool 0.ubuntu.pool.ntp.org iburst maxsources 1
pool 1.ubuntu.pool.ntp.org iburst maxsources 1
pool 2.ubuntu.pool.ntp.org iburst maxsources 2

Or use local NTP server

server 10.0.1.1 iburst

Record the rate at which the system clock gains/losses time

driftfile /var/lib/chrony/chrony.drift

Allow NTP client access from local network

allow 10.0.1.0/24

Serve time even if not synchronized to a time source

local stratum 10

Specify directory for log files

logdir /var/log/chrony

Select which information is logged

log measurements statistics tracking

開始して有効化_:

# Start chrony
sudo systemctl enable --now chrony

Check status

sudo systemctl status chrony

Verify time synchronization

chronyc sources -v chronyc tracking

予想通り出力_:

MS Name/IP address         Stratum Poll Reach LastRx Last sample

^* time.cloudflare.com 3 6 377 32 +123us[ +456us] +/- 20ms ^+ ntp.ubuntu.com 2 6 377 33 -234us[ -101us] +/- 15ms

代替: systemd-timesyncd (より単純な)

Ubuntu/Debian:_

# Install (usually pre-installed)
sudo apt install -y systemd-timesyncd

Edit /etc/systemd/timesyncd.conf

sudo vim /etc/systemd/timesyncd.conf

HTML TAG_353構成:

[Time]
NTP=ntp.ubuntu.com 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org
FallbackNTP=time.cloudflare.com

有効にして確認:

# Enable
sudo systemctl enable --now systemd-timesyncd

Check status

timedatectl status systemctl status systemd-timesyncd

Should show "System clock synchronized: yes"

全体の時刻同期を確認するクラスター_

検証スクリプトを作成:

#!/bin/bash

check_time_sync.sh

echo "Checking time synchronization across cluster..." echo "================================================"

for node in pg-node1 pg-node2 pg-node3; do echo -n "$node: " ssh $node "date '+%Y-%m-%d %H:%M:%S.%N %Z'" done

echo "" echo "Time difference check:" time1=$(ssh pg-node1 "date +%s%N") time2=$(ssh pg-node2 "date +%s%N") time3=$(ssh pg-node3 "date +%s%N")

diff12=$(( (time1 - time2) / 1000000 )) # Convert to milliseconds diff13=$(( (time1 - time3) / 1000000 )) diff23=$(( (time2 - time3) / 1000000 ))

echo "node1 vs node2: ${diff12}ms" echo "node1 vs node3: ${diff13}ms" echo "node2 vs node3: ${diff23}ms"

if [ ${diff12#-} -lt 100 ] && [ ${diff13#-} -lt 100 ] && [ ${diff23#-} -lt 100 ]; then echo "✓ Time synchronization is good (< 100ms)" else echo "✗ WARNING: Time drift detected! Please fix NTP configuration" fi

chmod +x check_time_sync.sh
./check_time_sync.sh

6。ラボ: インフラストラクチャの完全なセットアップ_

ラボの目的_

  • 正しいネットワークを使用して 3 つの VM をセットアップ
  • 必要なすべてのポートのファイアウォールを構成
  • パスワードなしの SSH をセットアップする認証
  • NTP と時刻を同期する__
  • ノード間の接続を確認する_

ラボのステップ

ステップ 1: VM を確認する仕様_

# On each node
ssh pg-node1 "cat /etc/os-release | grep PRETTY_NAME"
ssh pg-node1 "nproc"
ssh pg-node1 "free -h"
ssh pg-node1 "df -h"

Repeat for node2, node3

ステップ 2: ネットワーク接続テストHTMLTAG_392__CODEBLOCK_29

ステップ 3: SSH 認証の確認

# Test SSH without password
for node in pg-node1 pg-node2 pg-node3; do
echo "Testing SSH to $node..."
ssh -o BatchMode=yes $node "echo 'SSH OK'" || echo "SSH FAILED"
done

ステップ 4: 時刻同期の確認

./check_time_sync.sh

ステップ 5: 包括的な実行検証_

cat > validate_infrastructure.sh << 'EOF'
#!/bin/bash

RED='\033[0;31m' GREEN='\033[0;32m' NC='\033[0m' # No Color

NODES=("pg-node1" "pg-node2" "pg-node3")

echo "=========================================" echo "Infrastructure Validation Report" echo "=========================================" echo ""

for node in "${NODES[@]}"; do echo "Checking $node..."

Hostname

hostname=$(ssh $node "hostname") echo " Hostname: $hostname"

IP Address

ip=$(ssh $node "hostname -I | awk '{print $1}'") echo " IP: $ip"

CPU/RAM

cpu=$(ssh $node "nproc") ram=$(ssh $node "free -h | grep Mem | awk '{print $2}'") echo " CPU: ${cpu} cores, RAM: ${ram}"

Disk

disk=$(ssh $node "df -h / | tail -1 | awk '{print $4}'") echo " Disk free: $disk"

Firewall

firewall=$(ssh $node "sudo ufw status | grep Status | awk '{print $2}'") echo " Firewall: $firewall"

Time sync

timesync=$(ssh $node "timedatectl | grep 'System clock synchronized' | awk '{print $4}'") if [ "$timesync" == "yes" ]; then echo -e " Time sync: ${GREEN}✓${NC}" else echo -e " Time sync: ${RED}✗${NC}" fi

echo "" done

echo "=========================================" echo "Connectivity Matrix" echo "========================================="

for src in "${NODES[@]}"; do for dst in "${NODES[@]}"; do if [ "$src" != "$dst" ]; then if ssh $src "ping -c 1 -W 1 $dst" > /dev/null 2>&1; then echo -e "$src → $dst: ${GREEN}✓${NC}" else echo -e "$src → $dst: ${RED}✗${NC}" fi fi done done

echo "" echo "=========================================" echo "Validation Complete" echo "=========================================" EOF

chmod +x validate_infrastructure.sh ./validate_infrastructure.sh

期待される出力_ (すべて緑色のチェックマーク):

=========================================
Infrastructure Validation Report

Checking pg-node1... Hostname: pg-node1 IP: 10.0.1.11 CPU: 2 cores, RAM: 4.0Gi Disk free: 25G Firewall: active Time sync: ✓

[... similar for node2, node3 ...]

========================================= Connectivity Matrix

pg-node1 → pg-node2: ✓ pg-node1 → pg-node3: ✓ pg-node2 → pg-node1: ✓ pg-node2 → pg-node3: ✓ pg-node3 → pg-node1: ✓ pg-node3 → pg-node2: ✓

7。概要

チェックリスト インフラストラクチャ

レッスン 5 に進む前に、

✅ 3 台の VM/サーバー 十分な CPU、RAM、ディスク

✅ ネットワーク 構成: 静的 IP、 /etc/hosts

✅ ファイアウォール ルール: ポート 22、5432、8008、2379、 2380_

✅ SSH キー 導入済み、パスワードなしの認証は機能

✅ 時間sync chrony/timesyncd で構成

✅ システム最適化: スワップ無効、カーネルパラメータ調整済み

✅ 接続が確認されました: すべてのノードが相互に接続可能

トラブルシューティング

問題: SSH 接続拒否_

# Check SSH service
sudo systemctl status sshd

Check firewall

sudo ufw status | grep 22

問題: タイムドリフトが検出されました

# Force time sync
sudo chronyc makestep

Or restart chrony

sudo systemctl restart chrony

問題: ネットワーク到達不能_

# Check network interface
ip addr show

Check routing

ip route show

Restart networking

sudo systemctl restart systemd-networkd

確認質問_

  1. Patroni クラスターに少なくとも 3 つのノードが必要なのはなぜですか?
  2. ファイアウォールが必要ですどのポートを開きますか?その理由は何ですか?
  3. 分散システムにとって時刻同期が重要なのはなぜですか?
  4. PostgreSQL サーバーに対してスワップを有効にする必要がありますか?その理由は何ですか?
  5. etcd ノード間のレイテンシはどれくらいにすべきですか?

次のレッスンの準備

レッスン 5 で手順を説明します インストールPostgreSQL:

  • パッケージ リポジトリから PostgreSQL をインストール_
  • 構成 postgresql.conf
  • セットアップpg_hba.conf_
  • ラボ: 3 つのノードに PostgreSQL をインストール_