為Pod掛載獨立公網EIP
在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權限
請為RAM用戶生成訪問密鑰(AccessKey)。具體操作,請參見創建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應用市場或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控制器。
apiVersion: apps/v1 kind: Deployment metadata: name: example labels: app: example spec: replicas: 1 selector: matchLabels: app: example template: metadata: labels: app: example annotations: network.alibabacloud.com/pod-with-eip: "true" network.alibabacloud.com/eip-bandwidth: "5" spec: containers: - name: example image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest ports: - containerPort: 80
其中的annotations部分表示為每個Pod自動分配一個EIP實例,并且實例帶寬為5 Mbps。
創建成功后,進入名為example的Deployment。點擊Pod名稱(例如:example-78d17b7xxx-adxxx)進入Pod詳情頁面,在頁面右側注解部分查看創建出的EIP信息。您也可以點擊編輯,在Pod YAML中查看創建出的EIP信息。
apiVersion: v1 kind: Pod metadata: annotations: ... network.alibabacloud.com/allocated-eip-id: eip-xxxxx0y884ucrevoxxxxx network.alibabacloud.com/allocated-eipAddress: xxx.xxx.xxx.xxx network.alibabacloud.com/allocated-eni-id: eni-xxxxx563trofuhaxxxxx network.alibabacloud.com/eip-bandwidth: '5' network.alibabacloud.com/pod-with-eip: 'true' ... labels: alibabacloud.com/compute-class: general-purpose app: example name: example-78d17b7xxx-adxxx namespace: default spec: ...
完成示例后,刪除名為example的Deployment。由于在沒有指定Pod EIP實例ID的情況下,Pod EIP的默認回收策略是跟隨Pod生命周期。因此當Pod被刪除后,EIP會自動釋放。
指定EIP實例
準備示例使用的EIP實例,請先申請EIP。
登錄容器計算服務控制臺,在左側導航欄選擇集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇工作負載 > 無狀態。
在頁面右上方,單擊使用YAML創建資源。
使用如下YAML示例創建一個名為example的StatefulSet控制器。
apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: example name: example spec: replicas: 1 selector: matchLabels: app: example template: metadata: labels: app: example annotations: network.alibabacloud.com/pod-eip-instanceid: eip-xxxxx66wjkj16lf9xxxxx spec: containers: - name: example image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest ports: - containerPort: 80
其中的annotations部分表示為Pod指定一個實例ID為eip-xxxxx66wjkj16lf9xxxxx的EIP實例,該實例ID需要替換成實際的值。
創建成功后,進入名為example的StatefulSet。點擊Pod名稱(例如:example-0)進入Pod詳情頁面,在頁面右側注解部分查看已綁定的EIP實例信息。您也可以點擊編輯,在Pod YAML中查看已綁定的EIP實例信息。
apiVersion: v1 kind: Pod metadata: annotations: ... network.alibabacloud.com/allocated-eip-id: eip-xxxxx66wjkj16lf9xxxxx network.alibabacloud.com/allocated-eipAddress: xxx.xxx.xxx.xxx network.alibabacloud.com/allocated-eni-id: eni-xxxxx612ub33hunxxxxx network.alibabacloud.com/pod-eip-instanceid: eip-xxxxx66wjkj16lf9xxxxx ... labels: alibabacloud.com/compute-class: general-purpose app: example name: example-0 namespace: default spec: ...
完成示例后,刪除名為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