为Pod挂载独立公网EIP
Pod的IP地址一般是私网的IP地址,但是在ACK的Terway网络模式中,某些场景下的Pod需要独立的公网IP地址。本文介绍如何为Terway网络中的Pod挂载独立的公网EIP。
前提条件
已创建以下集群中的一个或多个。创建集群,请参见创建Kubernetes托管版集群、创建Kubernetes专有版集群、创建ASK集群。
ACK托管版集群
说明集群的网络插件必须为terway-eniip或terway-eni。
ACK专有版集群
说明集群的网络插件必须为terway-eniip或terway-eni。
ASK集群
背景信息
一般情况下,Terway网络模式中的Pod访问公网的流量是通过主机SNAT(Source Network Address Translation)或者外部SNAT通过EIP而实现,对于Pod的公网入口流量一般是通过LoadBalancer类型的Service流入。在有的场景中Pod需要独立的公网地址,例如:
Pod的对外映射端口是随机的,一般常见于UDP(User Datagram Protocol)的游戏服务器或电话会议等。例如RTSP协议,对不同的客户端使用不同的端口。
Pod访问公网流量存在争抢,Pod需要独立的公网出口。
关于ACK集群Terway网络模式的更多信息,请参见使用Terway网络插件。
组件差异对比
以下两个组件均支持为Pod挂载公网EIP能力,组件的差异对比如下。
您不能同时启用ack-extend-network-controller与Terway的EIP配置能力。
- | ack-extend-network-controller | terway |
支持的集群类型 |
|
|
固定EIP | 支持 | 不支持 |
配置阶段 | Pod IP分配后,控制器将为Pod分配、绑定EIP地址。 | 在CNI执行过程中分配、绑定EIP地址。 |
开启方式 | 可以在ACK应用市场中安装ack-extend-network-controller组件,并且开启EIP控制器。详细信息,请参见应用市场。 | Terway的EIP配置方法,请参见下文在Terway中启用EIP功能。 |
支持版本 | v0.2.0及以上 | v1.0.10.280-gdc2cb6c-aliyun及以上 |
使用限制
不支持ACK边缘托管版集群。
在使用弹性公网IP(Elastic IP Address,简称EIP)前,请先了解EIP的使用限制。详细信息,请参见使用限制。
如果您使用自动分配EIP能力,在Pod重建、CNI执行失败等情况下,可能会反复申请、释放EIP资源,这种情况下,可能会触发EIP使用限制。如果您想避免这种情况,可以通过配置Pod Annotation
k8s.aliyun.com/pod-eip-instanceid
为Pod指定EIP。
Pod配置
指定EIP实例ID
此模式不会对EIP实例配置进行修改,仅绑定EIP到指定Pod。不支持多副本类型的控制器,请确保EIP实例仅有一个Pod引用。
Pod Annotations | value |
k8s.aliyun.com/pod-eip-instanceid | 使用指定EIP,请填写EIP实例ID, 例如:epi-bp14qxxxxxxx。 |
k8s.aliyun.com/eci-eip-instanceid(兼容) |
自动分配EIP
Pod Annotations | value |
k8s.aliyun.com/pod-with-eip | 是否自动创建并绑定EIP。取值:
|
k8s.aliyun.com/eci-with-eip(兼容) | |
k8s.aliyun.com/eip-bandwidth | EIP峰值带宽。单位:Mbps。更多信息,请参见申请EIP。 |
k8s.aliyun.com/eip-internet-charge-type | EIP的计费方式。取值:
更多信息,请参见申请EIP。 说明
|
k8s.aliyun.com/eip-charge-type(兼容) | |
k8s.aliyun.com/eip-common-bandwidth-package-id | 绑定已有的共享带宽包。 说明 使用此Annotation,需要terway组件版本为v1.2.3及以上;对ack-extend-network-controller组件版本无限制。 |
k8s.aliyun.com/eip-isp | EIP的线路类型。取值:
更多信息,请参见申请EIP。 说明 使用此Annotation,需要terway组件版本为v1.2.3及以上;对ack-extend-network-controller组件版本无限制。 |
k8s.aliyun.com/eip-public-ip-address-pool-id | EIP地址池。 更多信息,请参见申请EIP。 说明 此Annotation仅在ack-extend-network-controller中支持。 |
k8s.aliyun.com/eip-resource-group-id | EIP资源组。 更多信息,请参见申请EIP。 说明 此Annotation仅ack-extend-network-controller组件版本为v0.4.0及以上支持使用。 |
设置固定EIP
固定EIP可以保证Pod重建后依然使用之前的EIP地址,仅在ack-extend-network-controller中支持。该策略可与自动分配EIP能力结合,用于有状态应用的固定EIP。
此能力对有状态类型副本控制器适用,您无法为无状态类型控制器使用。
指定EIP实例ID,不会释放EIP实例。
Pod Annotations | value |
k8s.aliyun.com/pod-eip-release-strategy | podEIP回收策略。取值:
|
控制Pod Ready状态
控制器会在Pod IP分配后,为Pod配置EIP地址,Pod Ready状态可能早于EIP绑定成功时间。您可以尝试使用下面的方式,控制Pod Ready状态。
为Pod配置Readiness gates
为Pod配置Readiness gates仅在ack-extend-network-controller中支持。
当在Pod中配置完readinessGates,并且绑定EIP成功后,控制器会设置Pod conditions 。在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
...
为Pod配置init container
为Pod配置init container,在init container中检查EIP是否已经分配成功。您可以参考以下示例配置init container。
apiVersion: v1
kind: Pod
metadata:
name: example
annotations:
k8s.aliyun.com/pod-with-eip: "true"
spec:
containers:
- name: example
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init
image: 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
在ack-extend-network-controller中启用EIP功能
ack-extend-network-controller需要访问阿里云OpenAPI来创建资源,您需要在RAM中配置相应的权限。 然后再在应用市场中安装ack-extend-network-controller,并通过注解为指定Pod创建和关联EIP 。
步骤一:配置EIP所需的 RAM 权限
对于ACK集群,按照如下步骤操作。
- 登录容器服务管理控制台,在左侧导航栏单击集群。
在集群列表页面中,单击目标集群名称。
在集群信息页面,单击集群资源页签,单击Worker RAM角色右侧链接。
在RAM角色基本信息的权限管理页签,单击目标权限策略名称。
单击修改策略内容,在策略内容区域增加如下内容,单击确定。
{ "Effect": "Allow", "Action": [ "vpc:DescribeVSwitches", "vpc:AllocateEipAddress", "vpc:AllocateEipAddressPro", "vpc:DescribeEipAddresses", "vpc:AssociateEipAddress", "vpc:UnassociateEipAddress", "vpc:ReleaseEipAddress", "vpc:AddCommonBandwidthPackageIp", "vpc:RemoveCommonBandwidthPackageIp", "vpc:TagResources", "ecs:DescribeNetworkInterfaces" ], "Resource": [ "*" ], "Condition": {} }
步骤二:在应用市场安装ack-extend-network-controller
在ACK应用市场中安装ack-extend-network-controller。详细信息,请参见应用市场。
控制器配置参数如下:
clusterID: "c11ba338192xxxxxxx" # 请按实际情况填写。
regionID: "cn-hangzhou" # 请按实际情况填写。
vpcID: "vpc-bp1rkq0zxxxxxx" # 请按实际情况填写。
enableControllers:
- eip # 启用EIP。
networkController:
eipController:
maxConcurrentReconciles: 1 # 控制器并发数量。
garbageCollectionPeriodInMinutes: 1 # 固定EIP清理周期。
customStatefulWorkloadKinds: # 自定义的有状态控制器,默认支持StatefulSet。
- foo
credential: # 使用AK/SK,对ACK集群,推荐使用RamRole模式配置。
accessKey: ""
accessSecret: ""
步骤三:通过注解为指定Pod创建和关联EIP
通过指定Pod中的Annotations可以创建或者关联EIP到此Pod中。注解内容,请参见上文Pod配置。
示例
使用如下示例创建一个Deployment控制器,从EIP地址池
pippool-bp1bbpq1jjncxxxx
为每个Pod自动分配一个EIP实例,实例带宽为5 Mbps。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-with-eip: "true" k8s.aliyun.com/eip-bandwidth: "5" k8s.aliyun.com/eip-public-ip-address-pool-id: "pippool-bp1bbpq1jjncxxxx" spec: readinessGates: - conditionType: "k8s.aliyun.com/eip" containers: - name: example image: nginx
Pod创建成功后,访问Pod同名的资源
podeips.alibabacloud.com
,跟踪分配的EIP信息。apiVersion: alibabacloud.com/v1beta1 kind: PodEIP metadata: annotations: k8s.aliyun.com/eip-controller: ack-extend-network-controller creationTimestamp: "2022-11-18T07:46:18Z" finalizers: - podeip-controller.alibabacloud.com/finalizer generation: 1 name: example-xxxx-xxxx namespace: default resourceVersion: "597256" uid: 2fd39250-7cf0-4b6e-a581-xxxxxx spec: allocationID: eip-bp1rcs9ilupxxxxx allocationType: releaseStrategy: Follow type: Auto status: bandwidth: "5" eipAddress: 112.xx.xx.xx internetChargeType: PayByBandwidth isp: BGP networkInterfaceID: eni-bp14qrdskvxxxxx podLastSeen: "2022-11-18T08:42:29Z" privateIPAddress: 172.18.XX.XX publicIpAddressPoolID: pippool-bp1bbpq1jjncxxxx resourceGroupID: rg-acfm2omxxxxx status: InUse
使用如下示例创建一个StatefulSet资源,创建两个Pod,并为每个Pod自动分配一个EIP实例,并设置回收策略为Pod删除10分钟后删除PodEIP。
apiVersion: apps/v1 kind: StatefulSet metadata: name: example labels: app: example spec: serviceName: "example" replicas: 2 selector: matchLabels: app: example template: metadata: labels: app: example annotations: k8s.aliyun.com/pod-with-eip: "true" k8s.aliyun.com/pod-eip-release-strategy: "10m" spec: containers: - name: example image: nginx
Pod创建成功后,访问Pod同名的资源
podeips.alibabacloud.com
,跟踪分配的EIP信息。apiVersion: v1 items: - apiVersion: alibabacloud.com/v1beta1 kind: PodEIP metadata: annotations: k8s.aliyun.com/eip-controller: ack-extend-network-controller creationTimestamp: "2022-12-01T02:56:27Z" finalizers: - podeip-controller.alibabacloud.com/finalizer generation: 1 name: example-0 namespace: default resourceVersion: "393589" uid: c4a69543-ef01-4596-a1ff-d3199624**** spec: allocationID: eip-bp1tqnbtwxxxxx allocationType: releaseAfter: 10m releaseStrategy: TTL type: Auto status: eipAddress: 121.40.XX.XX internetChargeType: PayByBandwidth isp: BGP networkInterfaceID: eni-bp1d9uh1tphxxxx podLastSeen: "2022-12-01T02:57:05Z" privateIPAddress: 172.16.XX.XX resourceGroupID: rg-acfm2om7xxxxx status: InUse - apiVersion: alibabacloud.com/v1beta1 kind: PodEIP metadata: annotations: k8s.aliyun.com/eip-controller: ack-extend-network-controller creationTimestamp: "2022-12-01T02:56:42Z" finalizers: - podeip-controller.alibabacloud.com/finalizer generation: 1 name: example-1 namespace: default resourceVersion: "393590" uid: 3a4fbc70-1bed-4e32-8961-da84768e**** spec: allocationID: eip-bp1sdp3axxxx allocationType: releaseAfter: 10m releaseStrategy: TTL type: Auto status: eipAddress: 121.199.XX.XX internetChargeType: PayByBandwidth isp: BGP networkInterfaceID: eni-bp1d9uh1tphxxxx podLastSeen: "2022-12-01T02:57:05Z" privateIPAddress: 172.16.1.145 resourceGroupID: rg-acfm2omxxxxxx status: InUse kind: List metadata: resourceVersion: ""
Pod删除后,PodEIP CR会保持10分钟后再删除,在此期间创建的同名称Pod,将继续使用相应的EIP。
在Terway中启用EIP功能
步骤一:升级Terway组件至最新版本
您需升级Terway组件到支持EIP功能的版本。关于升级Terway组件的具体步骤,请参见管理组件。
目前Terway组件v1.0.10.280-gdc2cb6c-aliyun
及以上版本支持EIP功能。建议您升级Terway组件至最新版本。
步骤二:为Terway部署EIP相关的配置和权限
Terway为Pod配置EIP需要EIP相关的权限去申请和配置EIP,所以需要部署额外的配置和权限。
为Terway模式的RAM角色配置EIP相关权限。
对于专有版集群或者2020年06月份之前创建的托管版集群,Terway的权限是通过Worker节点上的RAM角色进行配置。
- 登录容器服务管理控制台,在左侧导航栏单击集群。
在集群列表页面中,单击目标集群名称。然后单击集群资源页签,单击Worker RAM角色链接。
在权限管理页签,单击目标授权策略名称,进入授权策略详情页面。
单击修改策略内容,从右侧滑出侧边栏修改策略内容面板,在策略内容的
Action
字段中补充以下策略,然后单击确定。"vpc:DescribeVSwitches", "vpc:AllocateEipAddress", "vpc:DescribeEipAddresses", "vpc:AssociateEipAddress", "vpc:UnassociateEipAddress", "vpc:ReleaseEipAddress", "vpc:AddCommonBandwidthPackageIp", "vpc:RemoveCommonBandwidthPackageIp"
说明在策略内容的任意一个
Action
字段的最后一行补充英文半角逗号(,)。
对于Pro托管版集群,或者是2020年6月份及之后创建的标准托管版集群,Terway的权限是通过RAM角色AliyunCSManagedNetworkRole进行配置。您需要在RAM控制台中为这个角色添加EIP相关权限。
在RAM角色AliyunCSManagedNetworkRole页面的RAM角色列表中,单击目标授权策略名称右侧的添加权限。
在添加权限面板的选择权限区域,单击+新建权限策略创建自定义策略。
关于如何创建自定义策略,请参见创建自定义权限策略。
在您创建的自定义权限策略中添加以下权限。
关于如何修改自定义策略内容,请参见改自定义权限策略内容和备注。
"vpc:DescribeVSwitches", "vpc:AllocateEipAddress", "vpc:DescribeEipAddresses", "vpc:AssociateEipAddress", "vpc:UnassociateEipAddress", "vpc:ReleaseEipAddress", "vpc:AddCommonBandwidthPackageIp", "vpc:RemoveCommonBandwidthPackageIp"
部署Terway配置以支持EIP功能。
执行以下命令修改Terway的配置ConfigMap。
kubectl edit cm eni-config -n kube-system
在eni_conf中增加以下内容。
"enable_eip_pool": "true"
说明如果您希望在指定EIP的时候能够强制解绑之前的实例,还需要在eni_conf中增加参数"allow_eip_rob": "true"。
修改完成后,按Esc键,输入:wq!并按Enter键,保存修改后的配置文件并退出编辑模式。
执行以下命令重建Terway实例。
kubectl delete pod -n kube-system -l app=terway-eniip
步骤三:通过注解为指定Pod创建和关联EIP
通过指定Pod中的Annotations可以创建或者关联EIP到此Pod中。注解内容,请参见上文Pod配置。EIP的使用限制,请参见使用限制。
根据不同场景,配置注解方式如下:
自动分配EIP场景
添加以下注解,为Pod创建并绑定一个EIP:
k8s.aliyun.com/pod-with-eip: "true"
示例YAML如下。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment-basic labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: annotations: k8s.aliyun.com/pod-with-eip: "true" # 为Nginx容器自动分配公网EIP地址。 labels: app: nginx spec: containers: - name: nginx image: nginx
添加以下注解,指定EIP的带宽,默认带宽5 Mbps(与EIP的默认值保持一致):
k8s.aliyun.com/eip-bandwidth: "5"
指定EIP场景
添加以下注解,为Pod指定EIP实例ID:
k8s.aliyun.com/pod-eip-instanceid: "<youreipInstanceId>"
说明由于单个EIP不支持关联多个Pod,所以不适用于Deployment和StatefulSet等场景。
默认情况下如果EIP已经绑定了实例,则会创建EIP失败。如果希望解绑之前的实例再绑定新的实例,需要在上述修改ConfigMap中配置"allow_eip_rob": "true"。
指定EIP实例ID的场景只能用于单个副本实例的情况,例如,Deployment不能超过1个Replicas。
验证配置
当Pod变成Running状态之后,可以观察部署完后的Pod中Annotations k8s.aliyun.com/allocated-eipAddress的值来查看到它分配到的关联EIP地址,通过该EIP即可访问到Pod。