IPモード
前述のように、作成したNLBは「インスタンスモード」で動作しています。インスタンスターゲットモードはAWS EC2インスタンス上で実行されているPodをサポートしています。このモードでは、AWS NLBはインスタンスにトラフィックを送信し、個々のワーカーノード上のkube-proxyがKubernetesクラスター内の1つ以上のワーカーノードを介してPodにトラフィックを転送します。
AWS Load Balancer Controllerは、「IPモード」で動作するNLBの作成もサポートしています。このモードでは、AWS NLBはKubernetesクラスター内のワーカーノードを経由する余分なネットワークホップを排除して、Serviceの背後にあるKubernetes Podに直接トラフィックを送信します。IPターゲットモードは、AWS EC2インスタンスとAWS Fargateの両方で実行されているPodをサポートしています。

上の図は2つのモードを並べて比較しています。Service、Network Load Balancer、およびポート80のTCPリスナーは両方で同一です。変更されるのはロードバランサーのターゲットグループに登録される対象だけです。
インスタンスモードでは、ターゲットグループはKubernetesがServiceに割り当てたNodePort上のEC2ワーカーノードを登録します。したがって、接続はまずノードに到達し、そのノード上のkube-proxyがui Podに中継します。接続を受信したノードがui Podを実行していない場合、kube-proxyは実行しているノードに転送し、2つ目のネットワークホップが追加されます。
IPモードでは、ターゲットグループはPod IPアドレスを登録するため、ロードバランサーはui Podに直接接続を開き、kube-proxyはデータパスに含まれません。これはAmazon VPC CNIがすべてのPodにファーストクラスでルーティング可能なVPC IPアドレスを付与するため機能します。
NLBをIPターゲットモードで構成したい理由はいくつかあります:
- 受信接続のためのより効率的なネットワークパスを作成し、EC2ワーカーノード上の
kube-proxyをバイパスします externalTrafficPolicyやその様々な構成オプションのトレードオフなどの側面を考慮する必要がなくなります- アプリケーションがEC2ではなくFargateで実行されている場合
NLBの再構成
NLBをIPモードを使用するように再構成し、インフラストラクチャにどのような影響があるかを見てみましょう。
これはServiceを再構成するために適用するパッチです:
- Kustomize Patch
- Service/ui-nlb
- Diff
apiVersion: v1
kind: Service
metadata:
name: ui-nlb
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
namespace: ui
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/load-balancer-source-ranges: $INBOUND_CIDRS
name: ui-nlb
namespace: ui
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app.kubernetes.io/component: service
app.kubernetes.io/instance: ui
app.kubernetes.io/name: ui
type: LoadBalancer
apiVersion: v1
kind: Service
metadata:
annotations:
- service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
+ service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/load-balancer-source-ranges: $INBOUND_CIDRS
name: ui-nlb
kustomizeでマニフェストを適用します:
ロードバランサーの構成が更新されるまで数分かかります。以下のコマンドを実行して、アノテーションが更新されたことを確認します:
...
Annotations: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
...
以前と同じURLを使用してアプリケーションにアクセスできるはずですが、NLBは現在IPモードを使用してアプリケーションを公開しています。
{"TargetHealthDescriptions": [
{ "Target": {"Id": "10.42.180.183",
"Port": 8080,
"AvailabilityZone": "us-west-2a"
},
"HealthCheckPort": "8080",
"TargetHealth": {"State": "initial",
"Reason": "Elb.RegistrationInProgress",
"Description": "Target registration is in progress"
}
}
]
}
前のセクションで観察した3つのターゲットから、たった1つのターゲットに変わっていることに注目してください。なぜでしょうか?EKSクラスター内のEC2インスタンスを登録する代わりに、ロードバランサーコントローラーは現在個々のPodを登録し、トラフィックを直接送信しています。これはAWS VPC CNIとPodそれぞれがファーストクラスのVPC IPアドレスを持つという事実を活用しています。
uiコンポーネントを3つのレプリカにスケールアップして、何が起こるか見てみましょう:
ロードバランサーのターゲットを再度確認します:
{"TargetHealthDescriptions": [
{ "Target": {"Id": "10.42.180.181",
"Port": 8080,
"AvailabilityZone": "us-west-2c"
},
"HealthCheckPort": "8080",
"TargetHealth": {"State": "initial",
"Reason": "Elb.RegistrationInProgress",
"Description": "Target registration is in progress"
}
},
{ "Target": {"Id": "10.42.140.129",
"Port": 8080,
"AvailabilityZone": "us-west-2a"
},
"HealthCheckPort": "8080",
"TargetHealth": {"State": "healthy"
}
},
{ "Target": {"Id": "10.42.105.38",
"Port": 8080,
"AvailabilityZone": "us-west-2a"
},
"HealthCheckPort": "8080",
"TargetHealth": {"State": "initial",
"Reason": "Elb.RegistrationInProgress",
"Description": "Target registration is in progress"
}
}
]
}
予想通り、ui Deploymentのレプリカ数に一致する3つのターゲットが表示されるようになりました。
アプリケーションが同じように機能することを確認したい場合は、次のコマンドを実行してください。それ以外の場合は次のモジュールに進むことができます。