Kubernetes Ingressの503エラー修正:「No Endpoints Available」の解決策

intermediate☸️ Kubernetes2026-05-26| Kubernetesクラスター(クラウドまたはオンプレミス)、NGINX Ingress Controller

Error Message

503 Service Temporarily Unavailable no endpoints available for service "my-service"
#ingress#nginx-ingress#503#endpoints#service#kubernetes

503エラーの解読

アプリケーションのURLにアクセスした際、ダッシュボードの代わりに 503 Service Temporarily Unavailable という冷ややかな画面が表示されることがあります。NGINX Ingressを使用している場合、コントローラーのログには通常、次のような原因が記録されています。

[error] 197#197: *3586884 Service "default/my-service" does not have any active endpoints

このメッセージは非常に役立ちます。IngressはServiceを見つけられたものの、そのServiceがリクエストを処理するための正常なPodを見つけられなかったことを示しているからです。

根本原因

Kubernetesのルーティングは連鎖のように機能します。IngressがServiceを指し、そのServiceがPodのセットを指します。これが機能するために、ServiceはEndpointsリスト、つまり正常なPodのIPアドレスのリアルタイムなディレクトリを保持しています。

503エラーは、そのディレクトリが空のときに発生します。通常、ラベルの不一致、ヘルスチェックの失敗、または単純なポート番号の入力ミスが原因でこの断絶が起こります。

ステップバイステップのトラブルシューティング

1. Endpointsリソースの確認

まずは、ServiceとPodの間の架け橋が壊れていないか確認しましょう。次のコマンドを実行します。

kubectl get endpoints my-service -n <your-namespace>

ENDPOINTS 列を確認してください。もし <none> と表示されていれば、トラフィックの送り先がない状態です。これにより、問題はIngress自体ではなく、Pod側、あるいはServiceによるPodの選択方法にあることが確認できます。

2. ラベルの不一致を探す

ラベルはKubernetesにおける「接着剤」です。Serviceが app: payment-api を探しているのに、DeploymentがPodに app: payment-gateway というラベルを付けている場合、Serviceはそれらを見つけることができません。これはよくあるコピー&ペーストのミスです。

Serviceが何を探しているか確認します。

kubectl describe svc my-service -n <your-namespace> | grep Selector

次に、Podに付いている実際のラベルを一覧表示します。

kubectl get pods -n <your-namespace> --show-labels

Podは、Serviceセレクターに記載されているすべてのラベルを持っている必要があります。Serviceが3つのラベルを指定しているのに、Podが2つしか持っていない場合、トラフィックは受信されません。

3. Readiness Probeの失敗を診断する

Podは「Running(実行中)」であっても「Ready(準備完了)」ではない場合があります。Readiness Probe(起動準備状態チェック)が失敗すると、Kubernetesは壊れたコンテナにトラフィックを送信しないよう、EndpointsリストからそのIPを削除します。

Podの READY 列を確認します。

kubectl get pods -n <your-namespace>

もし 0/1 と表示されていれば、Podは生きていますがヘルスチェックに失敗しています。詳細を確認するには、 kubectl describe pod <pod-name> を実行し、下部の「Events」セクションを確認してください。 Readiness probe failed: HTTP probe failed with statuscode: 500 のようなエラーが表示されているかもしれません。これは、アプリケーション(Java Spring Bootサービスなど)の起動に45秒かかるのに、プローブがわずか5秒後からチェックを開始する場合によく発生します。

4. ポートマッピングの検証

ポート番号の入力ミスは「サイレントキラー」です。アプリケーションコンテナがポート 8080 で待機しているのに、Serviceが targetPort: 80 にトラフィックを送信している場合、接続はタイムアウトします。

Serviceの targetPort が、Deployment의 containerPort と一致していることを確認してください。

# Service (サービス)
ports:
- port: 80
  targetPort: 8080 # 下記と一致させる必要があります

# Deployment (デプロイメント)
containers:
- name: my-app
  ports:
  - containerPort: 8080 # 上記と一致させる必要があります

修正の確認

ラベルやプローブを更新した後、再度Endpointsリストを確認してください。 10.244.1.45:8080 のような内部IPアドレスのリストが表示されるはずです。100%確実にするために、クラスター内から簡単な接続テストを実行しましょう。

kubectl run curl-test --image=curlimages/curl -i --tty --rm -- curl http://my-service:80

200 OK というレスポンスが返ってくれば、503エラーは正式に解決されたことになります。

ベストプラクティス

  • ラベルの標準化: チーム間でセレクターの一貫性を保つために、 app.kubernetes.io/name などの標準ラベルを使用しましょう。
  • 適切なプローブ遅延の設定: initialDelaySeconds を、アプリの実際の起動時間に合わせて設定してください。起動の遅いアプリに30秒ほどの猶予を与えることで、不要な503エラーを防ぐことができます。
  • アラートの自動化: Prometheusなどのツールを使用して、 kube_endpoint_address_available がゼロになったときに通知されるようにしましょう。

Related Error Notes