EKSのIngressにてターゲットタイプがinstanceの場合にServiceでClusterIPは指定できません

2024.02.29

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

EKSのIngressにてALBのターゲットタイプにipとinstanceがありますが、instanceの場合ServiceではNodePortまたはLoadBalancerタイプを指定する必要があります。

このトラフィックモードを使用するには、Kubernetes サービスで NodePort または「LoadBalancer」 タイプを指定する必要があります。

Amazon EKS でのアプリケーション負荷分散より

ではClusterIPの場合だとどうなるの?ということで実際にClusterIPを指定してみようじゃないか!というのが本記事の目的です。

結論

kubectl applyコマンドではエラーが出ないものの、AWS Load Balancer Controllerにてエラーが出るためALBやターゲットグループが作成されない。

前提

  • EKS Cluster作成済み
  • AWS Load Balancer Controllerを使用できる状態

上記を前提といたします。今回は本題ではないので省略しますが、EKS初心者の方は下記記事による構築がすごくわかりやすかったです。

事前準備

AWS Load Balancer Controllerを使用できる状態まで完了していると、残りは以下のリソース作成が必要となります。

  • Ingress(ターゲットにinstanceを指定)
  • Service(ClusterIPを使用)
  • deployment

サンプルとはなってしまいますが、検証の際に自分が用いたyamlファイルを置いておきます。

Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing  # 外部からのトラフィックを許可
    alb.ingress.kubernetes.io/target-type: instance  # instanceをターゲットに設定
  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
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app  # 作成するリソースの名前
spec:
  replicas: 2  # Deploymentが管理するPodのレプリカ数
  selector:  # 適用するリソースの選択
    matchLabels:  # ラベルの一致を条件とする
      app: nginx
  template:  # 作成するpodの定義
    metadata:  
      labels:
        app: nginx
    spec:
      containers:  # pod内のコンテナの仕様
        - name: nginx  # コンテナの名前
          image: public.ecr.aws/nginx/nginx:1.23  # コンテナイメージ
          ports:  # コンテナが公開するポート(内部向け)
            - name: tcp
              containerPort: 80

やってみる

上記のファイルをapplyします。

k apply -f ingress.yaml -f service.yaml -f deployment.yaml        
ingress.networking.k8s.io/sample-ingress created
service/sample-service created
deployment.apps/sample-app created

すると以下のように特にエラーが発生せず、成功してしまいました(この時点でエラーが出ると想定していました)。

「ってことはALBが作成されている?」ということで続けてALBの設定を確認しにいきます。

しばらく待ちましたが、ALBもターゲットグループも作成されていないようです。

つまりAWS Load Balancer Controller側でALB等の作成に失敗しているのでしょうか?

AWS Load Balancer Controller(pod)のログを確認します。

k logs aws-load-balancer-controller-XXXX -n kube-system

ターゲットの作成で失敗している旨が確認できました!

{"level":"error","ts":"2024-02-29T13:54:24Z","msg":"Reconciler error","controller":"ingress","object":{"name":"sample-ingress","namespace":"default"},"namespace":"default","name":"sample-ingress","reconcileID":"XXXX","error":"InvalidParameter: 1 validation error(s) found.\n- minimum field value of 1, CreateTargetGroupInput.Port.\n"}

まとめ

Ingressのターゲットにinstanceを指定して、ServiceにClusterIPは矛盾しているのでkubectlコマンド時点で失敗すると思いきや、AWS Load Balancer Controller側のリソース作成時にエラーが出るという挙動でした。

また一つAWS Load Balancer Controllerの動きに詳しくなれてよかったです。