すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:localhost 経由でバインドされたアプリケーションを他の Pod に公開する

最終更新日:Mar 11, 2026

アプリケーションが localhost(127.0.0.1)ではなく 0.0.0.0 にバインドされている場合、クラスター内の他の Pod からそのアプリケーションにアクセスすることはできません。Kubernetes サービスが正しいポートを公開している場合でも同様です。本トピックでは、この現象の原因と、対応する 2 つのソリューションについて説明します。

問題の概要

クラスター内のアプリケーションが localhost でリスンしており、他の Pod が Kubernetes サービスを介してそのアプリケーションにアクセスできない状況です。

一般的な localhost バインドパターン:

言語コード
Gonet.Listen("tcp", "localhost:8080")
Node.jshttp.createServer().listen(8080, "localhost")
Pythonsocket.socket().bind(("localhost", 8083))

原因

Kubernetes の各 Pod には独自の IP アドレスが割り当てられます。サービスはこの Pod の IP アドレスにトラフィックをルーティングしますが、Pod 内部の localhost にはルーティングしません。アプリケーションが localhost にバインドされている場合、ループバックインターフェース(127.0.0.1)のみで接続を受け付けるため、その範囲は Pod 固有のネットワーク名前空間に限定されます。Pod の IP アドレスに到達したトラフィックは、アプリケーションに届くことはありません。

ASM によって管理されるクラスターでは、Istio サイドカープロキシがさらに 1 つのレイヤーを追加します。すなわち、iptables ルールを介してインバウンドトラフィックをインターセプトし、アプリケーションに転送します。アプリケーションが localhost のみでリスンしている場合、サイドカープロキシはトラフィックをアプリケーションに配信できません。これは、転送先が Pod の IP アドレスであり、ループバックアドレスではないためです。

ソリューション

以下の 2 つのアプローチが利用可能です:

アプローチ適用条件
バインドアドレスの変更アプリケーションのソースコードを制御できる場合
Sidecar リソースの構成アプリケーション コードは変更できません。

ソリューション 1:バインドアドレスの変更

アプリケーションのコードを更新し、0.0.0.0 でリスンするように変更します(localhost ではなく)。これにより、アプリケーションはすべてのネットワークインターフェース(Pod の IP を含む)で接続を受け付けるようになります。

言語変更前(localhost)変更後(すべてのインターフェース)
Gonet.Listen("tcp", "localhost:8080")net.Listen("tcp", "0.0.0.0:8080")
Node.jshttp.createServer().listen(8080, "localhost")http.createServer().listen(8080, "0.0.0.0")
Pythonsocket.socket().bind(("localhost", 8083))socket.socket().bind(("0.0.0.0", 8083))

更新後のコードをデプロイした後、他の Pod がサービスを介してアプリケーションに到達可能であることを確認してください。

ソリューション 2:Sidecar リソースの構成

アプリケーションのコードを変更できない場合は、インバウンドトラフィックを localhost アドレスに転送する Istio Sidecar リソースを作成します。サイドカープロキシはサービスのポートでトラフィックを受信し、Pod 内の 127.0.0.1:<container-port> へリダイレクトします。

操作手順

  1. ASM コンソールにログインします。左側のナビゲーションウィンドウで、Service Mesh > Mesh 管理 を選択します。

  2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。 左側のナビゲーションウィンドウで、[トラフィック管理センター] > [サイドカー トラフィック設定] を選択します。 表示されたページで、[YAML から作成] をクリックします。

  3. YAML からの作成 をクリックします。

  4. [作成] ページで、名前空間とテンプレートを選択し、次の YAML 構成を貼り付け、その後 [作成] をクリックします。

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: localhost-access
  namespace: <namespace>
spec:
  ingress:
    - defaultEndpoint: '127.0.0.1:<container-port>'
      port:
        name: tcp
        number: <service-port>
        protocol: TCP
  workloadSelector:
    labels:
      <label-key>: <label-value>

以下のプレースホルダーを実際の値に置き換えてください:

プレースホルダー説明
<namespace>アプリケーションがデプロイされている名前空間default
<container-port>アプリケーションが localhost でリスンしているポート8080
<service-port>Kubernetes サービスが公開しているポート80
<label-key>: <label-value>ターゲットワークロードを識別する Pod のラベルapp: my-service

defaultEndpoint フィールドは、サイドカープロキシがインバウンドトラフィックをどこに転送するかを指定します。127.0.0.1:<container-port> に設定することで、リクエストはアプリケーションが既にリスンしているループバックアドレスにルーティングされます。

修正の検証

いずれかのソリューションを適用した後、Pod 間の接続性をテストします:

# 別の Pod から、サービスを介してアプリケーションにリクエストを送信します
kubectl exec -it <test-pod> -- curl http://<service-name>.<namespace>.svc.cluster.local:<service-port>

正常な応答が得られた場合、アプリケーションが他の Pod から到達可能であることが確認されます。

リクエストが失敗した場合は、サイドカープロキシのログを確認し、転送エラーがないかを調べます:

kubectl logs <pod-name> -c istio-proxy