Cloudflare Load Balancing

クラウドベースのグローバルロードバランサー。インテリジェントルーティング、ヘルスチェック、DDoS保護を統合。世界290都市のエッジネットワーク。

ロードバランサーDNSクラウドグローバルSaaSDDoS保護ヘルスチェックトラフィック制御

サーバー

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 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