在ACS集群中,Pod的IP地址一般是私网的IP地址。但在某些场景下,Pod可能需要一个独立的公网IP地址,使得Pod可以独立地与外部网络通信。本文介绍如何为ACS集群中的Pod挂载独立的公网EIP。
前提条件
已创建ACS集群。具体操作,请参见创建ACS集群。
背景信息
一般情况下,Pod访问公网的流量是通过“外部SNAT+EIP”的方式实现,详情请参见为集群开启公网访问能力。对于Pod的公网入口流量,一般是通过LoadBalancer类型的Service流入。在一些特殊场景中Pod需要独立的公网地址,例如:
Pod的对外映射端口是随机的,一般常见于UDP(User Datagram Protocol)的游戏服务器或电话会议等。例如RTSP协议,对不同的客户端使用不同的端口。
公网流量存在出口资源争抢,Pod需要独立的公网出口。
使用限制
在使用弹性公网IP(Elastic IP Address,简称EIP)前,请先了解EIP的使用限制。详细信息,请参见使用限制。
如果您使用自动分配EIP能力,在Pod重建、CNI执行失败等情况下,可能会反复申请、释放EIP资源,这种情况下,可能会触发EIP使用限制。如果您想避免这种情况,可以通过配置Pod Annotation
network.alibabacloud.com/allocated-eip-id
为Pod指定EIP。
步骤一:配置挂载EIP所需的RAM权限
步骤二:为集群安装或升级插件
要使用ack-extend-network-controller插件,请在ACK应用市场或ACS集群内应用入口中安装ack-extend-network-controller插件,并开启EIP控制器。
ACS集群可以在ACK控制台中查看和管理。详细信息,请参见产品简介。
通过ACS集群内Helm入口安装
登录容器计算服务控制台,在左侧导航栏选择集群。
在集群页面,单击目标集群ID,然后在左侧导航栏,选择
。在Helm页面,单击创建。参考如下信息完成基本信息配置。
参数
示例值
应用名
ack-extend-network-controller
命名空间
kube-system
来源
默认为应用目录。
Chart
搜索框:搜索ack-extend-network-controller。
单击下一步。
在参数配置页面,选择Chart 版本。参考如下表格,配置必填参数,然后单击确定。
说明ACS集群仅支持安装和使用版本>=v0.9.3组件。
参数说明如下所示:
配置参数
类型
必填
描述
enableControllers
[]string
是
删除
eip
的默认注释以启用EIP功能。vpcid
string
是
EIP 关联的VPC ID。
credential.accessKey
string
是
挂载EIP所需权限账户的AK。
credential.accessSecret
string
是
挂载EIP所需权限账户的SK。
networkController.eipController.maxConcurrentReconciles
int
否
EIP控制器并发数量。
networkController.eipController.garbageCollectionPeriodInMinutes
int
否
EIP控制器清理固定EIP的周期。
customStatefulWorkloadKinds
[]string
否
自定义有状态控制器Kind。
返回Helm页面,可以看到新的ack-extend-network-controller组件已经成功部署。
通过ACK应用市场安装
登录容器服务管理控制台,在左侧导航栏选择 。
在应用市场页面的搜索栏中输入
ack-extend-network-controller
,然后单击目标应用。在应用详情页面,单击右上角的一键部署。
在创建面板中,选择集群和命名空间,然后单击下一步。
在参数配置页面,选择版本号并设置相应的参数,然后单击确定。
说明ACS集群仅支持安装和使用版本>=v0.9.2组件。
参数说明如下所示:
配置参数
类型
必填
描述
enableControllers
[]string
是
配置
eip
以启用EIP功能。vpcid
string
是
EIP 关联的VPC ID
credential.accessKey
string
是
挂载EIP所需权限账户的AK。
credential.accessSecret
string
是
挂载EIP所需权限账户的SK。
networkController.eipController.maxConcurrentReconciles
int
否
EIP控制器并发数量。
networkController.eipController.garbageCollectionPeriodInMinutes
int
否
EIP控制器清理固定EIP的周期。
customStatefulWorkloadKinds
[]string
否
自定义有状态控制器Kind。
参数示例如下:
clusterID: "c11ba338192xxxxxxx" regionID: "cn-hangzhou" vpcID: "vpc-bp1rkq0zxxxxxx" enableVirtualNode: true affinity: null enableControllers: - eip networkController: eipController: maxConcurrentReconciles: 10 garbageCollectionPeriodInMinutes: 1 customStatefulWorkloadKinds: - foo credential: accessKey: "xxxxxxxxxxxx" accessSecret: "xxxxxxxxxxxxxx"
如需更新ack-extend-network-controller插件的版本和参数,请参见应用市场。
步骤三:启用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的Deployment控制器。
创建成功后,进入名为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的StatefulSet控制器。
创建成功后,进入名为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