システム構成図とは
システム構成図は、システムを構成するサーバー・ストレージ・ネットワーク機器などのハードウェアと、それらにインストールされるOS・ミドルウェア・アプリケーションなどのソフトウェアの全体像を示す設計書です。
構成図は主に「論理構成図」と「物理構成図」の2種類に分けて作成します。論理構成図はシステムの論理的な役割と関係を示し、物理構成図は実際のサーバー台数・設置場所・ネットワーク配線などを示します。基本設計段階では論理構成図を先行して確定し、物理構成はインフラ調達と並行して詳細化します。
💡 論理構成図と物理構成図の違い
論理構成図:Web層・AP層・DB層などの論理的な役割とデータフローを示す。クラウドの場合はALB→EC2→RDSのような論理構成を記述する。物理構成図:実際のサーバー台数・ラック配置・NIC構成・ストレージ接続などの物理的な配置を示す。
① ハードウェア構成の定義
ハードウェア構成では、各サーバーのスペックと役割を明確に定義します。スペック不足はパフォーマンス問題の直接原因になるため、非機能要件(性能・可用性)から逆算して決定します。
| 定義項目 | 定義すべき内容 | 備考 |
|---|---|---|
| サーバー役割 | Webサーバー / APサーバー / DBサーバー / バッチサーバー / ジャンプサーバー など | 1台で複数役割を兼務する場合も明記 |
| 台数・冗長構成 | 本番2台(Active-Active)/ 予備1台 など | 環境(本番・検証・開発)ごとに定義 |
| CPU | コア数・クロック周波数・アーキテクチャ(x86_64 / Arm) | クラウドの場合はvCPU数とインスタンスタイプ |
| メモリ(RAM) | 容量(GB) | JVM ヒープ設計と整合を取ること |
| ストレージ | 種別(SSD/HDD/NVMe)・容量・RAID構成・IOPS | DBサーバーは IOPS を特に重視 |
| NIC | ポート数・帯域(1GbE / 10GbE)・ボンディング設定 | クラウドの場合はENA・SR-IOV対応状況 |
| 設置場所 | データセンター名・ラック番号・リージョン(クラウド) | DR要件がある場合はセカンダリリージョンも定義 |
② ソフトウェア構成の定義
各サーバーにインストールするソフトウェアをOS・MWレイヤー別に整理します。ライセンス費用・サポート終了日(EOL)・ライセンス購入方法も合わせて記録します。
| レイヤー | コンポーネント | 定義すべき内容 |
|---|---|---|
| OS | オペレーティングシステム | 種別(RHEL / Ubuntu / Windows Server)・バージョン・エディション・カーネルバージョン・ライセンス |
| 仮想化 | ハイパーバイザー / コンテナランタイム | VMware vSphere / KVM / Docker / containerd のバージョン |
| Webサーバー | HTTPサーバー | Nginx / Apache HTTPD のバージョン・モジュール構成 |
| APサーバー | アプリケーションコンテナ | Tomcat / WebLogic / WebSphere のバージョン・JDKバージョン |
| DB | データベースエンジン | Oracle / PostgreSQL / MySQL のバージョン・エディション・文字コード |
| 監視エージェント | メトリクス収集 | Zabbix エージェント / CloudWatch エージェント / Datadog エージェント |
| セキュリティ | ウイルス対策・ホスト型IDS | 製品名・バージョン・定義ファイル更新方針 |
⚠️ EOL(End of Life)を必ずチェックする
システムの運用期間中にMWのEOLを迎える場合、追加のアップグレード費用・リスクが発生します。設計書作成時点でEOLを調査し、運用期間中にアップグレードが必要なコンポーネントはロードマップに明記してください。
③ 冗長化・HA構成の定義
可用性要件(SLA・RPO・RTO)を満たすための冗長化方式を定義します。冗長化方式によってコストが大きく変わるため、コストとのバランスを明確にして決定します。
代表的な冗長化方式と特徴は以下の通りです。
- Active-Active:複数サーバーが同時に処理を行う。負荷分散にもなる。セッション共有が必要。
- Active-Standby(ホットスタンバイ):スタンバイサーバーが常時待機し、障害時に自動で切り替わる。Pacemaker / Corosync などで実現。
- コールドスタンバイ:障害時に手動または半自動でスタンバイを起動する。コストは低いがRTOが長くなる。
- Multi-AZ(クラウド):異なるアベイラビリティゾーンにリソースを配置し、AZ障害を跨いだ冗長化を実現する。
④ サーバー一覧表の書き方
構成図に加えて、サーバーの詳細情報を一覧表として記録します。一覧表があることで、インフラ担当者・セキュリティ審査・資産管理において参照性が大幅に向上します。
| サーバーID | ホスト名 | 役割 | IPアドレス | OS | CPU/MEM | ストレージ | 環境 |
|---|---|---|---|---|---|---|---|
| SV-001 | web-01-prd | Webサーバー | 192.168.10.11 | RHEL 9.3 | 4vCPU/8GB | SSD 100GB | 本番 |
| SV-002 | web-02-prd | Webサーバー | 192.168.10.12 | RHEL 9.3 | 4vCPU/8GB | SSD 100GB | 本番 |
| SV-003 | ap-01-prd | APサーバー | 192.168.10.21 | RHEL 9.3 | 8vCPU/32GB | SSD 200GB | 本番 |
| SV-004 | db-01-prd | DBサーバー(Primary) | 192.168.10.31 | RHEL 9.3 | 16vCPU/64GB | SSD 1TB | 本番 |
Python Tips — 実機のHW・SW情報を自動収集する
既存環境の移行案件や棚卸し作業では、複数サーバーの情報を手動で収集するのは非効率です。SSH経由でサーバー情報を自動収集するスクリプトを紹介します。
"""
SSH 経由でサーバーのHW・SW情報を自動収集するスクリプト。
pip install paramiko pandas openpyxl
"""
import paramiko
import pandas as pd
from typing import Optional
# ── 収集コマンド定義 ──────────────────────────────────────────
COMMANDS = {
"hostname": "hostname",
"os_release": "cat /etc/os-release | grep -E '^(NAME|VERSION)=' | tr '\n' ' '",
"kernel": "uname -r",
"cpu_cores": "nproc",
"memory_gb": "awk '/MemTotal/{printf \"%.1f\", $2/1024/1024}' /proc/meminfo",
"disk_root_gb": "df -BG / | awk 'NR==2{print $2}' | tr -d G",
"java_version": "java -version 2>&1 | head -1",
"nginx_version": "nginx -v 2>&1",
"tomcat_version":"find /opt /usr/local -name catalina.sh 2>/dev/null | head -1 | xargs -I{} sh -c 'dirname {} | xargs dirname | xargs basename'",
}
def collect_server_info(host: str, user: str, key_path: str,
port: int = 22) -> dict:
"""
1台のサーバーに接続して情報を収集する。
key_path: SSH秘密鍵のパス(~/.ssh/id_rsa など)
"""
result = {"host": host}
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, port=port, username=user,
key_filename=key_path, timeout=15)
for key, cmd in COMMANDS.items():
stdin, stdout, stderr = client.exec_command(cmd, timeout=10)
output = stdout.read().decode("utf-8").strip()
result[key] = output if output else "N/A"
client.close()
result["status"] = "OK"
except Exception as e:
result["status"] = f"ERROR: {e}"
return result
def collect_all_servers(server_list: list[dict], key_path: str) -> pd.DataFrame:
"""
複数サーバーの情報を収集してDataFrameに変換する。
server_list: [{"host": "192.168.10.11", "user": "ansible"}, ...]
"""
records = []
for srv in server_list:
print(f"Collecting: {srv['host']} ...")
info = collect_server_info(
host=srv["host"],
user=srv.get("user", "root"),
key_path=key_path,
)
records.append(info)
return pd.DataFrame(records)
if __name__ == "__main__":
# ── 対象サーバーリスト ────────────────────────────────────
servers = [
{"host": "192.168.10.11", "user": "ec2-user"},
{"host": "192.168.10.12", "user": "ec2-user"},
{"host": "192.168.10.21", "user": "ec2-user"},
]
KEY_PATH = "~/.ssh/id_rsa"
df = collect_all_servers(servers, KEY_PATH)
print(df.to_string(index=False))
# Excel に出力(設計書の素材として活用)
df.to_excel("server_inventory.xlsx", index=False)
print("\nserver_inventory.xlsx に出力しました")
✅ クラウド環境の場合
AWS 環境であれば boto3 ライブラリを使い、EC2インスタンスの情報(インスタンスタイプ・AMI・タグ・セキュリティグループ)をAPIから取得できます。describe_instances() を使えば、SSH不要でインスタンス一覧を収集できます。
インストール済みパッケージの一括確認
import subprocess
import platform
def get_installed_packages() -> list[dict]:
"""
ローカルサーバーのインストール済みパッケージ一覧を取得する。
RHEL/CentOS系: rpm -qa / Ubuntu/Debian系: dpkg -l
"""
system = platform.system()
if system != "Linux":
raise RuntimeError(f"Unsupported OS: {system}")
# パッケージマネージャーを自動判別
try:
# RHEL / Rocky / Alma
result = subprocess.run(
["rpm", "-qa", "--queryformat",
"%{NAME}\t%{VERSION}-%{RELEASE}\t%{ARCH}\n"],
capture_output=True, text=True, timeout=30
)
lines = result.stdout.strip().split("\n")
return [
{"name": p[0], "version": p[1], "arch": p[2]}
for line in lines if (p := line.split("\t")) and len(p) == 3
]
except FileNotFoundError:
pass
# Ubuntu / Debian
result = subprocess.run(
["dpkg-query", "-W", "-f=${Package}\t${Version}\t${Architecture}\n"],
capture_output=True, text=True, timeout=30
)
lines = result.stdout.strip().split("\n")
return [
{"name": p[0], "version": p[1], "arch": p[2]}
for line in lines if (p := line.split("\t")) and len(p) == 3
]
if __name__ == "__main__":
pkgs = get_installed_packages()
# MW関連だけ抽出
mw_keywords = ["nginx", "tomcat", "java", "postgresql", "mysql",
"redis", "httpd", "openssl", "openssh"]
mw_pkgs = [p for p in pkgs
if any(kw in p["name"].lower() for kw in mw_keywords)]
for p in mw_pkgs:
print(f"{p['name']:40s} {p['version']}")
定義チェックリスト
| チェック項目 | 確認ポイント |
|---|---|
| □ 全サーバーの役割が定義されているか | Web・AP・DB・バッチ・ジャンプサーバーなど役割が明確か |
| □ スペックの算出根拠があるか | 性能要件(TPS・レスポンスタイム)から逆算してスペックを決定しているか |
| □ ソフトウェアのバージョンが確定しているか | すべてのMWにバージョン番号が記載されているか |
| □ EOLを確認しているか | システム運用期間中にEOLを迎えるコンポーネントがないか |
| □ 冗長化方式が可用性要件を満たすか | SLA・RTO・RPOを満たす冗長化構成になっているか |
| □ ライセンスが調達済みか | 商用ソフトウェアのライセンス費用・本数が確認されているか |