ゲームや P2P (ピアツーピア) アプリケーションでは、クライアントが Pod に直接アクセスする必要があることがよくあります。各 Pod に Elastic IP アドレス (EIP) を割り当てる代わりに (EIP のクォータによる制限やセキュリティ管理が複雑になるため)、NAT ゲートウェイの DNAT ルールを通じてパブリックエンドポイントを Pod にマッピングします。
前提条件
開始する前に、次の要件を満たしていることを確認してください。
-
Terway をネットワークプラグインとして使用するACK マネージドクラスターまたはACK 専用クラスターを所有していること。
-
クラスターの VPC 内にインターネット NAT ゲートウェイが作成されており、natgw コントローラーによって管理されていること。
-
DNAT ルールが次の 4 つの値をマッピングする仕組みを理解していること:パブリック IP (NAT ゲートウェイ上の EIP)、パブリックポート (portRangeStart から portRangeEnd の範囲から自動割り当てされ、PodDNAT CR に記録される)、プライベートポート (アノテーションで指定される Pod のリスニングポート)、プライベート IP (Pod の IP)。DNAT ルールは、パブリック IP アドレスとポートをプライベート IP アドレスとポートにマッピングします。
制限事項
-
通常の ECS ノードでのみサポートされており、ECI インスタンスではサポートされていません。
-
DNAT エントリは NAT ゲートウェイのクォータによって制限されます。詳細については、「DNAT 機能に関する FAQ」をご参照ください。
仕組み
ack-extend-network-controller は、natgw コントローラーと呼ばれるサブコントローラーを実行します。Pod に DNAT を有効にするアノテーションを付けると、natgw コントローラーは次の処理を実行します。
-
NAT ゲートウェイの EIP プールから EIP を選択します。
-
設定された範囲 (
portRangeStartからportRangeEnd) からパブリックポートを割り当てます。 -
パブリック IP とポートを Pod のプライベート IP とポートにマッピングする DNAT 転送エントリを作成します。
-
割り当て情報を、Pod 名と同じ名前の
PodDNATカスタムリソース (CR) に記録します。
各 DNAT ルールは、パブリック IP アドレス、パブリックポート、プライベート IP アドレス、プライベートポートの 4 つの値をマッピングします。
natgw コントローラーは、設定した範囲からパブリックポートを自動的に割り当てます。同時に公開する Pod の最大数に応じて、範囲のサイズを設定してください。
Pod のアノテーション
DNAT の動作を制御するには、Pod テンプレートに次のアノテーションを適用します。
| アノテーション | 説明 |
|---|---|
k8s.aliyun.com/pod-dnat |
Pod の DNAT を有効にします。有効にするには、true または "" に設定します。無効にするには、DNAT 関連のすべてのアノテーションを削除します。 |
k8s.aliyun.com/pod-dnat-expose-port |
Pod のリスニングポート。複数のポートはカンマで区切ります。例:"80,443" |
k8s.aliyun.com/pod-dnat-expose-protocol |
プロトコル。有効な値:tcp、udp。デフォルト:tcp |
k8s.aliyun.com/pod-dnat-fixed |
Pod が再起動しても同じパブリックポートを維持できるようにします。 |
公開するポートでトラフィックを許可するために、Pod のセキュリティグループにインバウンドルールを追加してください。このルールがないと、DNAT トラフィックはセキュリティグループでドロップされます。
ack-extend-network-controller での DNAT の有効化
ステップ 1:RAM 権限の付与
natgw コントローラーは Alibaba Cloud API を呼び出して NAT 転送エントリを管理します。クラスタータイプに応じて権限を付与してください。
ACK マネージドクラスターまたは ACK 専用クラスター
natgw コントローラーは、クラスターのワーカー RAM ロールを使用します。次の権限を持つカスタムポリシーをワーカー RAM ロールに追加してください。
-
コンテナサービス管理コンソールにログインします。左側メニューで、[クラスター] をクリックします。
-
[クラスター] ページで、お使いのクラスター名をクリックします。左側のナビゲーションペインで、[クラスター情報] をクリックします。
-
[基本情報] タブで、Worker RAM Role の横にあるリンクをクリックします。
-
次の内容でカスタムポリシーを作成してください。詳細については、「ステップ 1: カスタムポリシーを作成する」をご参照ください。
{ "Effect": "Allow", "Action": [ "ecs:DescribeNetworkInterfaces", "vpc:DescribeNatGateways", "vpc:DescribeForwardTableEntries", "vpc:CreateForwardEntry", "vpc:DescribeEipAddresses", "vpc:DeleteForwardEntry", "vpc:DescribeRouteTableList", "vpc:DescribeRouteEntryList" ], "Resource": ["*"], "Condition": {} } -
ポリシーをワーカー RAM ロールにアタッチしてください。詳細については、「ステップ 2: ワーカー RAM ロールに権限を付与する」をご参照ください。
ACK サーバーレスクラスター
同等の権限を持つ RAM ユーザーの AccessKey ペアを作成します。詳細については、「RAM ユーザーの作成」および「カスタムポリシーの作成」をご参照ください。
ステップ 2:natgw コントローラーのインストールと設定
マーケットプレイスから ack-extend-network-controller をインストールし、natgw コントローラーを有効にします。
次のパラメータを使用して natgw コントローラーを設定します。
clusterID: "c11ba338192xxxxxxx" # クラスター ID
regionID: "cn-hangzhou" # リージョン ID
vpcID: "vpc-bp1rkq0zxxxxxx" # VPC ID
enableControllers:
- natgw # natgw コントローラーを有効にする
networkController:
natGwPool:
- natgwId: "<nat-gateway-id>" # インターネット NAT ゲートウェイ ID
zoneId: "<zone-id>" # NAT ゲートウェイのゾーン (例: cn-hangzhou-j)
portRangeStart: 512 # パブリックポート範囲の開始
portRangeEnd: 1024 # パブリックポート範囲の終了
eips:
- "<eip-address>" # NAT ゲートウェイ上の EIP。省略した場合、ゲートウェイ上のすべての EIP が使用されます。
credential: # ワーカー RAM ロールを使用する ACK クラスターの場合、このセクションは省略します。
accessKey: ""
accessSecret: ""
DNAT による Pod の公開
natgw コントローラーが実行されている状態で、Pod にアノテーションを付けると、DNAT エントリが自動的に作成されます。
-
DNAT アノテーションを含む Deployment を適用してください。この例では、nginx Pod のポート 80 を公開します。
apiVersion: apps/v1 kind: Deployment metadata: name: example labels: app: example spec: replicas: 1 selector: matchLabels: app: example template: metadata: labels: app: example annotations: k8s.aliyun.com/pod-dnat: "" k8s.aliyun.com/pod-dnat-expose-port: "80" spec: containers: - name: example image: nginx -
Pod が起動すると、natgw コントローラーは Pod 名と同じ名前の
PodDNATCR を作成します。割り当てを確認します:フィールド 説明 spec.externalIPNAT ゲートウェイのパブリック IP アドレス。このアドレスを使用して、インターネットから Pod にアクセスします。 spec.externalPortportRangeStartからportRangeEndの範囲から割り当てられたパブリックポート。この例では512です。spec.internalIPPod のプライベート IP アドレス。 spec.portMapping[].internalPortPod のリスニングポート。この例では 80です。status.entries[].forwardEntryIdDNAT 転送エントリ ID。 kubectl get poddnats -oyaml出力例:
apiVersion: alibabacloud.com/v1 kind: PodDNAT metadata: creationTimestamp: "20**-09-20T03:26:44Z" finalizers: - natgw-controller generation: 2 name: example-6cd498d7b-9**** namespace: default ownerReferences: - apiVersion: v1 blockOwnerDeletion: true kind: Pod name: example-6cd498d7b-9**** uid: 7af54e1c-eeb7-4fd0-b070-ff99ddbd**** resourceVersion: "357150" uid: 2fad9bb7-cc84-46b4-b6eb-5d15f06c**** spec: eni: eni-xxx externalIP: 114.55.**.** internalIP: 172.16.**.** portMapping: - externalPort: "512" internalPort: "80" protocol: tcp tableId: ngw-xxx vswitch: vsw-xxx zoneID: cn-hangzhou-k status: entries: - externalIP: 114.55.**.** externalPort: "512" forwardEntryId: fwd-xxx internalIP: 172.16.**.** internalPort: "80" ipProtocol: tcpインターネットから
114.55.**.**:512で Pod にアクセスできます。
次のステップ
-
複数のポートを公開するには、
k8s.aliyun.com/pod-dnat-expose-portをカンマ区切りのリストに設定します (例:"80,443")。 -
TCP の代わりに UDP を使用するには、
k8s.aliyun.com/pod-dnat-expose-protocolをudpに設定します。 -
Pod の再起動時に同じパブリックポートを保持するには、
k8s.aliyun.com/pod-dnat-fixedアノテーションを追加します。