AI

ロードバランサーOSS比較:Nginx vs HAProxy vs Traefik でAWS ELB代替をセルフホスト

オープンソースラボ編集部2026年6月13日

ロードバランサーOSS比較:Nginx vs HAProxy vs Traefik でAWS ELB代替をセルフホスト

AWS ALB/ELBは月$0.008/LCU+トラフィック量課金で、高トラフィック環境では月数万円になります。Nginx(デファクトスタンダード・高機能Web+LB)・HAProxy(純粋L4/L7LB・金融系で多用)・Traefik(コンテナ自動検出・Let's Encrypt内蔵)はOSSのロードバランサーで、VPS1台からKubernetesまで幅広く使えます。

ロードバランサー選定の背景

  • コスト削減: AWS ALBの月$100〜を、VPS $5/月のNginxで代替する
  • Kubernetes Ingress: NginxやTraefikをK8s Ingressコントローラーとして使う
  • Let's Encrypt自動SSL: TraefikはHTTPS証明書の自動取得・更新が設定1行で完了
  • Blue/Green・カナリア: バックエンドの重み付けルーティングで段階的なデプロイを実現
  • WebSocket・gRPC: 長期接続・HTTP/2のロードバランシングが必要

主要ツールの概要

Nginx

Igor Sysoevが開発した高性能Webサーバーかつリバースプロキシです。GitHubスター(nginx本体は公式Gitlabのみ)。HTTPサーバー・リバースプロキシ・ロードバランサー・メールプロキシ機能を持ち、現在世界のWebサーバーシェア約30%を占めます。

# nginx.conf - リバースプロキシ + ロードバランシング設定
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 10000;
    use epoll;
    multi_accept on;
}

