In games and peer-to-peer (P2P) applications, clients often need direct pod access. Instead of assigning an elastic IP address (EIP) to each pod—which is limited by EIP quotas and complicates security management—map public endpoints to pods through NAT gateway DNAT rules.
Prerequisites
Before you begin, ensure that you have:
An ACK managed cluster or ACK dedicated cluster with Terway as the network plugin.
An Internet NAT gateway created in the cluster's VPC, managed by the natgw controller.
Familiarity with how DNAT rules map four values: public IP (an EIP on the NAT gateway), public port (auto-allocated from portRangeStart–portRangeEnd and recorded in the PodDNAT CR), private port (the pod listening port from annotations), and private IP (the pod IP). DNAT rules map a public IP address and port to a private IP address and port.
Limitations
Supported on regular ECS nodes only, not ECI instances.
DNAT entries are limited by the NAT gateway quota. See DNAT feature FAQ.
How it works
The ack-extend-network-controller runs a sub-controller called the natgw controller. When you annotate a pod to enable DNAT, the natgw controller:
Selects an EIP from the NAT gateway's EIP pool.
Allocates a public port from the configured range (
portRangeStart–portRangeEnd).Creates a DNAT forward entry mapping the public IP and port to the pod's private IP and port.
Records the allocation in a
PodDNATCustom Resource (CR) named after the pod.
Each DNAT rule maps four values: public IP address, public port, private IP address, and private port.
The natgw controller auto-allocates public ports from your configured range. Size the range for the maximum number of pods to expose simultaneously.
Pod annotations
Apply these annotations to the pod template to control DNAT behavior.
Annotation | Description |
| Enables DNAT for the pod. Set to |
| The pod's listening port. Separate multiple ports with commas. Example: |
| The protocol. Valid values: |
| Enables configuration persistence for a stateful container. |
Add an inbound rule to the pod's security group to allow traffic on the exposed port. Without this rule, DNAT traffic is dropped at the security group.
Enable DNAT in ack-extend-network-controller
The ack-extend-network-controller calls Alibaba Cloud OpenAPIs to create resources. Grant the required RAM permissions, install ack-extend-network-controller from the Marketplace, and use pod annotations to create and associate DNAT entries.
Step 1: Configure RAM permissions
The natgw controller calls Alibaba Cloud APIs to manage NAT forward entries. Grant permissions based on your cluster type.
ACK managed or dedicated cluster
The natgw controller uses the cluster's Worker RAM Role. Add a custom policy with the following permissions to the Worker RAM Role.
Log on to the Container Service Management Console. In the left navigation pane, click Clusters.
On the Clusters page, click your cluster name. In the left navigation pane, click Cluster Information.
On the Basic Information tab, click the link next to Worker RAM Role.
Create a custom policy with the following content. See Step 1: Create a custom policy.
{ "Effect": "Allow", "Action": [ "ecs:DescribeNetworkInterfaces", "vpc:DescribeNatGateways", "vpc:DescribeForwardTableEntries", "vpc:CreateForwardEntry", "vpc:DescribeEipAddresses", "vpc:DeleteForwardEntry", "vpc:DescribeRouteTableList", "vpc:DescribeRouteEntryList" ], "Resource": ["*"], "Condition": {} }Attach the policy to the Worker RAM Role. See Step 2: Grant permissions to the Worker RAM Role.
ACK serverless cluster
Create an AccessKey pair for a RAM user with the equivalent permissions. See Create a RAM user and Create a custom policy.
Step 2: Install and configure the natgw controller
Install ack-extend-network-controller from the Marketplace and enable the natgw controller.
Configure the natgw controller with the following parameters:
clusterID: "c11ba338192xxxxxxx" # Your cluster ID
regionID: "cn-hangzhou" # Your region ID
vpcID: "vpc-bp1rkq0zxxxxxx" # Your VPC ID
enableControllers:
- natgw # Enable the natgw controller
networkController:
natGwPool:
- natgwId: "<nat-gateway-id>" # Internet NAT gateway ID
zoneId: "<zone-id>" # Zone of the NAT gateway, e.g., cn-hangzhou-j
portRangeStart: 512 # Start of the public port range
portRangeEnd: 1024 # End of the public port range
eips:
- "<eip-address>" # EIP on the NAT gateway. If omitted, all EIPs on the gateway are used.
credential: # For ACK clusters using the Worker RAM Role, omit this section.
accessKey: ""
accessSecret: ""Expose a pod with DNAT
After the natgw controller is running, annotate a pod to create a DNAT entry automatically.
Apply a Deployment with DNAT annotations. This example exposes port 80 of an nginx pod.
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: nginxAfter the pod starts, the natgw controller creates a
PodDNATCR named after the pod. View the allocation:Field
Description
spec.externalIPThe NAT gateway's public IP address. Use this address to reach the pod from the internet.
spec.externalPortThe public port allocated from
portRangeStart–portRangeEnd. In this example:512.spec.internalIPThe pod's private IP address.
spec.portMapping[].internalPortThe pod's listening port. In this example:
80.status.entries[].forwardEntryIdThe DNAT forward entry ID.
kubectl get poddnats -oyamlExpected output:
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: tcpThe pod is reachable at
114.55.**.**:512from the internet.
Next steps
To expose multiple ports, set
k8s.aliyun.com/pod-dnat-expose-portto a comma-separated list, for example"80,443".To use UDP instead of TCP, set
k8s.aliyun.com/pod-dnat-expose-protocoltoudp.To retain the same public port across pod restarts, add the
k8s.aliyun.com/pod-dnat-fixedannotation.