割り当てられたポートとは異なるポートで応答するKubernetesサービス

Dec 16 2020

私はいくつかのサービスを展開しましたが、あるサービスが他のサービスとは異なる動作をしていることがわかりました。8090ポート(内部で8443にマップされます)でリッスンするように構成しましたが、リクエストはポート8080で送信した場合にのみ機能します。これがサービスのyamlファイル(エッセンシャルまで削除)であり、サービスをカプセル化するデプロイがありますとコンテナ

apiVersion: v1
kind: Service
metadata:
  name: uisvc
  namespace: default
  labels:
    helm.sh/chart: foo-1
    app.kubernetes.io/name: foo
    app.kubernetes.io/instance: rb-foo
spec:
  clusterIP: None
  ports:
    - name: http
      port: 8090
      targetPort: 8080
  selector:
    app.kubernetes.io/component: uisvc

ヘルムを取り付けた後、実行するkubectl get svcと、次の出力が得られます

fooaccess       ClusterIP   None         <none>        8888/TCP   119m
fooset          ClusterIP   None         <none>        8080/TCP   119m
foobus          ClusterIP   None         <none>        6379/TCP   119m
uisvc           ClusterIP   None         <none>        8090/TCP   119m

ただし、実行中の他のコンテナの1つにSSHで接続し、8090でcurlリクエストを発行すると、「接続が拒否されました」というメッセージが表示されます。「http:// uisvc:8080」にカールすると、正しい応答が得られます。コンテナは、デフォルトで8080でリッスンするSpring Bootアプリケーションを実行しています。私が思いついた唯一の説明は、この構成ではポート/ targetPortが無視されており、他のポッドが内部のSpringサービスに直接到達していることです。

この動作は正しいですか?なぜ8090でリッスンしないのですか?このように機能させるにはどうすればよいですか?

編集:出力 kubectl describe svc uisvc

Name:              uisvc
Namespace:         default
Labels:            app.kubernetes.io/instance=foo-rba
                   app.kubernetes.io/managed-by=Helm
                   app.kubernetes.io/name=rba
                   helm.sh/chart=rba-1
Annotations:       meta.helm.sh/release-name: foo
                   meta.helm.sh/release-namespace: default
Selector:          app.kubernetes.io/component=uisvc
Type:              ClusterIP
IP:                None
Port:              http  8090/TCP
TargetPort:        8080/TCP
Endpoints:         172.17.0.8:8080
Session Affinity:  None
Events:            <none>

回答

1 thomas Dec 16 2020 at 20:39

を使用して以来、これは予想される動作ですheadless service

ヘッドレスサービスはサービス検出メカニズムに使用されるためDNS A records、単一を返す代わりに、サービスをバックアップする個々のポッドのIPをそれぞれ指すDNS server複数のA recordsサービスを返します。したがって、単純なDNS A recordsルックアップを実行して、サービスの一部であるすべてのポッドのIPを取得します。

以来headless service作成されませんiptablesルールを作成しますが、dns recordsその代わり、あなたはポッドの代わりに、プロキシと直接対話することができます。したがって、解決<servicename:port>すると<podN_IP:port>、接続がポッドに直接接続されます。これらすべてが同じ名前空間にある限り、完全なDNS名で解決することはできません。

いくつかのポッドがある場合、DNSはそれらすべてを提供し、ランダムな順序(またはRRの順序)で配置します。順序は、DNSサーバーの実装と設定によって異なります。

詳細については、以下をご覧ください。

  • サービス-netowrking / headless-services
  • このスタックの質問には、ヘッドレスサービスの仕組みを説明する優れた回答が含まれています