Amazon EKS で HTTP 504 エラーが発生した場合の解決方法を教えてください。

最終更新日 2020 年 2 月 17 日

Amazon Elastic Kubernetes Service (Amazon EKS) の Classic Load Balancer もしくは Application Load Balancer を通じ Kubernetes サービスに接続しようとしたところ、HTTP 504 エラーが発生しました。

簡単な説明

HTTP 504 エラーは、次のような理由で発生することがあります。

  • ロードバランサーは接続を確立していますが、ターゲットから、アイドル状態のタイムアウト時間以内に応答が返されませんでした。Classic Load Balancer と Application Load Balancer では、アイドル状態のデフォルトのタイムアウト時間は、60 秒間に設定されています。
  • ロードバランサーが、接続のタイムアウト時間(10 秒間)以内に、バックエンドターゲットとの接続を確立できませんでした。
  • 一時的ポート(1024-65535)での、ターゲットからロードバランサーノードへの接続が、サブネット用のアクセスコントロールリスト(ACL)で許可されていません。

解決方法

アイドル状態のタイムアウト時間が適切に設定されているか、ロードバランサーを確認します。

1.    Classic Load Balancer もしくは Application Load Balancer 用の、Amazon CloudWatch メトリクスを確認します。

ロードバランサーで設定されているタイムアウト時間と、レイテンシーのデータポイントの値が等しく、HTTPCode_ELB_5XX メトリクスにデータポイントが存在する場合には、少なくとも 1 つのリクエストでタイムアウトが発生しています。

2.    HTTP リクエストの処理がアイドル状態以内に完了できるよう、ロードバランサーのタイムアウト時間を修正します。あるいは、アプリケーションの設定を、応答が早くなるように変更します。

Classic Load Balancer のアイドル状態のタイムアウトを変更するには、サービスの定義で、service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeoutアノテーションを含むように修正します。サンプルについては、他のELBアノテーションを参照してください。

Application Load Balancer のアイドル状態のタイムアウトを変更するには、alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds アノテーションを含むようにイングレスの定義を修正します。サンプルについては、Ingress annotations を参照してください。

バックエンドインスタンスで、バックエンド接続エラーが起きていないことを確認します。

ロードバランサーがアイドル状態のタイムアウトに達する以前に、バックエンドインスタンスにより TCP 接続が終了された場合、そのロードバランサーはリクエストに完全に対応できない場合があります。

1.    Classic Load Balancer に関しては BackendConnectionErrors メトリクスを、Application Load Balancer については TargetConnectionErrorCount メトリクスを、それぞれ CloudWatch で確認します。

2.    バックエンドのワーカーノードもしくはポッドで、keep-alive 設定を有効化します。さらに、keep-alive タイムアウト値を、ロードバランサーのアイドル状態アイムアウトより大きな値に設定します。

keep-alive 値が、アイドル状態のタイムアウトより小さいかどうかは、ポッドもしくはワーカーノードで、keep-alive 値を見ることで確認できます。ポッドとノードに関する例を、次に示します。

ポッドでの例:

$ kubectl exec your-pod-name -- sysctl \
    net.ipv4.tcp_keepalive_time \
    net.ipv4.tcp_keepalive_intvl \
    net.ipv4.tcp_keepalive_probes

ノードでの例:

$ sysctl \
    net.ipv4.tcp_keepalive_time \
    net.ipv4.tcp_keepalive_intvl \
    net.ipv4.tcp_keepalive_probes

ロードバランサーからのトラフィックを、一時ポート範囲でバックエンドターゲットが受信できることを確認します。

ロードバランサーとバックエンドターゲットの間でデータが移動できるように、セキュリティグループとネットワーク ACL を設定する必要があります。たとえば、ロードバランサーのタイプに応じて、これらのターゲットは IP アドレスやインスタンスで指定します。

一時ポートアクセスのためのセキュリティグループを設定するには、そのセキュリティグループ内のノードもしくはポッド用のエグレスルールを、ロードバランサーのセキュリティグループに接続する必要があります。詳細については、「セキュリティグループを操作する」および「ルールの追加と削除」を参照してください。