http {
    # ロードバランシング: 重み付きラウンドロビン
    upstream backend {
        least_conn;  # 最小接続数ベース(デフォルトはround_robin)

        server app1.internal:3000 weight=5;   # 50%のリクエスト
        server app2.internal:3000 weight=3;   # 30%のリクエスト
        server app3.internal:3000 weight=2;   # 20%のリクエスト

        # ヘルスチェック(Nginx Plus機能。OSS版は下記passive方式)
        server app4.internal:3000 backup;     # 全サーバーダウン時のフォールバック
        keepalive 32;
    }

    server {
        listen 80;
        server_name yoursite.com www.yoursite.com;
        return 301 https://$host$request_uri;  # HTTPSにリダイレクト
    }

    server {
        listen 443 ssl http2;
        server_name yoursite.com www.yoursite.com;

        ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
        ssl_prefer_server_ciphers off;

        # セキュリティヘッダー
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src 'self' https: data: blob: 'unsafe-inline'" always;
        add_header Strict-Transport-Security "max-age=63072000" always;

        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            # タイムアウト設定
            proxy_connect_timeout 5s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;

            # バッファリング
            proxy_buffering on;
            proxy_buffer_size 128k;
            proxy_buffers 4 256k;
        }

        # WebSocketのプロキシ
        location /ws {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }

        # 静的ファイルはNginxが直接配信
        location /static/ {
            root /var/www/html;
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
}
# Ubuntu/DebianにNginxをインストール
sudo apt update && sudo apt install -y nginx certbot python3-certbot-nginx

# Let's Encryptで自動SSL証明書を取得(Nginx設定を自動変更)
sudo certbot --nginx -d yoursite.com -d www.yoursite.com   --non-interactive --agree-tos -m admin@yoursite.com

# 証明書自動更新のcron確認
sudo systemctl list-timers | grep certbot
# または手動テスト
sudo certbot renew --dry-run

HAProxy

Willy Tarreauが開発する高性能なTCP/HTTPロードバランサーです。GitHubスター5k+。L4(TCP)・L7(HTTP)両方のロードバランシングに対応し、金融機関・大規模EC・高トラフィックAPIで採用実績が豊富です。Nginxより設定が直感的なACL(アクセスコントロールリスト)によるトラフィック振り分けが特徴です。

# haproxy.cfg - 本番向け設定例
global
    maxconn     50000
    log         127.0.0.1 local0
    chroot      /var/lib/haproxy
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/run/haproxy/admin.sock mode 660 level admin
    tune.ssl.default-dh-param 2048

defaults
    mode            http
    log             global
    option          httplog
    option          dontlognull
    option          http-server-close
    option          forwardfor except 127.0.0.0/8
    option          redispatch
    retries         3
    timeout connect 5s
    timeout client  30s
    timeout server  30s
    timeout http-request 10s
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 503 /etc/haproxy/errors/503.http

# 統計ダッシュボード
listen stats
    bind *:8080
    stats enable
    stats uri /haproxy?stats
    stats realm HAProxy\ Statistics
    stats auth admin:your-stats-password
    stats refresh 30s

# HTTPSフロントエンド
frontend https_front
    bind *:443 ssl crt /etc/haproxy/certs/yoursite.pem alpn h2,http/1.1
    bind *:80
    http-request redirect scheme https code 301 unless { ssl_fc }

    # ACL: パスによるバックエンド振り分け
    acl is_api path_beg /api/
    acl is_ws hdr(Upgrade) -i websocket

    use_backend api_servers if is_api
    use_backend ws_servers if is_ws
    default_backend web_servers

# Webバックエンド(ラウンドロビン)
backend web_servers
    balance roundrobin
    option httpchk GET /health HTTP/1.1
Host:\ yoursite.com
    http-check expect status 200

    server web1 10.0.0.1:3000 check inter 2s fall 3 rise 2
    server web2 10.0.0.2:3000 check inter 2s fall 3 rise 2
    server web3 10.0.0.3:3000 check inter 2s fall 3 rise 2

# APIバックエンド(最小接続数)
backend api_servers
    balance leastconn
    option httpchk GET /api/health
    http-check expect status 200

    server api1 10.0.1.1:8080 check inter 1s fall 2 rise 3
    server api2 10.0.1.2:8080 check inter 1s fall 2 rise 3

# WebSocketバックエンド(ソースIP固定)
backend ws_servers
    balance source
    timeout tunnel 1h
    server ws1 10.0.2.1:3001 check
    server ws2 10.0.2.2:3001 check

Traefik

Containous(現Traefik Labs)が開発するクラウドネイティブなリバースプロキシです。GitHubスター51k+。Docker/Kubernetes/Consul/ECSなどのプロバイダーを自動検出してルーティングを動的に設定でき、Let's Encrypt証明書の自動取得・更新が設定1行で完了します。Docker Composeで新しいコンテナを起動するだけで自動的にHTTPS対応のサブドメインが割り当てられます。

# docker-compose.yml でTraefikを起動
version: "3"

services:
  traefik:
    image: traefik:v3.0
    restart: always
    command:
      # ダッシュボードを有効化
      - "--api.dashboard=true"
      # Dockerプロバイダーを有効化
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      # エントリポイント設定
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # Let's Encrypt自動SSL
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@yoursite.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      # アクセスログ
      - "--accesslog=true"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt
    labels:
      # ダッシュボードにアクセス(Basic認証)
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.yoursite.com`)"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$2y$$05$$... "

  # アプリコンテナはラベルを追加するだけで自動でHTTPS化
  my-app:
    image: my-app:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.my-app.rule=Host(`app.yoursite.com`)"
      - "traefik.http.routers.my-app.entrypoints=websecure"
      - "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
      - "traefik.http.services.my-app.loadbalancer.server.port=3000"
      # HTTPSにリダイレクト
      - "traefik.http.routers.my-app-http.rule=Host(`app.yoursite.com`)"
      - "traefik.http.routers.my-app-http.entrypoints=web"
      - "traefik.http.routers.my-app-http.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"

volumes:
  letsencrypt:

機能比較表

比較項目NginxHAProxyTraefik
ライセンスBSD-2-ClauseGPL/LGPLMIT
L4 TCP LB✅ 優秀
L7 HTTP LB✅ 優秀
Let's Encrypt要certbot要手動✅ 自動
Docker自動検出
K8s Ingress✅ Nginx Ingress✅ Traefik IngressRoute
設定のホットリロード
最小リソース最小
GitHub Stars-5k+51k+

KubernetesでのGitOpsとロードバランサーの組み合わせはDevOpsカテゴリ/categories/devopsを参照。SSLとセキュリティ設定はセキュリティカテゴリ/categories/securityにまとめています。

FAQ

Q. NginxとTraefikはどちらをKubernetes Ingressコントローラーとして使うべきですか?

A. どちらも成熟していますが選択基準が異なります。Nginx Ingress Controller推奨のケース: ①チームがNginx設定に慣れており追加学習コストを避けたい②細かいNginx固有の設定(upstream zone・lua-nginx-module等)が必要③アノテーション数が少なくシンプルな設定で済む。Traefik IngressRoute推奨のケース: ①Docker Composeとの一貫性を保ちたい(dev/prod同じ設定方針)②ミドルウェア(レートリミット・認証・圧縮)をYAMLで宣言的に管理したい③カナリアリリースをTraefikのWeighted Round Robinで簡単に設定したい。AWSではaws-load-balancer-controller(NLB/ALBをK8sから操作)とNginx/Traefikを組み合わせるハイブリッド構成も一般的です。

Q. HAProxyでカナリアリリースの段階的なトラフィック移行を設定する方法は?

A. HAProxyのランタイムAPIを使ってサービスを止めずにバックエンドの重みを動的に変更できます。

# HAProxyのランタイムAPI経由で重みを変更(サービス無停止)
echo "set weight web_servers/web-v2 10" | socat stdio /var/run/haproxy/admin.sock

# 段階的に重みを増やすスクリプト
for weight in 10 20 30 50 80 100; do
  echo "set weight web_servers/web-v2 $weight" | socat stdio /var/run/haproxy/admin.sock
  echo "Traffic to v2: $weight%"
  # メトリクスを確認してから次のステップへ(例: 5分待機)
  sleep 300
done

# v1を完全に除外
echo "set server web_servers/web-v1 state maint" | socat stdio /var/run/haproxy/admin.sock

PromQLでエラー率が上昇したらv1に戻す自動ロールバックスクリプトと組み合わせると、ArgoCDのRollout・Flaggerと同等のProgressive Deliveryが実現できます。

Q. TraefikのMiddlewareでレートリミットとIP制限を設定する方法は?

A. TraefikのMiddlewareは宣言的に組み合わせられます。

# Traefikのミドルウェア設定(docker labels版)
# レートリミット: 1秒に100リクエストまで
- "traefik.http.middlewares.rate-limit.ratelimit.average=100"
- "traefik.http.middlewares.rate-limit.ratelimit.period=1s"
- "traefik.http.middlewares.rate-limit.ratelimit.burst=200"
# IPホワイトリスト
- "traefik.http.middlewares.ip-whitelist.ipallowlist.sourcerange=10.0.0.0/8,192.168.0.0/16"
# Basic認証
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..."
# HTTPS強制リダイレクト
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
# セキュリティヘッダー
- "traefik.http.middlewares.security-headers.headers.browserxssfilter=true"
- "traefik.http.middlewares.security-headers.headers.contenttypenosniff=true"
- "traefik.http.middlewares.security-headers.headers.forcestsheader=true"
- "traefik.http.middlewares.security-headers.headers.stsseconds=63072000"

# APIルートに複数ミドルウェアをまとめて適用
- "traefik.http.routers.api.middlewares=rate-limit,ip-whitelist,security-headers"

Kubernetes環境ではTraefik Middleware CRD(カスタムリソース定義)として設定します。

Q. NginxをAPI Gatewayとして使い、OpenID ConnectでJWT検証を行う方法は?

A. nginx-auth-requestモジュールを使って認証サーバー(Keycloak/Authentik)にサブリクエストを送り、JWTを検証できます。より簡単な方法はngx_http_auth_jwt_moduleを使うことです。

# nginx.conf でJWT検証(nginx.orgビルドのcommercialモジュールまたはOpenResty)
# OpenRestyを使った方法:
location /api/ {
    access_by_lua_block {
        local jwt = require("resty.jwt")
        local auth_header = ngx.req.get_headers()["Authorization"]
        if not auth_header or not auth_header:match("Bearer ") then
            ngx.status = 401
            ngx.say('{"error": "missing token"}')
            ngx.exit(401)
        end
        local token = auth_header:gsub("Bearer ", "")
        local jwt_obj = jwt:verify("your-jwt-secret", token)
        if not jwt_obj.verified then
            ngx.status = 401
            ngx.exit(401)
        end
        # JWTのクレームをバックエンドヘッダーに転送
        ngx.req.set_header("X-User-Id", jwt_obj.payload.sub)
        ngx.req.set_header("X-User-Role", jwt_obj.payload.role)
    }
    proxy_pass http://backend;
}

本番環境ではnginx-jwtモジュールよりもKeycloak/AuthentikをOIDC認証プロバイダーとして使い、NginxはJWT検証をAuthリクエスト先に委譲する方が安全です。

まとめ

ユースケース推奨ツール
高トラフィックL4/L7・金融系HAProxy
Web+LB統合・静的ファイル配信Nginx
Docker/K8s自動化・Let's EncryptTraefik
KubernetesIngressNginx Ingress または Traefik

関連外部リソース

他の記事も読む

Let's Build Together

OSS導入、自社だけで悩まない。

ツール選定から構築・運用・AI活用まで、オープンソースラボ運営元のClasslessが伴走します。初回のご相談は無料です。