在ACS集群中,Pod的IP地址默认是私有IP地址。但在某些场景(多租户隔离或安全隔离场景等)下,Pod可能需要一个独立的公网IP地址,使得Pod可以独立地与外部网络通信。本文介绍如何通过配置注解为ACS集群中的Pod挂载独立的EIP。
背景信息
一般情况下,Pod访问公网的流量是通过公网NAT网关的方式实现,详情请参见为集群开启公网访问能力。对于Pod的公网入口流量,一般是通过LoadBalancer类型的Service流入。在一些特殊场景中Pod需要独立的公网地址,例如:
动态端口需求:如UDP游戏服务器或RTSP协议需为不同客户端分配随机端口,配置独立IP以避免端口冲突。
避免SNAT限制:Pod调用外部服务时,若服务要求固定IP白名单,共享SNAT的出口IP会被封禁。
直接IP标识需求:需通过独立IP与外部系统建立端到端连接(如实时通信协议)。
使用限制
在使用弹性公网IP(Elastic IP Address,简称EIP)前,请先了解EIP使用限制。
如果您使用自动分配EIP能力,在Pod重建、CNI执行失败等情况下,可能会反复申请、释放EIP资源,这种情况下,可能会触发EIP使用限制。如果您想避免这种情况,可以通过配置Pod Annotation
network.alibabacloud.com/allocated-eip-id
为Pod指定EIP。
操作流程
为Pod挂载EIP,需要为集群安装ack-extend-network-controller组件,您可以在组件管理中进行安装。具体的步骤流程如下:
步骤一:为集群安装或升级插件
开始安装前,请确认是否已经通过Helm或者ACK应用市场安装过组件。如有请先卸载。
登录容器计算服务控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择运维管理 > 组件管理。
在页面搜索框中搜索ack-extend-network-controller,在结果中单击组件卡片右下角的安装。
根据以下内容,在弹出框中进行配置。完成后单击确定。
参数名称
功能说明
enableControllers
配置启用功能:
eip:启用EIP功能。
ipv6gw: 启用IPv6功能。
natgw:启用DNAT网关功能。
eip,ipv6gw功能默认勾选,可以直接启用,无需配置 RAM 权限。
使用natgw需配置RAM权限,请按照配置DNAT所需的RAM权限进行配置。
natGwPool
DNAT配置。
customStatefulWorkloadKinds
自定义有状态容器类型。默认支持K8s StatefulSet和直接创建的Pod。若您有其他容器类型需要使用EIP,请单击+ 添加。
步骤二:启用EIP功能
ACS支持使用Annotation的方式启用EIP功能,通过指定Pod中的annotations
可以创建或者关联EIP到Pod中。关于启用EIP功能注解的详细内容,请参见启用EIP的Annotation介绍。
您可以按需选择自动分配EIP或者指定EIP实例的方式。这两种方式除了使用的Annotation不同之外,在EIP回收策略上也有不同。对于指定EIP实例的方式,删除Pod不会释放EIP实例,而自动分配EIP的方式则默认释放EIP实例。EIP回收策略的详细信息,请参见设置EIP回收策略的Annotation介绍。
自动分配EIP
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 无状态。
在页面右上方,单击使用YAML创建资源。
使用如下YAML示例创建一个名为example的无状态工作负载。
创建成功后,进入名为example的Deployment。点击Pod名称(例如:example-78d17b7xxx-adxxx)进入Pod详情页面,在页面注解部分查看创建出的EIP信息。您也可以点击编辑,在Pod YAML中查看创建出的EIP信息。
完成示例后,删除名为example的Deployment。由于在没有指定Pod EIP实例ID的情况下,Pod EIP的默认回收策略是跟随Pod生命周期。因此当Pod被删除后,EIP会自动释放。
指定EIP实例
准备示例使用的EIP实例,请先申请EIP。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 >有状态。
在页面右上方,单击使用YAML创建资源。
使用如下YAML示例创建一个名为example的有状态工作负载。
创建成功后,进入名为example的StatefulSet。点击Pod名称(例如:example-0)进入Pod详情页面,在页面右侧注解部分查看已绑定的EIP实例信息。您也可以点击编辑,在Pod YAML中查看已绑定的EIP实例信息。
完成示例后,删除名为example的StatefulSet。由于在指定Pod EIP实例ID的情况下,Pod EIP的回收策略是不释放EIP实例。因此当Pod被删除后,EIP不会自动释放。
相关操作
控制器会在Pod IP分配后,为Pod配置EIP地址,在这个过程中Pod可能在EIP绑定成功前进入Ready状态。您可以尝试使用以下方式来解决这类问题,确保Pod在进入服务可用状态之前已完成EIP的绑定,避免可能出现的服务中断或者连接超时等情况。
使用Readiness gates检查EIP绑定状态
当在Pod中配置readinessGates
,并且绑定EIP成功后,控制器会设置Podconditions
。在EIP未绑定前,Pod不会处于Ready状态。
kind: Pod
...
spec:
readinessGates:
- conditionType: "k8s.aliyun.com/eip"
status:
conditions:
- lastProbeTime: "2022-12-12T03:45:48Z"
lastTransitionTime: "2022-12-12T03:45:48Z"
reason: Associate eip succeed
status: "True"
type: k8s.aliyun.com/eip
...
使用initContainers检查EIP绑定状态
为Pod配置initContainers
,在initContainers
中检查EIP是否已经分配成功。您可以参考以下示例配置initContainers
。
apiVersion: v1
kind: Pod
metadata:
name: example
annotations:
network.alibabacloud.com/pod-with-eip: "true"
spec:
containers:
- name: example
image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init
image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/busybox:1.28
command: ['timeout', '-t' ,'60', 'sh','-c', "until grep -E '^k8s.aliyun.com\\/pod-ips=\\S?[0-9]+\\S?' /etc/podinfo/annotations; do echo waiting for annotations; sleep 2; done"]
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
配置DNAT所需的RAM权限
DNAT功能依赖于ack-extend-network-controller访问阿里云OpenAPI来创建资源,您需要在RAM中配置相应的权限。
登录RAM控制台,在左侧导航栏中单击权限策略,单击创建权限策略。
在创建权限策略页面单击脚本编辑,将以下内容粘贴至代码区域的
Statement
中,单击确定,配置策略名称为DNAT-Policy,再次单击确定。{ "Effect": "Allow", "Action": [ "ecs:DescribeNetworkInterfaces", "vpc:DescribeNatGateways", "vpc:DescribeForwardTableEntries", "vpc:CreateForwardEntry", "vpc:DescribeEipAddresses", "vpc:DeleteForwardEntry", "vpc:DescribeRouteTableList", "vpc:DescribeRouteEntryList" ], "Resource": [ "*" ], "Condition": {} }
单击左侧导航栏中的角色,在搜索栏中搜索AliyunCCNECRole,在操作列单击新增授权。
在权限策略部分的搜索栏中搜索并勾选DNAT-Policy,单击确认新增授权。