web-dev-qa-db-ja.com

HAProxyでHTTP / 2を有効にするにはどうすればよいですか?

最近、HTTPからHTTPSに移行しました。すでにHTTPSに移行しているため、パフォーマンスのメリットを得るためにHTTP/2に移行することを考えています。

enter image description here

上記で説明したように、LBとアプリサーバー間の通信は引き続きHTTPを使用している間、ブラウザーとLB間の要求は保護されます(HTTPS)

現在の設定でHTTP/2を有効にする可能性は何ですか? LBとアプリサーバー間の通信がHTTPのままで、ブラウザーとLBの間でHTTP/2を有効にできますか?

17
ssharma

HAProxy 1.8はHTTP/2をサポートします

1.8発表 から:

HAProxy 1.8は、クライアント側(フロントエンドセクション)でHTTP/2をサポートするようになり、HTTP/2クライアントとHTTP/1.1およびHTTP/1.0アプリケーション間のゲートウェイとして機能できます。

h2haproxy.confディレクティブが必要です。 FromCertSimpleのHAProxy HTTP/2および動的負荷分散ガイド

frontend myapp
  bind :443 ssl crt /path/to/cert.crt alpn h2,http/1.1
  mode http

HAProxyの古いバージョン

1.6や1.7などの古いバージョンのHAProxyは、パススルーHTTP/2のみをサポートします。つまり、HTTP/2をサポートする別のアプリサーバーにトラフィックを転送します。これはかなり複雑です-これを行う方法に関する他の回答を参照してください。 HTTP/2を終了してHAProxyのトラフィックを読み取るには、HAProxy 1.8が必要です。

32
mikemaccana

NginXとともにいくつかのHaProxyを実行できる場合、以下はロードバランサーで動作するはずです。 NginXは、フル機能のWebサーバーとしてではなく、純粋なSSLターミネーターとして(ab)使用されるため、このNginXによってコンテンツは提供されません。

警告:これは急いで行われたため、これが実際に機能することは確認されていません。いくつかの例が欠落しているので、リンクは申し訳ありません。

このアイデアは、有名なMunchhausenの絵にちなんで、自分自身と馬を沼地から引き抜きました

ミュンヒハウゼン法

まず、 HaProxyでH2設定を行いますScott Farrell の答えのように、次の調整を行います:

frontend http-in
    mode http
    bind *:80
    option forwardfor
    default_backend nodes-http

frontend https-in
    mode tcp
    bind *:443 ssl crt /etc/ssl/dummy.pem alpn h2,http/1.1
    use_backend nodes-http2 if { ssl_fc_alpn -i h2 }
    default_backend nodes-http

frontend http-lo
    mode http
    bind 127.0.0.1:82
    #http-request set-header X-Forwarded-For req.hdr_ip([X-Forwarded-For])
    default_backend nodes-http

backend nodes-http
    mode http
    server node1 web.server:80 check

backend nodes-http2
    mode tcp
    server loadbalancer 127.0.0.1:81 check send-proxy

これはHTTP/2接続をロードバランサーマシンにループバックし、http-loを介して再びロードバランシングに入るためのデコードされたリクエストを受け入れます。

LB自体で、NginXを起動して、ポート81をリッスンして構成インスタンスと同様にHTTP/2接続を終了し、ロードバランサーに再度プロキシします。

NginXでは、次のことを確認してください。

  • NginXのsend-proxy-protocol を使用します

  • NginXHTTP/2を使用してSSLを終了します

  • すべてを透過的に(別名、ダム)プロキシして、HaProxy port 82に戻します。

    # Sorry, example `NginX`-config is missing here,
    # but it includes something like:
    proxy_pass http://127.0.0.1:82;
    
  • プロキシリクエストにX-Forwarded-Forヘッダーを介してClient-IPを含めることを忘れないでください(発信プロキシリクエストで「プロキシを送信」プロトコルを使用するようにNginXを構成する方法がわかりません)。

このセットアップはほとんど静的であることに注意してください。変更部分は、これらすべてのドメインとそれらのTLS証明書に関するものです。

HTTP/2リクエストフローのASCII画像

     Browser
        |  HTTP/2
        V
     Loadbalancer HaProxy *:443
        |  frontend https-in
        |  backend nodes-http2
        |  send-proxy
        |  TCP (transparent, HTTP/2)
        V
     Loadbalancer NginX 127.0.0.1:81 
        |  HTTP/2 termination
        |  proxy_protocol
        |  proxy_pass 127.0.0.1:82
        |  Add header X-Forwarded-For
        |  HTTP
        V
     Loadbalancer HaProxy 127.0.0.1:82
        |  frontend https-lo
        |  Forward Header X-Forwarded-For
        |  backend nodes-http
        |  # DO YOUR LOADBALANCING HERE
        |  HTTP
        V
      web.server:80

はい、HaProxyを2回ループしますが、HaProxyの動作速度のおかげで、これは非常に高速に動作します。

本当に非効率な部分は、HTTP/2ヘッダーをプレーンなHTTPヘッダーに圧縮解除することです。

1
Tino

haproxyはまだhttp/2をサポートしていません

唯一サポートしているのは、http/2リクエストを検出し、httpsおよびhttp/2をサポートするサーバーにhttps/tcp443 tcpストリームを渡すことです。

ここに他の人のガイドがあります http://m12.io/blog/http-2-with-haproxy-and-nginx-guide

1
Scott Farrell