Cloudflare Load Balancing
クラウドベースのグローバルロードバランサー。インテリジェントルーティング、ヘルスチェック、DDoS保護を統合。世界290都市のエッジネットワーク。
サーバー
Cloudflare Load Balancing
概要
Cloudflare Load Balancingは、世界330以上の都市に展開するCloudflareのグローバルネットワークを活用したクラウドベースの負荷分散サービスです。DNSレベルでの高速なトラフィック制御により、エンドポイントの負荷軽減とレイテンシ改善を実現します。地理的分散、重み付けによる負荷分散、リアルタイムヘルスチェック機能により、グローバルユーザーに最適なパフォーマンスを提供します。SaaSソリューションとして、追加のハードウェア・ソフトウェアを必要とせず、Cloudflareダッシュボードやbuild in DDoS保護APIによる簡単な設定・管理が可能です。
詳細
Cloudflare Load Balancingは、世界最速の権威DNSサーバーとDDoS耐性を備えたインフラストラクチャ上で動作し、L4-L7プロトコル(HTTP/HTTPS、TCP、UDP)に対応します。エンドポイントプール(機能・地理的エリア・リージョン別のエンドポイントグループ)、ヘルスモニター(サービスタイプ・パス・ポート設定)、トラフィック制御アルゴリズムから構成されます。地理的ルーティング、レイテンシベースルーティング、GPSベースルーティング等の高度なトラフィック制御機能により、ユーザーに最適なエンドポイントへの自動誘導を実現します。リアルタイム分析、包括的ヘルスモニタリング、自動フェイルオーバー機能を提供します。
主な特徴
- グローバルネットワーク: 330以上の都市でのトラフィック分散とDDoS保護
- インテリジェントルーティング: 地理的・レイテンシ・GPSベースの最適ルーティング
- リアルタイムヘルスチェック: 複数データセンターでの継続的エンドポイント監視
- マルチプロトコル対応: HTTP/HTTPS、TCP、UDPでの負荷分散
- APIファーストアプローチ: 開発者フレンドリーなREST APIとダッシュボード
- 統合セキュリティ: DDoS保護、WAF、SSL/TLS暗号化の統合
メリット・デメリット
メリット
- グローバルな分散ネットワークによる低レイテンシと高可用性
- 追加ハードウェア不要でスケーラブルなSaaSソリューション
- DDoS保護・WAF・CDN等のセキュリティ機能統合
- 直感的なダッシュボードと充実したAPI機能による運用効率化
- リアルタイム分析・アラート機能による詳細な監視とインサイト
- 自動フェイルオーバーとセルフヒーリング機能による運用負荷軽減
デメリット
- クラウドベースによるロードバランサー・エンドポイント間のレイテンシ増加
- Cloudflareネットワーク依存によるベンダーロックインリスク
- 複雑な設定での学習コストと管理コストの増加
- DNSベースルーティングによるリアルタイム性の制約
- 使用量ベース料金によるトラフィック増加時のコスト上昇
- オンプレミス環境との統合における制約事項
参考ページ
- Cloudflare Load Balancing 公式サイト
- Cloudflare Load Balancing ドキュメント
- Cloudflare API ドキュメント
- Cloudflare ダッシュボード
書き方の例
基本設定とプール作成
# Cloudflare APIキー設定
export CF_API_TOKEN="your_cloudflare_api_token"
export CF_ZONE_ID="your_zone_id"
# Load Balancer用プール作成
curl -X POST "https://api.cloudflare.com/client/v4/user/load_balancers/pools" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"name": "web-servers-pool",
"description": "Primary web servers pool",
"enabled": true,
"minimum_origins": 1,
"monitor": "health_check_monitor",
"origins": [
{
"name": "web-server-1",
"address": "203.0.113.10",
"enabled": true,
"weight": 1,
"header": {
"Host": ["example.com"]
}
},
{
"name": "web-server-2",
"address": "203.0.113.11",
"enabled": true,
"weight": 1,
"header": {
"Host": ["example.com"]
}
}
],
"notification_email": "[email protected]"
}'
# 地理的バックアッププール作成
curl -X POST "https://api.cloudflare.com/client/v4/user/load_balancers/pools" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"name": "backup-pool-eu",
"description": "European backup servers",
"enabled": true,
"minimum_origins": 1,
"origins": [
{
"name": "backup-eu-1",
"address": "198.51.100.10",
"enabled": true,
"weight": 1
},
{
"name": "backup-eu-2",
"address": "198.51.100.11",
"enabled": true,
"weight": 1
}
]
}'
ヘルスチェックモニター設定
# HTTPヘルスチェックモニター作成
curl -X POST "https://api.cloudflare.com/client/v4/user/load_balancers/monitors" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "http",
"description": "Web server health check",
"method": "GET",
"path": "/health",
"port": 80,
"interval": 60,
"retries": 2,
"timeout": 5,
"expected_codes": "200",
"expected_body": "healthy",
"follow_redirects": true,
"allow_insecure": false,
"header": {
"Host": ["example.com"],
"User-Agent": ["Cloudflare-Health-Check"]
}
}'
# HTTPSヘルスチェック
curl -X POST "https://api.cloudflare.com/client/v4/user/load_balancers/monitors" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "https",
"description": "HTTPS health check",
"method": "GET",
"path": "/api/health",
"port": 443,
"interval": 30,
"retries": 3,
"timeout": 10,
"expected_codes": "200-299",
"expected_body": "\"status\":\"ok\"",
"header": {
"Authorization": ["Bearer health_check_token"]
}
}'
# TCPヘルスチェック
curl -X POST "https://api.cloudflare.com/client/v4/user/load_balancers/monitors" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "tcp",
"description": "Database TCP health check",
"port": 3306,
"interval": 60,
"retries": 2,
"timeout": 5
}'
ロードバランサー作成と地理的ルーティング
# 基本ロードバランサー作成
curl -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/load_balancers" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"name": "api.example.com",
"description": "API load balancer with geographic routing",
"ttl": 30,
"fallback_pool": "backup-pool-global",
"default_pools": ["web-servers-pool"],
"region_pools": {
"WNAM": ["web-servers-pool-us"],
"ENAM": ["web-servers-pool-us"],
"WEU": ["web-servers-pool-eu"],
"EEU": ["web-servers-pool-eu"],
"APAC": ["web-servers-pool-asia"]
},
"country_pools": {
"JP": ["web-servers-pool-japan"],
"CN": ["web-servers-pool-china"],
"AU": ["web-servers-pool-australia"]
},
"pop_pools": {
"LAX": ["web-servers-pool-california"],
"ORD": ["web-servers-pool-chicago"]
},
"steering_policy": "geo",
"session_affinity": "cookie",
"session_affinity_ttl": 1800,
"session_affinity_attributes": {
"samesite": "Auto",
"secure": "Auto",
"drain_duration": 100
}
}'
# ランダム・ステアリング設定
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/load_balancers/{load_balancer_id}" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"steering_policy": "random",
"random_steering": {
"pool_weights": {
"pool_id_1": 0.7,
"pool_id_2": 0.2,
"pool_id_3": 0.1
},
"default_weight": 1
}
}'
高度なトラフィック制御設定
// JavaScript APIクライアント使用例
const cloudflare = require('cloudflare');
const cf = cloudflare({
token: 'your_cloudflare_api_token'
});
// 動的重み付け調整
async function updatePoolWeights(poolId, origins) {
try {
const response = await cf.userLoadBalancerPools.edit(poolId, {
origins: origins.map(origin => ({
name: origin.name,
address: origin.address,
weight: origin.weight,
enabled: origin.enabled
}))
});
console.log('Pool weights updated:', response.result);
} catch (error) {
console.error('Error updating pool weights:', error);
}
}
// カナリアデプロイメント設定
async function setupCanaryDeployment(lbId, productionPool, canaryPool, canaryWeight = 0.1) {
const config = {
steering_policy: 'random',
random_steering: {
pool_weights: {}
},
default_pools: [productionPool, canaryPool]
};
config.random_steering.pool_weights[productionPool] = 1 - canaryWeight;
config.random_steering.pool_weights[canaryPool] = canaryWeight;
try {
const response = await cf.dnsRecords.edit(zoneId, lbId, config);
console.log('Canary deployment configured:', response.result);
} catch (error) {
console.error('Error setting up canary deployment:', error);
}
}
// レイテンシベースルーティング
const latencyBasedConfig = {
steering_policy: 'proximity',
proximity_steering: {
policy: "least_outstanding_requests"
}
};
Terraform設定例
# terraform/cloudflare_lb.tf
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
# ヘルスチェックモニター
resource "cloudflare_load_balancer_monitor" "http_monitor" {
type = "http"
expected_codes = "200"
method = "GET"
timeout = 7
path = "/health"
interval = 60
retries = 2
description = "HTTP health check"
header {
Host = ["example.com"]
}
}
# プライマリプール
resource "cloudflare_load_balancer_pool" "primary_pool" {
name = "primary-web-pool"
monitor = cloudflare_load_balancer_monitor.http_monitor.id
origins {
name = "web-1"
address = "203.0.113.10"
enabled = true
weight = 1
}
origins {
name = "web-2"
address = "203.0.113.11"
enabled = true
weight = 1
}
origins {
name = "web-3"
address = "203.0.113.12"
enabled = true
weight = 2
}
description = "Primary web servers"
enabled = true
minimum_origins = 2
notification_email = "[email protected]"
notification_filter {
pool {
disable = false
healthy = false
}
origin {
disable = false
healthy = false
}
}
}
# バックアッププール
resource "cloudflare_load_balancer_pool" "backup_pool" {
name = "backup-web-pool"
monitor = cloudflare_load_balancer_monitor.http_monitor.id
origins {
name = "backup-1"
address = "198.51.100.10"
enabled = true
}
description = "Backup web servers"
enabled = true
minimum_origins = 1
}
# ロードバランサー
resource "cloudflare_load_balancer" "main_lb" {
zone_id = var.cloudflare_zone_id
name = "api.example.com"
fallback_pool = cloudflare_load_balancer_pool.backup_pool.id
default_pools = [cloudflare_load_balancer_pool.primary_pool.id]
description = "Main application load balancer"
ttl = 30
steering_policy = "geo"
# 地理的ルーティング
region_pools = {
"WNAM" = [cloudflare_load_balancer_pool.primary_pool.id]
"ENAM" = [cloudflare_load_balancer_pool.primary_pool.id]
"WEU" = [cloudflare_load_balancer_pool.backup_pool.id]
"EEU" = [cloudflare_load_balancer_pool.backup_pool.id]
}
# セッション親和性
session_affinity = "cookie"
session_affinity_ttl = 1800
# アダプティブルーティング
adaptive_routing {
failover_across_pools = true
}
# ランダムステアリング
random_steering {
pool_weights = {
(cloudflare_load_balancer_pool.primary_pool.id) = 0.9
(cloudflare_load_balancer_pool.backup_pool.id) = 0.1
}
default_weight = 1
}
}
# DNS レコード
resource "cloudflare_record" "lb_record" {
zone_id = var.cloudflare_zone_id
name = "api"
value = cloudflare_load_balancer.main_lb.id
type = "CNAME"
proxied = true
}
監視とアラート設定
# プール状態確認
curl -X GET "https://api.cloudflare.com/client/v4/user/load_balancers/pools/{pool_id}/health" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json"
# ロードバランサー統計取得
curl -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/load_balancers/{lb_id}/events" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json"
# 通知設定
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/alerting/v3/policies" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"name": "Load Balancer Pool Health Alert",
"description": "Alert when pool becomes unhealthy",
"enabled": true,
"alert_type": "load_balancing_pool_enablement_alert",
"mechanisms": {
"email": [
{
"id": "[email protected]"
}
],
"webhooks": [
{
"id": "webhook_id_here"
}
]
},
"conditions": {
"load_balancing_pool_enablement_alert": {
"pool": "pool_id_here",
"enabled": false
}
}
}'
パフォーマンス最適化設定
# オリジン最適化設定
curl -X PATCH "https://api.cloudflare.com/client/v4/user/load_balancers/pools/{pool_id}" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"load_shedding": {
"default_percent": 0,
"default_policy": "random",
"session_percent": 0,
"session_policy": "hash"
},
"origin_steering": {
"policy": "least_outstanding_requests"
}
}'
# アダプティブルーティング有効化
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/load_balancers/{lb_id}" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"adaptive_routing": {
"failover_across_pools": true
},
"location_strategy": {
"prefer_ecs": "proximity",
"mode": "resolver_ip"
}
}'
# プロキシモードでのパフォーマンス設定
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/always_online" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value": "on"}'
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/settings/rocket_loader" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value": "on"}'
トラブルシューティング
# ロードバランサー状態確認
curl -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/load_balancers" \
-H "Authorization: Bearer $CF_API_TOKEN"
# プールヘルス詳細確認
curl -X GET "https://api.cloudflare.com/client/v4/user/load_balancers/pools/{pool_id}/preview" \
-H "Authorization: Bearer $CF_API_TOKEN"
# DNSルックアップテスト
dig @1.1.1.1 api.example.com
nslookup api.example.com 1.1.1.1
# トレースルート確認
traceroute api.example.com
mtr api.example.com
# Cloudflare分析データ取得
curl -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/analytics/dashboard" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-G -d 'since=-1440' -d 'until=0' -d 'continuous=true'
# ログストリーミング(Enterprise)
curl -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/logpush/jobs" \
-H "Authorization: Bearer $CF_API_TOKEN"
# パフォーマンステスト
curl -w "@curl-format.txt" -o /dev/null -s "https://api.example.com/"
# curl-format.txt content:
# time_namelookup: %{time_namelookup}\n
# time_connect: %{time_connect}\n
# time_appconnect: %{time_appconnect}\n
# time_pretransfer: %{time_pretransfer}\n
# time_redirect: %{time_redirect}\n
# time_starttransfer: %{time_starttransfer}\n
# ----------\n
# time_total: %{time_total}\n