在游戏、P2P等场景中需要在客户端直接访问Pod,传统方式下通过为Pod分配EIP访问Pod。但是这种方式存在一些问题,比如EIP数量限制、安全管理等。本文介绍如何使用公网NAT网关的DNAT方式暴露访问入口给Pod,这种方式只需在NAT网关上配置EIP,从而节省EIP数量。
索引
前提条件
- 已创建ACK托管版或专有版集群,集群网络插件选择Terway。详细信息,请参见创建Kubernetes托管版集群、创建Kubernetes专有版集群。
- 您需要在VPC中创建NAT网关后再使用natgw控制器,如何创建NAT网关请参见创建和管理公网NAT网关实例。
- DNAT规则需要公网 IP、公网端口、私网端口、私网IP来建立映射。关于DNAT原理请参见通过公网NAT网关DNAT功能实现ECS对外提供服务。
- 公网IP: 为公网NAT网关上配置的EIP。
- 公网端口:为natgw控制器配置文件中配置的
portRangeStart
、portRangeEnd
范围,由natgw控制器自动分配,分配后信息在Pod同名CRpoddnats.alibabacloud.com
中记录。 - 私网端口:为Pod Annotations中配置的Pod监听的端口。
- 私网IP: 为Pod IP。
使用限制
- 不支持ASK集群、ACK边缘托管版和ASI 集群。
- 配置条目数受限于NAT网关能力,使用约束请参见DNAT功能FAQ。
Pod配置
您可以使用以下Pod Annotations配置:
Pod Annotations | Value |
---|---|
k8s.aliyun.com/pod-dnat | 为Pod开启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的端口。
在ack-extend-network-controller中启用DNAT功能
ack-extend-network-controller需要访问阿里云OpenAPI来创建资源,您需要在RAM中配置相应的权限,然后在应用市场中安装ack-extend-network-controller,并通过注解为指定Pod创建和关联DNAT 。
步骤一:配置DNAT所需的RAM权限
- 对于ACK集群:
- 登录容器服务管理控制台,在左侧导航栏单击集群。
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息。
- 在集群信息页面,单击集群资源页签,然后单击Worker RAM角色右侧链接。
- 在RAM角色页面的权限管理页签,在权限策略列,单击目标权限策略名称。
- 在权限策略页面的策略内容页签,单击修改策略内容,然后在脚本编辑页签下,将以下策略内容增加到脚本中。
{ "Effect": "Allow", "Action": [ "ecs:DescribeNetworkInterfaces", "vpc:DescribeNatGateways", "vpc:DescribeForwardTableEntries", "vpc:CreateForwardEntry", "vpc:DescribeEipAddresses", "vpc:DeleteForwardEntry", "vpc:DescribeRouteTableList", "vpc:DescribeRouteEntryList" ], "Resource": [ "*" ], "Condition": {} }
- 策略内容添加完成后,单击继续编辑基本信息,然后单击确定。
- 对于ASK集群:
步骤二:为ack-extend-network-controller组件开启natgw控制器
安装ack-extend-network-controller组件,并且开启natgw控制器。您可以在ACK应用市场中选择安装,请参见应用市场。
natgw控制器配置参数如下。
clusterID: "c11ba338192xxxxxxx" # 请按实际情况填写。
regionID: "cn-hangzhou" # 请按实际情况填写。
vpcID: "vpc-bp1rkq0zxxxxxx" # 请按实际情况填写。
enableControllers:
- natgw # 启用DNAT。
networkController:
natGwPool:
- natgwId: "< nat gateway id. >" # nat 公网网关ID。
zoneId: "< nat gateway zone id. cn-hangzhou-j >" # nat 公网网关可用区ID。
portRangeStart: 512 # 起始端口。
portRangeEnd: 1024 # 结束端口。
eips:
- "<auto config all nat gateway eips if not config. 0.0.0.0 >" # 使用公网网关EIP,如不设置,则使用网关上配置的全部EIP。
credential: # 使用AK/SK,ACK集群推荐使用RamRole模式配置。
accessKey: ""
accessSecret: ""
使用自定义资源跟踪配置
创建Pod后,控制器会创建Pod同名的自定义资源。以下示例将为Pod配置DNAT规则,将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
执行如下命令,读取poddnats.alibabacloud.com
中的分配信息来获取Pod的外部地址和端口。
kubectl get poddnats -oyaml example-6cd498d7b-9****
预期输出:
apiVersion: alibabacloud.com/v1
kind: PodDNAT
metadata:
creationTimestamp: "2022-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
其中
- externalPort:是公网端口,由控制器在端口范围中分配。
- externalIP:是NAT网关的公网IP,也是外部访问的地址。