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 秒) になる前に、ロードバランサーはバックエンドターゲットへの接続の確立に失敗した。
  • サブネットのネットワークアクセスコントロールリスト (ACL) は、ターゲットから一時ポート (1024-65535) 上のロードバランサーノードへのトラフィックが許可されていません。

解決方法

ロードバランサーのアイドルタイムアウトが正しく設定されていることを確認する

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 のアイドルタイムアウトを変更するには、Ingress 定義を更新して alb.ingress.kubernetes.io/load-balancer-attributes:idle_timeout.timeout_seconds 注釈を含めます。具体例については、「Ingress の注釈」を参照してください。

バックエンドインスタンスにバックエンド接続エラーがないことを確認する

ロードバランサーがアイドルタイムアウト値に達する前に、バックエンドインスタンスがロードバランサーへの TCP 接続を閉じた場合、ロードバランサーはリクエストを満たせない可能性があります。

1.    Classic Load Balancer の CloudWatch BackendConnectionErrors メトリクスと、Application Load Balancer のターゲットグループの TargetConnectionErrorCount を確認します。

2.    バックエンドワーカーノードまたはポッドでキープアライブ設定を有効にします。キープアライブタイムアウトをロードバランサーのアイドルタイムアウトより大きい値に設定します。

キープアライブタイムアウトがアイドルタイムアウトより小さいかどうかを確認するには、ポッドまたはワーカーノードのキープアライブ値を確認します。ポッドとノードについては、次の例を参照してください。

ポッドの場合:

$ 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 アドレスまたはインスタンスになりえます。

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