8.4 実践的シナリオ
様々な環境・規模・要件におけるZabbix実装の実践的パターンとベストプラクティス
概要
実践的シナリオでは、実際の企業環境で遭遇する様々な要件・制約・課題に対応するZabbix実装パターンを学習します。企業規模、技術スタック、運用体制に応じた最適な監視戦略により、効果的で持続可能な監視システムを構築できます。
シナリオベース学習の価値
要素 | 学習効果 | 実用性 |
---|---|---|
企業規模別実装 | 段階的成長対応 | スケーラブル設計 |
クラウド統合 | モダンインフラ対応 | 柔軟性・効率性 |
DevOps統合 | 開発・運用連携 | 自動化・迅速性 |
コンテナ監視 | 最新技術対応 | 動的環境対応 |
業界特化 | 専門要件対応 | コンプライアンス |
企業規模別導入シナリオ
小規模企業(50-200台)
シンプル統合監視の実装
yaml
# 小規模企業向けZabbix設計
小規模企業要件:
環境特性:
- サーバー数: 50-200台
- 運用人員: 1-3名
- IT予算: 限定的
- 技術専門性: 中程度
設計方針:
- 単一サーバー構成
- オールインワン実装
- テンプレート活用
- 最小限の設定
- 自動化重視
# インフラ構成
インフラ設計:
Zabbixサーバー:
スペック:
- CPU: 4コア
- Memory: 8GB
- Storage: 500GB SSD
- OS: Ubuntu 22.04 LTS
役割:
- Zabbixサーバー
- データベース (MySQL)
- Webインターフェース
- 監視対象エージェント
ネットワーク:
構成: "フラットネットワーク"
セキュリティ: "ファイアウォール + VPN"
接続: "LAN + リモートサイト"
監視対象:
- Windowsサーバー: 20台
- Linuxサーバー: 15台
- ネットワーク機器: 10台
- 仮想化環境: VMware vSphere
- クラウドリソース: AWS/Azure (部分的)
実装テンプレート
bash
#!/bin/bash
# 小規模企業向けZabbix自動セットアップスクリプト
COMPANY_NAME="Small Enterprise"
SETUP_LOG="/var/log/zabbix/small_enterprise_setup.log"
CONFIG_DIR="/etc/zabbix/templates/small_enterprise"
# ログ関数
log_setup() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$SETUP_LOG"
}
# 基本システム設定
setup_basic_system() {
log_setup "Setting up basic system for small enterprise..."
# パッケージ更新
apt update && apt upgrade -y
# 必要パッケージインストール
apt install -y mysql-server nginx php-fpm php-mysql \
zabbix-server-mysql zabbix-frontend-php zabbix-nginx-conf \
zabbix-agent zabbix-get
# MySQL設定
mysql_secure_installation
# Zabbixデータベース作成
mysql -e "CREATE DATABASE zabbix CHARACTER SET utf8 COLLATE utf8_bin;"
mysql -e "CREATE USER 'zabbix'@'localhost' IDENTIFIED BY 'ZabbixPass123!';"
mysql -e "GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'localhost';"
mysql -e "FLUSH PRIVILEGES;"
# スキーマインポート
zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -u zabbix -p'ZabbixPass123!' zabbix
log_setup "Basic system setup completed"
}
# 小規模企業向け設定最適化
optimize_for_small_enterprise() {
log_setup "Optimizing configuration for small enterprise..."
# Zabbixサーバー設定
cat > /etc/zabbix/zabbix_server.conf << 'EOF'
# Small Enterprise Zabbix Server Configuration
LogFile=/var/log/zabbix/zabbix_server.log
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=ZabbixPass123!
StartPollers=5
StartPingers=2
StartPollersUnreachable=1
StartTrappers=5
StartTimers=1
StartEscalators=1
StartAlerters=1
StartDiscoverers=1
StartHTTPPollers=2
CacheSize=64M
ValueCacheSize=128M
TrendCacheSize=32M
HistoryCacheSize=64M
HistoryIndexCacheSize=32M
Timeout=10
AlertScriptsPath=/usr/lib/zabbix/alertscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
LogSlowQueries=3000
StartVMwareCollectors=1
VMwareCacheSize=64M
EOF
# PHP-FPM設定最適化
sed -i 's/max_execution_time = 30/max_execution_time = 300/' /etc/php/*/fpm/php.ini
sed -i 's/max_input_time = 60/max_input_time = 300/' /etc/php/*/fpm/php.ini
sed -i 's/post_max_size = 8M/post_max_size = 16M/' /etc/php/*/fpm/php.ini
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 2M/' /etc/php/*/fpm/php.ini
sed -i 's/;date.timezone =/date.timezone = Asia\/Tokyo/' /etc/php/*/fpm/php.ini
# MySQL最適化(小規模環境向け)
cat > /etc/mysql/mysql.conf.d/zabbix.cnf << 'EOF'
[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 256M
innodb_log_buffer_size = 8M
max_connections = 200
query_cache_size = 64M
query_cache_type = 1
tmp_table_size = 64M
max_heap_table_size = 64M
innodb_file_per_table = 1
EOF
log_setup "Configuration optimization completed"
}
# 小規模企業向けテンプレート導入
deploy_small_enterprise_templates() {
log_setup "Deploying small enterprise templates..."
mkdir -p "$CONFIG_DIR"
# Windows Server Template
cat > "$CONFIG_DIR/template_windows_server.xml" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>6.0</version>
<templates>
<template>
<template>Template Small Enterprise Windows</template>
<name>Template Small Enterprise Windows</name>
<description>Windows Server monitoring template for small enterprise</description>
<groups>
<group>
<name>Templates/Operating systems</name>
</group>
</groups>
<applications>
<application>
<name>CPU</name>
</application>
<application>
<name>Memory</name>
</application>
<application>
<name>Network</name>
</application>
<application>
<name>Storage</name>
</application>
<application>
<name>Services</name>
</application>
</applications>
<items>
<item>
<name>CPU utilization</name>
<type>ZABBIX_ACTIVE</type>
<key>perf_counter[\Processor(_Total)\% Processor Time]</key>
<delay>60s</delay>
<value_type>FLOAT</value_type>
<units>%</units>
<applications>
<application>
<name>CPU</name>
</application>
</applications>
</item>
<item>
<name>Memory utilization</name>
<type>ZABBIX_ACTIVE</type>
<key>vm.memory.util</key>
<delay>60s</delay>
<value_type>FLOAT</value_type>
<units>%</units>
<applications>
<application>
<name>Memory</name>
</application>
</applications>
</item>
</items>
<triggers>
<trigger>
<expression>{Template Small Enterprise Windows:perf_counter[\Processor(_Total)\% Processor Time].avg(5m)}>85</expression>
<name>High CPU utilization on {HOST.NAME}</name>
<priority>WARNING</priority>
</trigger>
<trigger>
<expression>{Template Small Enterprise Windows:vm.memory.util.avg(5m)}>90</expression>
<name>High memory utilization on {HOST.NAME}</name>
<priority>WARNING</priority>
</trigger>
</triggers>
</template>
</templates>
</zabbix_export>
EOF
# Linux Server Template
cat > "$CONFIG_DIR/template_linux_server.xml" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>6.0</version>
<templates>
<template>
<template>Template Small Enterprise Linux</template>
<name>Template Small Enterprise Linux</name>
<description>Linux server monitoring template for small enterprise</description>
<groups>
<group>
<name>Templates/Operating systems</name>
</group>
</groups>
<applications>
<application>
<name>CPU</name>
</application>
<application>
<name>Memory</name>
</application>
<application>
<name>Network</name>
</application>
<application>
<name>Filesystems</name>
</application>
</applications>
<items>
<item>
<name>CPU utilization</name>
<type>ZABBIX_ACTIVE</type>
<key>system.cpu.util</key>
<delay>60s</delay>
<value_type>FLOAT</value_type>
<units>%</units>
<applications>
<application>
<name>CPU</name>
</application>
</applications>
</item>
<item>
<name>Memory utilization</name>
<type>ZABBIX_ACTIVE</type>
<key>vm.memory.util</key>
<delay>60s</delay>
<value_type>FLOAT</value_type>
<units>%</units>
<applications>
<application>
<name>Memory</name>
</application>
</applications>
</item>
</items>
<discovery_rules>
<discovery_rule>
<name>Filesystem discovery</name>
<type>ZABBIX_ACTIVE</type>
<key>vfs.fs.discovery</key>
<delay>3600s</delay>
<item_prototypes>
<item_prototype>
<name>Disk space usage {#FSNAME}</name>
<type>ZABBIX_ACTIVE</type>
<key>vfs.fs.size[{#FSNAME},pused]</key>
<delay>300s</delay>
<value_type>FLOAT</value_type>
<units>%</units>
<applications>
<application>
<name>Filesystems</name>
</application>
</applications>
</item_prototype>
</item_prototypes>
<trigger_prototypes>
<trigger_prototype>
<expression>{Template Small Enterprise Linux:vfs.fs.size[{#FSNAME},pused].last()}>90</expression>
<name>Disk space usage high on {#FSNAME} ({HOST.NAME})</name>
<priority>WARNING</priority>
</trigger_prototype>
</trigger_prototypes>
</discovery_rule>
</discovery_rules>
</template>
</templates>
</zabbix_export>
EOF
log_setup "Small enterprise templates created"
}
# 自動化スクリプト配置
setup_automation_scripts() {
log_setup "Setting up automation scripts..."
# 日次ヘルスチェックスクリプト
cat > /usr/local/bin/zabbix_daily_check.sh << 'EOF'
#!/bin/bash
# Small Enterprise Daily Health Check
LOG_FILE="/var/log/zabbix/daily_check.log"
EMAIL_RECIPIENT="[email protected]"
# ヘルスチェック実行
check_health() {
local status="OK"
local issues=""
# Zabbixサーバープロセス確認
if ! pgrep -f zabbix_server > /dev/null; then
status="ERROR"
issues="$issues\n- Zabbix server not running"
fi
# データベース接続確認
if ! mysql -u zabbix -p'ZabbixPass123!' -e "SELECT 1;" zabbix >/dev/null 2>&1; then
status="ERROR"
issues="$issues\n- Database connection failed"
fi
# ディスク容量確認
local disk_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$disk_usage" -gt 85 ]; then
status="WARNING"
issues="$issues\n- High disk usage: ${disk_usage}%"
fi
# レポート生成
local report="Daily Zabbix Health Check - $(date)\n\nStatus: $status"
if [ -n "$issues" ]; then
report="$report\n\nIssues detected:$issues"
fi
echo -e "$report" | tee -a "$LOG_FILE"
# 問題がある場合はメール通知
if [ "$status" != "OK" ]; then
echo -e "$report" | mail -s "Zabbix Health Check Alert" "$EMAIL_RECIPIENT"
fi
}
check_health
EOF
chmod +x /usr/local/bin/zabbix_daily_check.sh
# Cron設定
cat > /etc/cron.d/zabbix-daily-check << 'EOF'
# Daily Zabbix health check for small enterprise
0 8 * * * root /usr/local/bin/zabbix_daily_check.sh
EOF
log_setup "Automation scripts configured"
}
# サービス起動・有効化
start_services() {
log_setup "Starting and enabling services..."
systemctl restart mysql
systemctl restart zabbix-server
systemctl restart zabbix-agent
systemctl restart nginx
systemctl restart php*-fpm
systemctl enable mysql
systemctl enable zabbix-server
systemctl enable zabbix-agent
systemctl enable nginx
systemctl enable php*-fpm
log_setup "All services started and enabled"
}
# メイン実行
main() {
echo "Small Enterprise Zabbix Setup"
echo "============================="
log_setup "Starting small enterprise Zabbix setup..."
setup_basic_system
optimize_for_small_enterprise
deploy_small_enterprise_templates
setup_automation_scripts
start_services
log_setup "Small enterprise setup completed successfully!"
echo ""
echo "✓ Setup completed!"
echo "📍 Web interface: http://$(hostname -I | awk '{print $1}')/zabbix"
echo "👤 Default login: Admin / zabbix"
echo "📝 Setup log: $SETUP_LOG"
echo ""
echo "Next steps:"
echo "1. Change default password"
echo "2. Import templates from $CONFIG_DIR"
echo "3. Configure monitoring targets"
echo "4. Set up email notifications"
}
# スクリプト実行
main "$@"
中規模企業(500-2000台)
分散監視アーキテクチャ
yaml
# 中規模企業向けZabbix分散設計
中規模企業要件:
環境特性:
- サーバー数: 500-2000台
- 拠点数: 3-10箇所
- 運用人員: 5-15名
- 可用性要件: 99.5%以上
アーキテクチャ:
中央監視センター:
- Zabbixサーバー (Active/Standby)
- データベースクラスター
- Webインターフェース (負荷分散)
- 管理・レポート機能
拠点別プロキシ:
- 各拠点にZabbixプロキシ
- ローカルデータ収集
- 中央への転送
- 回線障害時の自律動作
# インフラ構成
分散監視設計:
中央サイト:
Zabbixサーバー1 (Primary):
- CPU: 16コア
- Memory: 32GB
- Storage: 2TB SSD (RAID1)
Zabbixサーバー2 (Standby):
- CPU: 16コア
- Memory: 32GB
- Storage: 2TB SSD (RAID1)
データベースクラスター:
- MySQL Master-Master構成
- 各ノード: 32GB RAM, 4TB SSD
- レプリケーション + フェイルオーバー
ロードバランサー:
- HAProxy / Nginx
- SSL終端
- ヘルスチェック
拠点プロキシ (各拠点):
Zabbixプロキシ:
- CPU: 8コア
- Memory: 16GB
- Storage: 500GB SSD
- ローカルデータベース (SQLite)
監視対象:
- 拠点サーバー: 50-200台
- ネットワーク機器: 10-50台
- 業務アプリケーション
- インフラサービス
プロキシ自動配置スクリプト
python
#!/usr/bin/env python3
"""中規模企業向けZabbixプロキシ自動配置システム"""
import json
import requests
import subprocess
import yaml
from typing import Dict, List
import ipaddress
class ZabbixProxyDeployment:
def __init__(self, config_file: str):
with open(config_file, 'r') as f:
self.config = yaml.safe_load(f)
self.zabbix_api_url = self.config['zabbix']['api_url']
self.api_token = self.config['zabbix']['api_token']
self.sites = self.config['sites']
def deploy_proxy_infrastructure(self) -> Dict:
"""プロキシインフラの自動配置"""
deployment_results = {
'successful_deployments': [],
'failed_deployments': [],
'total_sites': len(self.sites)
}
for site in self.sites:
try:
result = self.deploy_single_proxy(site)
if result['success']:
deployment_results['successful_deployments'].append(result)
else:
deployment_results['failed_deployments'].append(result)
except Exception as e:
deployment_results['failed_deployments'].append({
'site': site['name'],
'error': str(e),
'success': False
})
return deployment_results
def deploy_single_proxy(self, site: Dict) -> Dict:
"""単一拠点へのプロキシ配置"""
print(f"Deploying proxy to site: {site['name']}")
# VM作成(仮想化環境の場合)
if site.get('virtualization') == 'vmware':
vm_result = self.create_vmware_vm(site)
if not vm_result['success']:
return vm_result
# OS設定
os_result = self.configure_proxy_os(site)
if not os_result['success']:
return os_result
# Zabbixプロキシインストール
proxy_result = self.install_zabbix_proxy(site)
if not proxy_result['success']:
return proxy_result
# 中央サーバーへの登録
registration_result = self.register_proxy_to_server(site)
if not registration_result['success']:
return registration_result
# 監視対象の自動発見・登録
discovery_result = self.setup_site_monitoring(site)
return {
'site': site['name'],
'success': True,
'vm_ip': site['proxy_ip'],
'discovered_hosts': discovery_result.get('host_count', 0),
'configuration': site
}
def create_vmware_vm(self, site: Dict) -> Dict:
"""VMware環境でのVM作成"""
vmware_config = site['vmware']
# vSphere API呼び出し(pyvmomiライブラリ使用想定)
vm_spec = {
'name': f"zabbix-proxy-{site['name']}",
'cpu_cores': site['resources']['cpu'],
'memory_gb': site['resources']['memory'],
'disk_gb': site['resources']['storage'],
'network': site['network']['vlan'],
'template': 'Ubuntu-22.04-Template'
}
# 実際のVM作成処理(簡略化)
print(f"Creating VM: {vm_spec['name']}")
# IP設定
network_config = {
'ip': site['proxy_ip'],
'subnet': site['network']['subnet'],
'gateway': site['network']['gateway'],
'dns': site['network']['dns']
}
return {
'success': True,
'vm_name': vm_spec['name'],
'ip_address': network_config['ip']
}
def configure_proxy_os(self, site: Dict) -> Dict:
"""プロキシOS設定"""
proxy_ip = site['proxy_ip']
# SSH経由でのOS設定(Ansible等のツール想定)
os_config_script = f"""
# システム更新
apt update && apt upgrade -y
# 必要パッケージインストール
apt install -y curl wget gnupg2 software-properties-common
# Zabbixリポジトリ追加
wget https://repo.zabbix.com/zabbix/6.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_6.0-4+ubuntu22.04_all.deb
dpkg -i zabbix-release_6.0-4+ubuntu22.04_all.deb
apt update
# Zabbixプロキシインストール
apt install -y zabbix-proxy-sqlite3 zabbix-get
# ファイアウォール設定
ufw allow 10051/tcp
ufw allow ssh
ufw --force enable
# NTP設定
timedatectl set-timezone {site.get('timezone', 'Asia/Tokyo')}
"""
# SSH実行(実際の実装では適切な認証・実行機構を使用)
print(f"Configuring OS for proxy at {proxy_ip}")
return {'success': True, 'message': 'OS configuration completed'}
def install_zabbix_proxy(self, site: Dict) -> Dict:
"""Zabbixプロキシインストール・設定"""
proxy_config = f"""
# Zabbix Proxy Configuration for {site['name']}
Server={self.config['zabbix']['server_ip']}
ServerPort=10051
Hostname={site['name']}-proxy
ListenPort=10051
SourceIP={site['proxy_ip']}
# Database
DBName=/var/lib/zabbix/zabbix_proxy.db
# Performance
StartPollers={site['performance']['pollers']}
StartPingers={site['performance']['pingers']}
StartPollersUnreachable={site['performance']['unreachable_pollers']}
StartTrappers={site['performance']['trappers']}
StartDiscoverers={site['performance']['discoverers']}
# Cache
ConfigFrequency=3600
DataSenderFrequency=1
CacheSize={site['performance']['cache_size']}
# Logging
LogFile=/var/log/zabbix/zabbix_proxy.log
LogFileSize=100
DebugLevel=3
# Network
Timeout=30
TrapperTimeout=300
# Location specific settings
"""
# 設定ファイル配置・サービス起動
print(f"Installing Zabbix proxy for site: {site['name']}")
return {
'success': True,
'proxy_hostname': f"{site['name']}-proxy",
'config_file': '/etc/zabbix/zabbix_proxy.conf'
}
def register_proxy_to_server(self, site: Dict) -> Dict:
"""中央サーバーへのプロキシ登録"""
# Zabbix API経由でのプロキシ登録
proxy_data = {
"jsonrpc": "2.0",
"method": "proxy.create",
"params": {
"host": f"{site['name']}-proxy",
"status": 5, # Active proxy
"description": f"Proxy server for {site['name']} site",
"proxy_address": site['proxy_ip'],
"tls_connect": 1, # No encryption (can be changed to 2 for PSK)
"tls_accept": 1
},
"auth": self.api_token,
"id": 1
}
try:
response = requests.post(self.zabbix_api_url, json=proxy_data)
result = response.json()
if 'result' in result:
return {
'success': True,
'proxy_id': result['result']['proxyids'][0],
'proxy_name': f"{site['name']}-proxy"
}
else:
return {
'success': False,
'error': result.get('error', 'Unknown API error')
}
except Exception as e:
return {
'success': False,
'error': f"API call failed: {str(e)}"
}
def setup_site_monitoring(self, site: Dict) -> Dict:
"""拠点監視設定"""
# ネットワーク自動探索設定
discovery_rules = []
for network in site['networks']:
rule = {
"name": f"Network discovery for {network['name']}",
"iprange": network['range'],
"delay": "3600s",
"checks": "19,21,22,23,25,53,80,110,143,443,993,995,1723,3389,5432,3306,10050,10051",
"status": 0, # Enabled
"proxy_hostid": site.get('proxy_id') # 作成されたプロキシIDを使用
}
discovery_rules.append(rule)
# ホストグループ作成
hostgroup_data = {
"jsonrpc": "2.0",
"method": "hostgroup.create",
"params": {
"name": f"Site-{site['name']}"
},
"auth": self.api_token,
"id": 2
}
try:
response = requests.post(self.zabbix_api_url, json=hostgroup_data)
hostgroup_result = response.json()
# 探索ルール作成
for rule in discovery_rules:
drule_data = {
"jsonrpc": "2.0",
"method": "drule.create",
"params": rule,
"auth": self.api_token,
"id": 3
}
requests.post(self.zabbix_api_url, json=drule_data)
return {
'success': True,
'hostgroup_id': hostgroup_result['result']['groupids'][0],
'discovery_rules': len(discovery_rules)
}
except Exception as e:
return {
'success': False,
'error': f"Site monitoring setup failed: {str(e)}"
}
def generate_deployment_report(self, results: Dict) -> str:
"""配置レポート生成"""
report = f"""
# Zabbix Proxy Deployment Report
**Deployment Date**: {datetime.now().isoformat()}
**Total Sites**: {results['total_sites']}
**Successful Deployments**: {len(results['successful_deployments'])}
**Failed Deployments**: {len(results['failed_deployments'])}
## Successful Deployments
"""
for deployment in results['successful_deployments']:
report += f"""
### {deployment['site']}
- **Proxy IP**: {deployment['vm_ip']}
- **Discovered Hosts**: {deployment['discovered_hosts']}
- **Status**: ✅ SUCCESS
"""
if results['failed_deployments']:
report += "\n## Failed Deployments\n\n"
for failure in results['failed_deployments']:
report += f"""
### {failure['site']}
- **Status**: ❌ FAILED
- **Error**: {failure['error']}
"""
report += """
## Next Steps
1. Verify proxy connectivity from central server
2. Test monitoring data collection
3. Configure site-specific templates
4. Set up escalation rules
5. Train local site administrators
## Monitoring Dashboard
Access the central monitoring dashboard to view:
- Proxy status and performance
- Site-specific monitoring data
- Cross-site correlation analysis
- Capacity utilization trends
"""
return report
# 設定ファイル例
def create_sample_config():
config = {
'zabbix': {
'server_ip': '10.1.1.10',
'api_url': 'http://10.1.1.10/zabbix/api_jsonrpc.php',
'api_token': 'your_api_token_here'
},
'sites': [
{
'name': 'tokyo',
'proxy_ip': '10.2.1.10',
'timezone': 'Asia/Tokyo',
'resources': {
'cpu': 8,
'memory': 16,
'storage': 500
},
'performance': {
'pollers': 10,
'pingers': 3,
'unreachable_pollers': 2,
'trappers': 5,
'discoverers': 2,
'cache_size': '128M'
},
'network': {
'vlan': 'VLAN-200',
'subnet': '10.2.1.0/24',
'gateway': '10.2.1.1',
'dns': ['10.2.1.2', '8.8.8.8']
},
'networks': [
{
'name': 'Server Network',
'range': '10.2.10.1-254'
},
{
'name': 'Client Network',
'range': '10.2.20.1-254'
}
],
'vmware': {
'vcenter': '10.2.1.5',
'datacenter': 'Tokyo-DC',
'cluster': 'Production'
}
},
{
'name': 'osaka',
'proxy_ip': '10.3.1.10',
'timezone': 'Asia/Tokyo',
'resources': {
'cpu': 6,
'memory': 12,
'storage': 300
},
'performance': {
'pollers': 8,
'pingers': 2,
'unreachable_pollers': 1,
'trappers': 3,
'discoverers': 1,
'cache_size': '64M'
},
'network': {
'vlan': 'VLAN-300',
'subnet': '10.3.1.0/24',
'gateway': '10.3.1.1',
'dns': ['10.3.1.2', '8.8.8.8']
},
'networks': [
{
'name': 'Server Network',
'range': '10.3.10.1-254'
}
]
}
]
}
with open('zabbix_proxy_deployment.yaml', 'w') as f:
yaml.dump(config, f, default_flow_style=False)
# 使用例
def main():
# 設定ファイル作成(初回のみ)
create_sample_config()
# 配置システム初期化
deployer = ZabbixProxyDeployment('zabbix_proxy_deployment.yaml')
# プロキシ配置実行
results = deployer.deploy_proxy_infrastructure()
# レポート生成
report = deployer.generate_deployment_report(results)
# ファイル出力
with open('deployment_report.md', 'w') as f:
f.write(report)
print("Deployment completed. Report saved to deployment_report.md")
print(f"Successful: {len(results['successful_deployments'])}/{results['total_sites']}")
if __name__ == "__main__":
main()
大規模企業(5000+台)
エンタープライズアーキテクチャ
yaml
# 大規模企業向けZabbixエンタープライズ設計
大規模企業要件:
環境特性:
- サーバー数: 5000+台
- 拠点数: 50+箇所
- 運用人員: 50+名
- 可用性要件: 99.9%以上
- コンプライアンス: SOX, GDPR, HIPAA
アーキテクチャ原則:
- 完全冗長化
- 地理的分散
- 自動スケーリング
- 階層化監視
- 統合セキュリティ
# 階層化監視設計
階層化監視:
Tier 1 - Global:
役割: "全社統合監視・レポート"
構成:
- グローバル監視センター
- エグゼクティブダッシュボード
- 統合レポート・分析
- 災害対策統制
技術仕様:
- Zabbixサーバークラスター (5ノード)
- 分散データベース (Galera Cluster)
- ロードバランサー (HAProxy + Keepalived)
- キャッシュレイヤー (Redis Cluster)
Tier 2 - Regional:
役割: "地域別監視・集約"
構成:
- 地域監視センター (6拠点)
- 地域プロキシクラスター
- 地域データ集約
- ローカル障害対応
技術仕様:
- 地域別Zabbixプロキシクラスター
- 地域データベース
- VPN/専用線接続
- エッジコンピューティング対応
Tier 3 - Local:
役割: "拠点別監視・収集"
構成:
- 拠点プロキシ
- ローカルエージェント
- エッジデバイス監視
- 緊急時自律動作
クラウド環境統合
AWS環境での実装
CloudFormationテンプレート
yaml
# AWS環境向けZabbix CloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Enterprise Zabbix deployment on AWS'
Parameters:
VpcCidr:
Type: String
Default: '10.0.0.0/16'
Description: 'VPC CIDR block'
ZabbixInstanceType:
Type: String
Default: 'c5.2xlarge'
AllowedValues: ['c5.large', 'c5.xlarge', 'c5.2xlarge', 'c5.4xlarge']
Description: 'Zabbix server instance type'
DBInstanceClass:
Type: String
Default: 'db.r5.xlarge'
AllowedValues: ['db.r5.large', 'db.r5.xlarge', 'db.r5.2xlarge']
Description: 'RDS instance class'
Resources:
# VPC構成
ZabbixVPC:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: 'Zabbix-VPC'
# パブリックサブネット
PublicSubnet1:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref ZabbixVPC
CidrBlock: '10.0.1.0/24'
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: 'Zabbix-Public-1'
PublicSubnet2:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref ZabbixVPC
CidrBlock: '10.0.2.0/24'
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: 'Zabbix-Public-2'
# プライベートサブネット
PrivateSubnet1:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref ZabbixVPC
CidrBlock: '10.0.11.0/24'
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: 'Zabbix-Private-1'
PrivateSubnet2:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref ZabbixVPC
CidrBlock: '10.0.12.0/24'
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: 'Zabbix-Private-2'
# インターネットゲートウェイ
InternetGateway:
Type: 'AWS::EC2::InternetGateway'
Properties:
Tags:
- Key: Name
Value: 'Zabbix-IGW'
AttachGateway:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId: !Ref ZabbixVPC
InternetGatewayId: !Ref InternetGateway
# Application Load Balancer
ZabbixALB:
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
Properties:
Name: 'Zabbix-ALB'
Type: application
Scheme: internet-facing
IpAddressType: ipv4
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref ALBSecurityGroup
Tags:
- Key: Name
Value: 'Zabbix-ALB'
# セキュリティグループ
ZabbixSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: 'Security group for Zabbix servers'
VpcId: !Ref ZabbixVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 10051
ToPort: 10051
CidrIp: '10.0.0.0/8'
Description: 'Zabbix server port'
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref ALBSecurityGroup
Description: 'HTTP from ALB'
- IpProtocol: tcp
FromPort: 443
ToPort: 443
SourceSecurityGroupId: !Ref ALBSecurityGroup
Description: 'HTTPS from ALB'
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: '10.0.0.0/16'
Description: 'SSH access'
Tags:
- Key: Name
Value: 'Zabbix-SG'
ALBSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: 'Security group for Zabbix ALB'
VpcId: !Ref ZabbixVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: '0.0.0.0/0'
Description: 'HTTP access'
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: '0.0.0.0/0'
Description: 'HTTPS access'
Tags:
- Key: Name
Value: 'Zabbix-ALB-SG'
# RDSサブネットグループ
DBSubnetGroup:
Type: 'AWS::RDS::DBSubnetGroup'
Properties:
DBSubnetGroupDescription: 'Subnet group for Zabbix RDS'
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Tags:
- Key: Name
Value: 'Zabbix-DB-SubnetGroup'
# RDSデータベース
ZabbixDatabase:
Type: 'AWS::RDS::DBInstance'
Properties:
DBInstanceIdentifier: 'zabbix-database'
DBInstanceClass: !Ref DBInstanceClass
Engine: mysql
EngineVersion: '8.0'
AllocatedStorage: 200
StorageType: gp2
StorageEncrypted: true
MultiAZ: true
DBName: zabbix
MasterUsername: zabbixuser
MasterUserPassword: !Ref DBPassword
VPCSecurityGroups:
- !Ref DatabaseSecurityGroup
DBSubnetGroupName: !Ref DBSubnetGroup
BackupRetentionPeriod: 30
PreferredBackupWindow: '03:00-04:00'
PreferredMaintenanceWindow: 'sun:04:00-sun:05:00'
DeletionProtection: true
Tags:
- Key: Name
Value: 'Zabbix-Database'
DatabaseSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: 'Security group for Zabbix database'
VpcId: !Ref ZabbixVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref ZabbixSecurityGroup
Description: 'MySQL access from Zabbix servers'
Tags:
- Key: Name
Value: 'Zabbix-DB-SG'
# Auto Scaling Group用のLaunch Template
ZabbixLaunchTemplate:
Type: 'AWS::EC2::LaunchTemplate'
Properties:
LaunchTemplateName: 'Zabbix-LaunchTemplate'
LaunchTemplateData:
ImageId: 'ami-0c02fb55956c7d316' # Amazon Linux 2
InstanceType: !Ref ZabbixInstanceType
SecurityGroupIds:
- !Ref ZabbixSecurityGroup
IamInstanceProfile:
Arn: !GetAtt ZabbixInstanceProfile.Arn
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
# Zabbixリポジトリ追加
rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/8/x86_64/zabbix-release-6.0-4.el8.noarch.rpm
# Zabbixサーバーインストール
yum install -y zabbix-server-mysql zabbix-web-mysql zabbix-nginx-conf zabbix-sql-scripts zabbix-selinux-policy zabbix-agent
# MySQL初期設定
mysql -h ${ZabbixDatabase.Endpoint.Address} -u zabbixuser -p${DBPassword} zabbix < /usr/share/doc/zabbix-sql-scripts/mysql/server.sql.gz
# Zabbix設定
cat > /etc/zabbix/zabbix_server.conf << EOF
LogFile=/var/log/zabbix/zabbix_server.log
DBHost=${ZabbixDatabase.Endpoint.Address}
DBName=zabbix
DBUser=zabbixuser
DBPassword=${DBPassword}
StartPollers=30
StartPingers=10
StartPollersUnreachable=5
StartTrappers=10
StartTimers=2
StartEscalators=2
StartAlerters=5
StartDiscoverers=5
StartHTTPPollers=5
CacheSize=256M
ValueCacheSize=512M
TrendCacheSize=128M
HistoryCacheSize=256M
HistoryIndexCacheSize=128M
EOF
# サービス起動
systemctl restart zabbix-server zabbix-agent nginx php-fpm
systemctl enable zabbix-server zabbix-agent nginx php-fpm
# CloudWatch Agentインストール・設定
wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
rpm -U ./amazon-cloudwatch-agent.rpm
# Zabbixメトリクスの CloudWatch 送信設定
cat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << EOF
{
"metrics": {
"namespace": "Zabbix/Monitoring",
"metrics_collected": {
"cpu": {"measurement": ["cpu_usage_idle", "cpu_usage_iowait", "cpu_usage_user", "cpu_usage_system"]},
"disk": {"measurement": ["used_percent"], "metrics_collection_interval": 60, "resources": ["*"]},
"mem": {"measurement": ["mem_used_percent"]},
"netstat": {"measurement": ["tcp_established", "tcp_time_wait"]}
}
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/zabbix/zabbix_server.log",
"log_group_name": "/aws/ec2/zabbix-server",
"log_stream_name": "{instance_id}/zabbix-server.log"
}
]
}
}
}
}
EOF
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s
# IAMロール
ZabbixRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy'
- 'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess'
Policies:
- PolicyName: 'ZabbixCloudWatchPolicy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'cloudwatch:PutMetricData'
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'logs:DescribeLogStreams'
Resource: '*'
ZabbixInstanceProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
- !Ref ZabbixRole
# Auto Scaling Group
ZabbixAutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
AutoScalingGroupName: 'Zabbix-ASG'
LaunchTemplate:
LaunchTemplateId: !Ref ZabbixLaunchTemplate
Version: !GetAtt ZabbixLaunchTemplate.LatestVersionNumber
MinSize: 2
MaxSize: 6
DesiredCapacity: 2
VPCZoneIdentifier:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
TargetGroupARNs:
- !Ref ZabbixTargetGroup
HealthCheckType: ELB
HealthCheckGracePeriod: 300
Tags:
- Key: Name
Value: 'Zabbix-Server'
PropagateAtLaunch: true
# Target Group
ZabbixTargetGroup:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
Name: 'Zabbix-TG'
Port: 80
Protocol: HTTP
VpcId: !Ref ZabbixVPC
HealthCheckPath: '/zabbix/'
HealthCheckProtocol: HTTP
HealthCheckIntervalSeconds: 30
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
TargetType: instance
Tags:
- Key: Name
Value: 'Zabbix-TargetGroup'
# ALB Listener
ZabbixListener:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ZabbixTargetGroup
LoadBalancerArn: !Ref ZabbixALB
Port: 80
Protocol: HTTP
Parameters:
DBPassword:
Type: String
NoEcho: true
Description: 'Password for Zabbix database'
MinLength: 8
MaxLength: 128
AllowedPattern: '[a-zA-Z0-9]*'
Outputs:
ZabbixURL:
Description: 'Zabbix Web Interface URL'
Value: !Sub 'http://${ZabbixALB.DNSName}/zabbix'
DatabaseEndpoint:
Description: 'RDS Database Endpoint'
Value: !GetAtt ZabbixDatabase.Endpoint.Address
VPCId:
Description: 'VPC ID'
Value: !Ref ZabbixVPC
Export:
Name: !Sub '${AWS::StackName}-VPC-ID'
Azure環境での実装
ARM テンプレート
json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources"
}
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_D4s_v3",
"allowedValues": [
"Standard_D2s_v3",
"Standard_D4s_v3",
"Standard_D8s_v3"
],
"metadata": {
"description": "Size of the virtual machine"
}
},
"adminUsername": {
"type": "string",
"metadata": {
"description": "Admin username for the VM"
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Admin password for the VM"
}
},
"dbServerName": {
"type": "string",
"metadata": {
"description": "Database server name"
}
},
"dbAdminLogin": {
"type": "string",
"metadata": {
"description": "Database admin login"
}
},
"dbAdminPassword": {
"type": "securestring",
"metadata": {
"description": "Database admin password"
}
}
},
"variables": {
"vnetName": "zabbix-vnet",
"subnetName": "zabbix-subnet",
"publicIPName": "zabbix-public-ip",
"networkSecurityGroupName": "zabbix-nsg",
"storageAccountName": "[concat('zabbixstorage', uniqueString(resourceGroup().id))]",
"vmName": "zabbix-vm",
"nicName": "zabbix-nic",
"loadBalancerName": "zabbix-lb"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage"
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2021-02-01",
"name": "[variables('vnetName')]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/16"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "10.0.0.0/24",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
}
}
}
]
},
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
]
},
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2021-02-01",
"name": "[variables('networkSecurityGroupName')]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "SSH",
"properties": {
"priority": 1001,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "22"
}
},
{
"name": "HTTP",
"properties": {
"priority": 1002,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "80"
}
},
{
"name": "HTTPS",
"properties": {
"priority": 1003,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "443"
}
},
{
"name": "Zabbix-Server",
"properties": {
"priority": 1004,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "10.0.0.0/16",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "10051"
}
},
{
"name": "Zabbix-Agent",
"properties": {
"priority": 1005,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "10.0.0.0/16",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "10050"
}
}
]
}
},
{
"type": "Microsoft.DBforMySQL/servers",
"apiVersion": "2017-12-01",
"name": "[parameters('dbServerName')]",
"location": "[parameters('location')]",
"sku": {
"name": "GP_Gen5_2",
"tier": "GeneralPurpose",
"family": "Gen5",
"capacity": 2
},
"properties": {
"administratorLogin": "[parameters('dbAdminLogin')]",
"administratorLoginPassword": "[parameters('dbAdminPassword')]",
"version": "8.0",
"sslEnforcement": "Enabled",
"storageProfile": {
"storageMB": 102400,
"backupRetentionDays": 30,
"geoRedundantBackup": "Enabled",
"storageAutoGrow": "Enabled"
}
}
},
{
"type": "Microsoft.DBforMySQL/servers/databases",
"apiVersion": "2017-12-01",
"name": "[concat(parameters('dbServerName'), '/zabbix')]",
"dependsOn": [
"[resourceId('Microsoft.DBforMySQL/servers', parameters('dbServerName'))]"
],
"properties": {
"charset": "utf8",
"collation": "utf8_bin"
}
},
{
"type": "Microsoft.DBforMySQL/servers/firewallRules",
"apiVersion": "2017-12-01",
"name": "[concat(parameters('dbServerName'), '/AllowAzureServices')]",
"dependsOn": [
"[resourceId('Microsoft.DBforMySQL/servers', parameters('dbServerName'))]"
],
"properties": {
"startIpAddress": "0.0.0.0",
"endIpAddress": "0.0.0.0"
}
},
{
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2021-02-01",
"name": "[variables('publicIPName')]",
"location": "[parameters('location')]",
"properties": {
"publicIPAllocationMethod": "Static",
"dnsSettings": {
"domainNameLabel": "[concat('zabbix-', uniqueString(resourceGroup().id))]"
}
}
},
{
"type": "Microsoft.Network/loadBalancers",
"apiVersion": "2021-02-01",
"name": "[variables('loadBalancerName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPName'))]"
],
"properties": {
"frontendIPConfigurations": [
{
"name": "LoadBalancerFrontEnd",
"properties": {
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPName'))]"
}
}
}
],
"backendAddressPools": [
{
"name": "BackendPool1"
}
],
"loadBalancingRules": [
{
"name": "LBRule-HTTP",
"properties": {
"frontendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), 'LoadBalancerFrontEnd')]"
},
"backendAddressPool": {
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), 'BackendPool1')]"
},
"probe": {
"id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), 'HTTPProbe')]"
},
"protocol": "TCP",
"frontendPort": 80,
"backendPort": 80,
"idleTimeoutInMinutes": 15
}
}
],
"probes": [
{
"name": "HTTPProbe",
"properties": {
"protocol": "HTTP",
"port": 80,
"requestPath": "/zabbix/",
"intervalInSeconds": 15,
"numberOfProbes": 2
}
}
]
}
}
],
"outputs": {
"zabbixURL": {
"type": "string",
"value": "[concat('http://', reference(variables('publicIPName')).dnsSettings.fqdn, '/zabbix')]"
},
"databaseServer": {
"type": "string",
"value": "[reference(parameters('dbServerName')).fullyQualifiedDomainName]"
}
}
}
DevOps統合
CI/CD パイプライン統合
GitLab CI/CD統合
yaml
# .gitlab-ci.yml - Zabbix統合CI/CDパイプライン
stages:
- build
- test
- deploy
- monitor
variables:
ZABBIX_API_URL: "https://monitoring.company.com/zabbix/api_jsonrpc.php"
ZABBIX_API_TOKEN: "$ZABBIX_API_TOKEN"
APP_NAME: "my-application"
before_script:
- 'command -v curl >/dev/null 2>&1 || { echo "curl is required but not installed. Aborting." >&2; exit 1; }'
# ビルドステージ
build:
stage: build
image: node:18-alpine
script:
- npm ci
- npm run build
- echo "BUILD_ID=$CI_PIPELINE_ID" > build.env
artifacts:
paths:
- dist/
- build.env
reports:
dotenv: build.env
only:
- main
- develop
# テストステージ
test:
stage: test
image: node:18-alpine
script:
- npm ci
- npm run test:coverage
coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
only:
- main
- develop
# Zabbix監視設定更新
update_zabbix_monitoring:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache curl jq
script:
- |
# アプリケーション情報をZabbixに送信
curl -X POST \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"item.update\",
\"params\": {
\"itemid\": \"$ZABBIX_APP_VERSION_ITEM_ID\",
\"lastvalue\": \"$CI_COMMIT_SHA\",
\"lastclock\": \"$(date +%s)\"
},
\"auth\": \"$ZABBIX_API_TOKEN\",
\"id\": 1
}" \
"$ZABBIX_API_URL"
# デプロイメントイベント送信
curl -X POST \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"history.push\",
\"params\": [
{
\"host\": \"$APP_NAME\",
\"key\": \"deployment.event\",
\"value\": \"Deployed version $CI_COMMIT_SHORT_SHA by $GITLAB_USER_NAME\",
\"clock\": \"$(date +%s)\"
}
],
\"auth\": \"$ZABBIX_API_TOKEN\",
\"id\": 2
}" \
"$ZABBIX_API_URL"
only:
- main
# デプロイメント後監視
post_deployment_monitoring:
stage: monitor
image: alpine:latest
before_script:
- apk add --no-cache curl jq
script:
- |
echo "Starting post-deployment monitoring for $APP_NAME"
# デプロイメント後の健全性チェック
HEALTH_CHECK_URL="https://$APP_NAME.company.com/health"
# 5分間のヘルスチェック
for i in {1..10}; do
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_CHECK_URL")
if [ "$RESPONSE" = "200" ]; then
echo "Health check $i/10: PASSED"
# Zabbixにヘルスチェック結果送信
curl -X POST \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"history.push\",
\"params\": [
{
\"host\": \"$APP_NAME\",
\"key\": \"app.health.check\",
\"value\": \"1\",
\"clock\": \"$(date +%s)\"
}
],
\"auth\": \"$ZABBIX_API_TOKEN\",
\"id\": 3
}" \
"$ZABBIX_API_URL"
else
echo "Health check $i/10: FAILED (HTTP $RESPONSE)"
# Zabbixに失敗を通知
curl -X POST \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"history.push\",
\"params\": [
{
\"host\": \"$APP_NAME\",
\"key\": \"app.health.check\",
\"value\": \"0\",
\"clock\": \"$(date +%s)\"
}
],
\"auth\": \"$ZABBIX_API_TOKEN\",
\"id\": 4
}" \
"$ZABBIX_API_URL"
exit 1
fi
sleep 30
done
echo "Post-deployment monitoring completed successfully"
only:
- main
when: on_success
# Zabbixアラート統合
zabbix_integration:
stage: monitor
image: alpine:latest
before_script:
- apk add --no-cache curl jq
script:
- |
# CI/CDメトリクスをZabbixに送信
BUILD_DURATION=$((CI_JOB_STARTED_AT - CI_PIPELINE_CREATED_AT))
TEST_RESULT=$([ "$CI_JOB_STATUS" = "success" ] && echo "1" || echo "0")
# ビルド時間メトリクス
curl -X POST \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"history.push\",
\"params\": [
{
\"host\": \"cicd-metrics\",
\"key\": \"build.duration[$APP_NAME]\",
\"value\": \"$BUILD_DURATION\",
\"clock\": \"$(date +%s)\"
},
{
\"host\": \"cicd-metrics\",
\"key\": \"test.result[$APP_NAME]\",
\"value\": \"$TEST_RESULT\",
\"clock\": \"$(date +%s)\"
},
{
\"host\": \"cicd-metrics\",
\"key\": \"deployment.count[$APP_NAME]\",
\"value\": \"1\",
\"clock\": \"$(date +%s)\"
}
],
\"auth\": \"$ZABBIX_API_TOKEN\",
\"id\": 5
}" \
"$ZABBIX_API_URL"
when: always
allow_failure: true
# パフォーマンステスト統合
performance_test:
stage: test
image: loadimpact/k6:latest
script:
- |
cat > performance_test.js << EOF
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [
{ duration: '1m', target: 10 },
{ duration: '3m', target: 50 },
{ duration: '1m', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<500'],
http_req_failed: ['rate<0.1'],
},
};
export default function() {
let response = http.get('https://$APP_NAME.company.com/api/health');
check(response, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}
export function handleSummary(data) {
// K6結果をZabbixに送信するカスタム関数
const metrics = {
avg_response_time: data.metrics.http_req_duration.values.avg,
p95_response_time: data.metrics.http_req_duration.values['p(95)'],
error_rate: data.metrics.http_req_failed.values.rate,
total_requests: data.metrics.http_reqs.values.count
};
// Zabbixへの送信処理(実際の実装では外部スクリプト使用)
console.log('Performance metrics:', JSON.stringify(metrics));
return {
'performance_results.json': JSON.stringify(metrics, null, 2),
};
}
EOF
- k6 run performance_test.js
artifacts:
paths:
- performance_results.json
only:
- main
コンテナ監視
Kubernetes統合監視
Helm Chart for Zabbix
yaml
# values.yaml - Zabbix Kubernetes Helm Chart
global:
imageRegistry: ""
imagePullSecrets: []
zabbixServer:
enabled: true
image:
repository: zabbix/zabbix-server-mysql
tag: "6.0-alpine-latest"
pullPolicy: IfNotPresent
replicaCount: 2
service:
type: ClusterIP
port: 10051
resources:
limits:
cpu: 2
memory: 4Gi
requests:
cpu: 1
memory: 2Gi
persistence:
enabled: true
storageClass: "fast-ssd"
size: 10Gi
config:
DB_SERVER_HOST: "zabbix-mysql"
DB_SERVER_PORT: "3306"
MYSQL_DATABASE: "zabbix"
MYSQL_USER: "zabbix"
MYSQL_PASSWORD: "zabbix_password"
# Performance tuning
StartPollers: "30"
StartPingers: "10"
StartPollersUnreachable: "5"
StartTrappers: "10"
StartTimers: "2"
StartEscalators: "2"
StartAlerters: "5"
StartDiscoverers: "5"
StartHTTPPollers: "5"
CacheSize: "256M"
ValueCacheSize: "512M"
TrendCacheSize: "128M"
HistoryCacheSize: "256M"
zabbixWeb:
enabled: true
image:
repository: zabbix/zabbix-web-nginx-mysql
tag: "6.0-alpine-latest"
pullPolicy: IfNotPresent
replicaCount: 3
service:
type: LoadBalancer
port: 80
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
resources:
limits:
cpu: 1
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
ingress:
enabled: true
className: "nginx"
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: zabbix.company.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: zabbix-tls
hosts:
- zabbix.company.com
mysql:
enabled: true
auth:
rootPassword: "mysql_root_password"
database: "zabbix"
username: "zabbix"
password: "zabbix_password"
primary:
persistence:
enabled: true
storageClass: "fast-ssd"
size: 100Gi
resources:
limits:
cpu: 2
memory: 4Gi
requests:
cpu: 1
memory: 2Gi
configuration: |-
[mysqld]
innodb_buffer_pool_size=2G
innodb_log_file_size=256M
innodb_log_buffer_size=8M
max_connections=300
query_cache_size=64M
tmp_table_size=64M
max_heap_table_size=64M
innodb_file_per_table=1
metrics:
enabled: true
serviceMonitor:
enabled: true
# Kubernetes monitoring components
kubernetesMonitoring:
enabled: true
# Node monitoring via DaemonSet
nodeAgent:
enabled: true
image:
repository: zabbix/zabbix-agent2
tag: "6.0-alpine-latest"
hostNetwork: true
hostPID: true
config:
Server: "zabbix-server"
ServerActive: "zabbix-server:10051"
Hostname: "" # Use node name
# Kubernetes specific plugins
Plugins.Kubernetes.System.Path: "/hostfs"
Plugins.Docker.Endpoint: "unix:///var/run/docker.sock"
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name: dev
hostPath:
path: /dev
- name: docker-sock
hostPath:
path: /var/run/docker.sock
- name: hostfs
hostPath:
path: /
volumeMounts:
- name: proc
mountPath: /hostfs/proc
readOnly: true
- name: sys
mountPath: /hostfs/sys
readOnly: true
- name: dev
mountPath: /hostfs/dev
readOnly: true
- name: docker-sock
mountPath: /var/run/docker.sock
readOnly: true
- name: hostfs
mountPath: /hostfs
readOnly: true
# API Server monitoring
apiServerMonitoring:
enabled: true
serviceAccount:
create: true
name: "zabbix-k8s-monitor"
clusterRole:
create: true
rules:
- apiGroups: [""]
resources: ["nodes", "pods", "services", "endpoints", "namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "daemonsets", "statefulsets"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
resources: ["nodes", "pods"]
verbs: ["get", "list"]
# Pod monitoring
podMonitoring:
enabled: true
annotations:
zabbix.monitor: "true"
# Custom discovery rules for pods
discoveryRules:
- name: "Kubernetes Pods Discovery"
key: "kubernetes.pods.discovery"
type: "script"
params: "kubectl get pods --all-namespaces -o json"
serviceMonitor:
enabled: true
namespace: monitoring
labels:
app: zabbix
interval: 30s
# Grafana integration
grafana:
enabled: true
datasources:
- name: Zabbix
type: alexanderzobnin-zabbix-datasource
url: http://zabbix-web/zabbix
access: proxy
basicAuth: false
jsonData:
username: "monitoring"
trends: true
trendsFrom: "7d"
trendsRange: "4h"
cacheTTL: "1h"
timeout: "30s"
dashboards:
enabled: true
provider:
name: "zabbix-dashboards"
folder: "/tmp/dashboards"
Kubernetes監視テンプレート
python
#!/usr/bin/env python3
"""Kubernetes Zabbix監視テンプレート自動生成"""
import json
import yaml
from kubernetes import client, config
from typing import Dict, List
class KubernetesZabbixTemplateGenerator:
def __init__(self, kubeconfig_path: str = None):
if kubeconfig_path:
config.load_kube_config(config_file=kubeconfig_path)
else:
config.load_incluster_config()
self.v1 = client.CoreV1Api()
self.apps_v1 = client.AppsV1Api()
self.metrics_v1 = client.CustomObjectsApi()
def discover_cluster_resources(self) -> Dict:
"""クラスターリソース発見"""
resources = {
'nodes': [],
'namespaces': [],
'deployments': [],
'services': [],
'pods': []
}
# ノード発見
nodes = self.v1.list_node()
for node in nodes.items:
resources['nodes'].append({
'name': node.metadata.name,
'labels': node.metadata.labels,
'capacity': node.status.capacity,
'conditions': [
{'type': condition.type, 'status': condition.status}
for condition in node.status.conditions
]
})
# 名前空間発見
namespaces = self.v1.list_namespace()
for ns in namespaces.items:
resources['namespaces'].append({
'name': ns.metadata.name,
'labels': ns.metadata.labels or {},
'phase': ns.status.phase
})
# デプロイメント発見
deployments = self.apps_v1.list_deployment_for_all_namespaces()
for deploy in deployments.items:
resources['deployments'].append({
'name': deploy.metadata.name,
'namespace': deploy.metadata.namespace,
'replicas': deploy.spec.replicas,
'ready_replicas': deploy.status.ready_replicas or 0,
'labels': deploy.metadata.labels or {}
})
return resources
def generate_node_template(self) -> Dict:
"""Kubernetesノード監視テンプレート"""
template = {
"zabbix_export": {
"version": "6.0",
"templates": [{
"template": "Template Kubernetes Node",
"name": "Template Kubernetes Node",
"description": "Kubernetes Node monitoring template",
"groups": [{"name": "Templates/Containers"}],
"items": [
{
"name": "Node CPU Usage",
"type": "HTTP_AGENT",
"key": "k8s.node.cpu.usage[{$K8S.NODE.NAME}]",
"delay": "60s",
"value_type": "FLOAT",
"units": "%",
"url": "http://kubernetes.default.svc.cluster.local/api/v1/nodes/{$K8S.NODE.NAME}/proxy/stats/summary",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.node.cpu.usageNanoCores"
},
{
"type": "JAVASCRIPT",
"params": "return value / 1000000000 * 100 / {$K8S.NODE.CPU.CAPACITY};"
}
],
"applications": [{"name": "Kubernetes Node"}]
},
{
"name": "Node Memory Usage",
"type": "HTTP_AGENT",
"key": "k8s.node.memory.usage[{$K8S.NODE.NAME}]",
"delay": "60s",
"value_type": "FLOAT",
"units": "%",
"url": "http://kubernetes.default.svc.cluster.local/api/v1/nodes/{$K8S.NODE.NAME}/proxy/stats/summary",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.node.memory.usageBytes"
},
{
"type": "JAVASCRIPT",
"params": "return value * 100 / {$K8S.NODE.MEMORY.CAPACITY};"
}
],
"applications": [{"name": "Kubernetes Node"}]
},
{
"name": "Node Pods Count",
"type": "HTTP_AGENT",
"key": "k8s.node.pods.count[{$K8S.NODE.NAME}]",
"delay": "300s",
"value_type": "UNSIGNED",
"url": "http://kubernetes.default.svc.cluster.local/api/v1/pods",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"query_fields": [
{"name": "fieldSelector", "value": "spec.nodeName={$K8S.NODE.NAME}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.items.length()"
}
],
"applications": [{"name": "Kubernetes Node"}]
}
],
"triggers": [
{
"expression": "{Template Kubernetes Node:k8s.node.cpu.usage[{$K8S.NODE.NAME}].avg(5m)}>85",
"name": "High CPU usage on node {$K8S.NODE.NAME}",
"priority": "WARNING",
"description": "CPU usage is over 85% for 5 minutes"
},
{
"expression": "{Template Kubernetes Node:k8s.node.memory.usage[{$K8S.NODE.NAME}].avg(5m)}>90",
"name": "High memory usage on node {$K8S.NODE.NAME}",
"priority": "HIGH",
"description": "Memory usage is over 90% for 5 minutes"
}
],
"macros": [
{"macro": "{$K8S.NODE.NAME}", "value": ""},
{"macro": "{$K8S.API.TOKEN}", "value": ""},
{"macro": "{$K8S.NODE.CPU.CAPACITY}", "value": "1000"},
{"macro": "{$K8S.NODE.MEMORY.CAPACITY}", "value": "1073741824"}
]
}]
}
}
return template
def generate_pod_template(self) -> Dict:
"""Kubernetesポッド監視テンプレート"""
template = {
"zabbix_export": {
"version": "6.0",
"templates": [{
"template": "Template Kubernetes Pod",
"name": "Template Kubernetes Pod",
"description": "Kubernetes Pod monitoring template",
"groups": [{"name": "Templates/Containers"}],
"discovery_rules": [
{
"name": "Container Discovery",
"type": "HTTP_AGENT",
"key": "k8s.pod.containers.discovery[{$K8S.POD.NAME},{$K8S.NAMESPACE}]",
"delay": "300s",
"url": "http://kubernetes.default.svc.cluster.local/api/v1/namespaces/{$K8S.NAMESPACE}/pods/{$K8S.POD.NAME}",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.spec.containers"
},
{
"type": "JAVASCRIPT",
"params": """
var containers = JSON.parse(value);
var result = [];
containers.forEach(function(container) {
result.push({
"{#CONTAINER.NAME}": container.name,
"{#CONTAINER.IMAGE}": container.image
});
});
return JSON.stringify({"data": result});
"""
}
],
"item_prototypes": [
{
"name": "Container {#CONTAINER.NAME} CPU Usage",
"type": "HTTP_AGENT",
"key": "k8s.container.cpu.usage[{$K8S.POD.NAME},{$K8S.NAMESPACE},{#CONTAINER.NAME}]",
"delay": "60s",
"value_type": "FLOAT",
"units": "cores",
"url": "http://kubernetes.default.svc.cluster.local/api/v1/namespaces/{$K8S.NAMESPACE}/pods/{$K8S.POD.NAME}/proxy/stats/summary",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.pods[0].containers[?(@.name=='{#CONTAINER.NAME}')].cpu.usageNanoCores"
},
{
"type": "JAVASCRIPT",
"params": "return value / 1000000000;"
}
],
"applications": [{"name": "Kubernetes Containers"}]
},
{
"name": "Container {#CONTAINER.NAME} Memory Usage",
"type": "HTTP_AGENT",
"key": "k8s.container.memory.usage[{$K8S.POD.NAME},{$K8S.NAMESPACE},{#CONTAINER.NAME}]",
"delay": "60s",
"value_type": "UNSIGNED",
"units": "B",
"url": "http://kubernetes.default.svc.cluster.local/api/v1/namespaces/{$K8S.NAMESPACE}/pods/{$K8S.POD.NAME}/proxy/stats/summary",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.pods[0].containers[?(@.name=='{#CONTAINER.NAME}')].memory.usageBytes"
}
],
"applications": [{"name": "Kubernetes Containers"}]
}
],
"trigger_prototypes": [
{
"expression": "{Template Kubernetes Pod:k8s.container.cpu.usage[{$K8S.POD.NAME},{$K8S.NAMESPACE},{#CONTAINER.NAME}].avg(5m)}>2",
"name": "High CPU usage in container {#CONTAINER.NAME}",
"priority": "WARNING",
"description": "Container CPU usage is over 2 cores for 5 minutes"
}
]
}
],
"macros": [
{"macro": "{$K8S.POD.NAME}", "value": ""},
{"macro": "{$K8S.NAMESPACE}", "value": "default"},
{"macro": "{$K8S.API.TOKEN}", "value": ""}
]
}]
}
}
return template
def generate_deployment_template(self) -> Dict:
"""Kubernetesデプロイメント監視テンプレート"""
template = {
"zabbix_export": {
"version": "6.0",
"templates": [{
"template": "Template Kubernetes Deployment",
"name": "Template Kubernetes Deployment",
"description": "Kubernetes Deployment monitoring template",
"groups": [{"name": "Templates/Containers"}],
"items": [
{
"name": "Deployment Replicas Desired",
"type": "HTTP_AGENT",
"key": "k8s.deployment.replicas.desired[{$K8S.DEPLOYMENT.NAME},{$K8S.NAMESPACE}]",
"delay": "60s",
"value_type": "UNSIGNED",
"url": "http://kubernetes.default.svc.cluster.local/apis/apps/v1/namespaces/{$K8S.NAMESPACE}/deployments/{$K8S.DEPLOYMENT.NAME}",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.spec.replicas"
}
],
"applications": [{"name": "Kubernetes Deployment"}]
},
{
"name": "Deployment Replicas Ready",
"type": "HTTP_AGENT",
"key": "k8s.deployment.replicas.ready[{$K8S.DEPLOYMENT.NAME},{$K8S.NAMESPACE}]",
"delay": "60s",
"value_type": "UNSIGNED",
"url": "http://kubernetes.default.svc.cluster.local/apis/apps/v1/namespaces/{$K8S.NAMESPACE}/deployments/{$K8S.DEPLOYMENT.NAME}",
"headers": [
{"name": "Authorization", "value": "Bearer {$K8S.API.TOKEN}"}
],
"preprocessing": [
{
"type": "JSONPATH",
"params": "$.status.readyReplicas"
}
],
"applications": [{"name": "Kubernetes Deployment"}]
}
],
"triggers": [
{
"expression": "{Template Kubernetes Deployment:k8s.deployment.replicas.ready[{$K8S.DEPLOYMENT.NAME},{$K8S.NAMESPACE}].last()}<{Template Kubernetes Deployment:k8s.deployment.replicas.desired[{$K8S.DEPLOYMENT.NAME},{$K8S.NAMESPACE}].last()}",
"name": "Deployment {$K8S.DEPLOYMENT.NAME} has unavailable replicas",
"priority": "HIGH",
"description": "Some replicas of deployment {$K8S.DEPLOYMENT.NAME} are not ready"
}
],
"macros": [
{"macro": "{$K8S.DEPLOYMENT.NAME}", "value": ""},
{"macro": "{$K8S.NAMESPACE}", "value": "default"},
{"macro": "{$K8S.API.TOKEN}", "value": ""}
]
}]
}
}
return template
def export_templates(self, output_dir: str = "./k8s_templates"):
"""テンプレートファイル出力"""
import os
os.makedirs(output_dir, exist_ok=True)
templates = {
"kubernetes_node_template.json": self.generate_node_template(),
"kubernetes_pod_template.json": self.generate_pod_template(),
"kubernetes_deployment_template.json": self.generate_deployment_template()
}
for filename, template in templates.items():
filepath = os.path.join(output_dir, filename)
with open(filepath, 'w') as f:
json.dump(template, f, indent=2)
print(f"Generated template: {filepath}")
# クラスターリソース情報も出力
resources = self.discover_cluster_resources()
with open(os.path.join(output_dir, "cluster_resources.yaml"), 'w') as f:
yaml.dump(resources, f, default_flow_style=False)
print(f"Cluster resources exported to: {os.path.join(output_dir, 'cluster_resources.yaml')}")
# 使用例
def main():
# Kubernetesクラスター内から実行する場合
generator = KubernetesZabbixTemplateGenerator()
# テンプレート生成・出力
generator.export_templates()
print("Kubernetes Zabbix templates generated successfully!")
if __name__ == "__main__":
main()
まとめ
実践的なZabbixシナリオの学習により、様々な環境・要件に対応できる監視システムの設計・実装能力を習得できます。
重要ポイント
- 規模別設計: 企業規模に応じた最適なアーキテクチャ選択
- クラウド統合: モダンインフラとの効果的な統合
- DevOps連携: 開発・運用プロセスとの密接な統合
- コンテナ対応: 動的なコンテナ環境での監視実装
次のステップ
最終章では、継続的改善手法について学習し、監視システムの長期的な成功と組織能力向上を実現します。