【EKS小ネタ】AWS Load Balancer Controller(LBC)で構築したIngress(ALB)の接続先として正しくServiceが設定されていないとターゲットグループの設定がされない【Backend service does not exist】

2024.02.21

こんにちはカスタマーソリューション部のこーへいです!

今回小ネタですが、AWS Load Balancer Controller(以下LBC)で構築したIngress(ALB)のリスナールールにターゲットグループが紐づいておらず困ったので、対処法を備忘録として残しておきます。

「Backend service does not exist」と悲しみのレスポンスが返ってきました。

結論

Ingressの接続先のServiceが正しく存在するか確認しましょう

  • Ingressの中で指定したService名が正しいのか確認(今回はこちらでした)
  • そもそもServiceを建て忘れていないか確認

解説

        backend:
          service:
            name: sample-sample-service  # 接続するService
            port:
              number: 80

上記はingress.yamlの一部(全体版は後ほど折りたたみで載せています)ですが、接続するserviceのnameにて「sample-sample-service(実際は別の値)」を指定しています。

kind: Service
metadata:
  name: sample-service

一方こちらはservice.yamlの一部で、metadataにて「sample-service」と名付けられています。

つまりingress.yamlで指定したservice名にて対象のものがなかったため(今回は間違った値を指定したため)、ALBに代理アクション(503レスポンス)が設定されていたわけです。

Ingress.yamlの全体版
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing  # 外部からのトラフィックを許可
    alb.ingress.kubernetes.io/target-type: ip  # Ipをターゲットに設定
  name: sample-ingress
spec:
  ingressClassName: alb  # ingressのクラス名を定義
  rules:
  - http:  # httpルール
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: sample-service  # 接続するService
            port:
              number: 80
service.yamlの全体版
apiVersion: v1
kind: Service
metadata:
  name: sample-service
spec:
  ports:  # Podへのアクセスに使用するport
    - port: 80
      targetPort: 80
      protocol: TCP
  type: ClusterIP  # クラスター内Pod通信
  selector:
    app: nginx

コード参考:【Amazon EKS】第二回 ALBを利用してNginx Podに負荷分散設定をしてみた!

おまけ

これで終わりはちょっと寂しいので、Ingress周りの知識を軽くさらって(推測して)いきます。

Ingressのターゲットタイプにてipを指定した場合の通信について

metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing  # 外部からのトラフィックを許可
    alb.ingress.kubernetes.io/target-type: ip  # Ipをターゲットに設定

上記は先ほど載せたingress.yamlファイルの一部記述ですが、ターゲットタイプにipが指定されています。

これはAWSのターゲットグループにpodが直接登録(ちなみにinstanceを指定した場合はnodeが登録)されるようになる設定です。

Pods を ALB のターゲットとして登録します。ALB に到達するトラフィックは、サービスの Pods に直接ルーティングされます。

Amazon EKS でのアプリケーション負荷分散においてトラフィックの流れについて記述がされています。

Ingressは通常Service(Nodeportが多い)を経由する

Ingressより

上記図の通り、基本的にIngressはServiceを通じてpodにトラフィックが流れます。

一方でIngress(ALB)のターゲットタイプにてipを選択した場合は、先述通りpodに直接トラフィックが流れる仕組みになっています。

ターゲットグループに登録されるpodはおそらくLBCがコントロールしている

ここからはドキュメントから記述を探し当てることができなかったため推測も混じります(見つけ次第追記します)が、実際にトラフィックがIngressからServiceを経由するかは設定によって異なります。

例えばALBの場合だと、ターゲットタイプにinstanceを指定した場合Service(Nodeport等)を経由する一方で、ipの場合は直接podにトラフィックが流れます。

しかしipの場合はService(今回はClusterIP)を指定が必要ないかと言われたらそうではなく、Serviceの指定がないと本記事の通りALBのリスナールールにて適切なターゲットグループが紐づけられません。

How AWS Load Balancer controller worksより

ALBの場合、IngressリソースをK8s上でapplyすると自動的にALBが作成されますが、その作成を担っているのがpodとして存在するLBC(AWS Load Balancer Controller)です(これは事実)。

The controller watches for ingress events from the API server. When it finds ingress resources that satisfy its requirements, it begins the creation of AWS resources.

How AWS Load Balancer controller worksより

その上で以下を推測したというのが今回の結論です。

  • LBCはIngress側で指定したServiceを確認し、Service側で指定されたpodをターゲットグループに登録する

まとめ

前半パートは小ネタの回答、後半パートは周辺知識のメモのブログ記事となりました。

後半部分に関しては大きく間違ってはいないだろうと思いつつも、公式の記述を見つけ次第追記させていただきます。

参考

  • https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/alb-ingress.html
  • https://aws.github.io/aws-eks-best-practices/networking/loadbalancing/loadbalancing/
  • https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/