在Kubernetes叢集中,Pod的IP地址一般是私網的IP地址。但在某些情境下,Pod可能需要一個獨立的公網IP地址,使得Pod可以獨立地與外部網路通訊,不受其他Pod流量的幹擾。阿里雲的Terway和ack-extend-network-controller組件均支援將Elastic IP Address(Elastic IP Address,簡稱EIP)直接關聯到特定的Pod上,從而使得該Pod擁有獨立的公網出口。
前提條件
已建立ACK託管叢集、ACK專有版叢集,且叢集網路外掛程式為Terway。具體操作,請參見建立ACK託管叢集、建立ACK專有叢集。關於Terway網路模式的更多資訊,請參見使用Terway網路外掛程式。
自2023年11月起,Terway停止EIP功能更新,並在v1.7.0版本中正式移除。推薦您使用ack-extend-network-controller組件為Pod掛載獨立公網EIP。詳細資料,請參見將EIP功能從Terway遷移至ack-extend-network-controller。
使用限制
在使用EIP之前,請瞭解EIP的使用限制,請參見使用限制。
費用說明
啟用Terway和ack-extend-network-controller外掛程式不會產生額外的費用,但使用雲產品資源可能會產生費用。關於ACK的雲產品資源計費資訊,請參見雲產品資源費用。
背景資訊
一般情況下,Terway網路模式中的Pod訪問公網的流量基於主機SNAT(Source Network Address Translation)或者外部SNAT通過EIP來實現,對於Pod的公網入口流量一般通過LoadBalancer類型的Service流入。但在某些情境中,Pod可能需要獨立的公網地址,例如:
Pod的對外映射連接埠是隨機的,一般常見於UDP(User Datagram Protocol)的遊戲伺服器或電話會議等。例如RTSP協議,對不同的用戶端使用不同的連接埠。
Pod訪問公網流量存在爭搶,Pod需要獨立的公網出口。
步驟一:配置掛載EIP所需的RAM許可權
ack-extend-network-controller(推薦)
為ACK託管叢集或ACK專有版叢集授予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": {} }
為叢集的Worker RAM角色授權。具體操作,請參見步驟二:為叢集的Worker RAM角色授權。
為ACK Serverless叢集授予RAM許可權
對於ACK Serverless叢集,請為RAM使用者產生存取金鑰(AccessKey)。具體操作,請參見建立RAM使用者、建立自訂權限原則。
Terway
Terway為Pod配置EIP需要EIP相關的許可權來申請和配置EIP,所以需要部署額外的配置和許可權。
為ACK託管叢集或者2020年6月及之後建立的ACK叢集基礎版授予RAM許可權
建立自訂權限原則,策略內容如下。具體操作,請參見步驟一:建立自訂權限原則。
{ "Effect": "Allow", "Action": [ "vpc:DescribeVSwitches", "vpc:AllocateEipAddress", "vpc:DescribeEipAddresses", "vpc:AssociateEipAddress", "vpc:UnassociateEipAddress", "vpc:ReleaseEipAddress", "vpc:AddCommonBandwidthPackageIp", "vpc:RemoveCommonBandwidthPackageIp" ], "Resource": [ "*" ], "Condition": {} }
為叢集的Worker RAM角色授權。具體操作,請參見步驟二:為叢集的Worker RAM角色授權。
為ACK專有版叢集或者2020年06月之前建立的ACK託管叢集授予RAM許可權
建立自訂權限原則,策略內容如下。具體操作,請參見步驟一:建立自訂權限原則。
{ "Effect": "Allow", "Action": [ "vpc:DescribeVSwitches", "vpc:AllocateEipAddress", "vpc:DescribeEipAddresses", "vpc:AssociateEipAddress", "vpc:UnassociateEipAddress", "vpc:ReleaseEipAddress", "vpc:AddCommonBandwidthPackageIp", "vpc:RemoveCommonBandwidthPackageIp" ], "Resource": [ "*" ], "Condition": {} }
在RAM角色AliyunCSManagedNetworkRole頁面的權限原則頁簽,單擊新增授權,然後單擊自訂策略,將上一步建立的自訂權限原則選中。
單擊確定。
單擊完成。
步驟二:為叢集安裝或升級外掛程式
您不能同時啟用ack-extend-network-controller與Terway的EIP配置能力,否則可能會使EIP資源重複分配,從而導致EIP綁定失敗。推薦您使用ack-extend-network-controller外掛程式。
外掛程式對比
對比項 | ack-extend-network-controller | Terway |
支援的叢集類型 |
|
|
固定EIP | 支援 | 不支援 |
設定階段 | Pod IP分配後,控制器將為Pod分配、綁定EIP地址。 | 在CNI執行過程中分配、綁定EIP地址。 |
支援版本 | 外掛程式版本為v0.2.0及以上。 | Terway外掛程式版本大於等於v1.0.10.280-gdc2cb6c-aliyun,小於v1.7.0。 |
安裝或升級外掛程式
如果使用ack-extend-network-controller外掛程式,請在ACK應用市場中安裝ack-extend-network-controller外掛程式,並開啟EIP控制器;如果使用Terway網路外掛程式,請將Terway升級至v1.0.10.280-gdc2cb6c-aliyun
及以上版本。
安裝ack-extend-network-controller(推薦)
登入Container Service管理主控台,在左側導覽列選擇 。
在應用市場頁面的搜尋欄中輸入
ack-extend-network-controller
,然後單擊目標應用。在應用詳情頁面,單擊右上方的一鍵部署。
在建立面板中,選擇叢集和命名空間,然後單擊下一步。
在參數配置頁面,選擇版本號碼並設定相應的參數,然後單擊確定。
參數說明如下所示:
配置參數
類型
必填
描述
clusterID
string
是
叢集ID。
regionID
string
是
叢集可用性區域ID。
enableControllers
[]string
是
配置
eip
以啟用EIP功能。networkController.vpcid
string
是
叢集所在VPC ID。
networkController.eipController.maxConcurrentReconciles
int
否
EIP控制器並發數量。
networkController.eipController.garbageCollectionPeriodInMinutes
int
否
EIP控制器清理固定EIP的周期。
customStatefulWorkloadKinds
[]string
否
自訂有狀態控制器Kind。
enableVirtualNode
bool
否
是否支援ECI虛擬節點。
重要啟用此配置後,控制器將為ECI執行個體的Pod分配EIP,您配置的Pod annotation不能和ECI所支援EIP功能相同,請謹慎使用。
enableRRSA
bool
否
通過RRSA方式進行鑒權。
說明ack-extend-network-controller外掛程式版本為v0.10.0及以上支援。
僅支援ack-pod-identity-webhook注入方式配置RRSA,請為kube-system namespace 配置對應Label。配置內容請參考通過RRSA配置ServiceAccount的RAM許可權實現Pod許可權隔離。
rrsaRoleName
string
否
角色名稱。
說明ack-extend-network-controller外掛程式版本為v0.10.0及以上支援。
credential.accessKey
string
否
掛載EIP要求的權限賬戶的AK。
若使用步驟一為叢集的Worker RAM角色授權,此處無需配置。
重要此配置會將敏感資訊儲存到Kubernetes Secret中,不推薦使用。
credential.accessSecret
string
否
掛載EIP要求的權限賬戶的SK。
若使用步驟一為叢集的Worker RAM角色授權,此處無需配置。
重要此配置會將敏感資訊儲存到Kubernetes Secret中,不推薦使用。
參數樣本如下:
clusterID: "c11ba338192xxxxxxx" regionID: "cn-hangzhou" vpcID: "vpc-bp1rkq0zxxxxxx" enableControllers: - eip networkController: eipController: maxConcurrentReconciles: 1 garbageCollectionPeriodInMinutes: 1 customStatefulWorkloadKinds: - foo credential: accessKey: "" accessSecret: ""
如需更新ack-extend-network-controller外掛程式的版本和參數,請參見修改Helm Chart。
升級Terway
請確認您的叢集外掛程式為Terway,並將Terway外掛程式(terway-eni或terway-eniip)升級到支援EIP功能的版本。關於升級Terway外掛程式的具體步驟,請參見管理組件。
Terway外掛程式版本大於等於v1.0.10.280-gdc2cb6c-aliyun,小於v1.7.0。關於Terway外掛程式版本資訊,請參見Terway。
步驟三:啟用EIP功能
啟用EIP的Annotation介紹
ACK支援使用Annotation的方式啟用EIP功能,您可以按需選擇自動分配EIP或為Pod設定固定EIP。
自動分配EIP
使用自動分配EIP功能時,可能會在Pod重建、CNI執行失敗等情況下出現反覆申請、釋放EIP資源的情況。如果您想避免這種情況,可以選擇指定EIP執行個體的方式。
Pod Annotations | value |
network.alibabacloud.com/pod-with-eip k8s.aliyun.com/pod-with-eip | 是否自動建立並綁定EIP。取值:
|
k8s.aliyun.com/eci-with-eip(相容) | |
network.alibabacloud.com/eip-bandwidth k8s.aliyun.com/eip-bandwidth | 僅在建立EIP時支援。 EIP峰值頻寬。單位:Mbps。更多資訊,請參見申請EIP。 |
network.alibabacloud.com/eip-internet-charge-type k8s.aliyun.com/eip-internet-charge-type | 僅在建立EIP時支援。 EIP的計量方式。取值:
更多資訊,請參見申請EIP。 |
k8s.aliyun.com/eip-charge-type(相容) | |
network.alibabacloud.com/eip-instance-charge-type k8s.aliyun.com/eip-instance-charge-type | 僅在建立EIP時支援。 EIP的計費方式,取值:
更多資訊,請參見申請EIP。 說明 僅在ack-extend-network-controller中支援。 |
network.alibabacloud.com/eip-common-bandwidth-package-id k8s.aliyun.com/eip-common-bandwidth-package-id | 綁定已有的共用頻寬包。 說明 Terway外掛程式版本需為v1.2.3及以上;對ack-extend-network-controller外掛程式版本無限制。 |
network.alibabacloud.com/eip-isp k8s.aliyun.com/eip-isp | 僅在建立EIP時支援。 EIP的線路類型。取值:
更多資訊,請參見申請EIP。 說明 Terway外掛程式版本需為v1.2.3及以上;對ack-extend-network-controller外掛程式版本無限制。 |
network.alibabacloud.com/eip-public-ip-address-pool-id k8s.aliyun.com/eip-public-ip-address-pool-id | 僅在建立EIP時支援。 EIP位址集區。關於EIP位址集區的使用限制、使用步驟等,請參見建立和管理IP位址集區。 說明 僅在ack-extend-network-controller中支援。 |
network.alibabacloud.com/eip-resource-group-id k8s.aliyun.com/eip-resource-group-id | 僅在建立EIP時支援。 EIP資源群組。更多資訊,請參見申請EIP。 說明 僅ack-extend-network-controller外掛程式版本為v0.4.0及以上時支援使用。 |
network.alibabacloud.com/eip-name k8s.aliyun.com/eip-name | 僅在建立EIP時支援。 EIP名稱。更多資訊,請參見申請EIP。 說明 僅ack-extend-network-controller外掛程式版本為v0.6.0及以上時支援使用。 |
network.alibabacloud.com/eip-description k8s.aliyun.com/eip-description | 僅在建立EIP時支援。 EIP描述。更多資訊,請參見申請EIP。 說明 僅ack-extend-network-controller外掛程式版本為v0.6.0及以上時支援使用。 |
network.alibabacloud.com/eip-security-protection-types k8s.aliyun.com/eip-security-protection-types | 僅在建立EIP時支援。 EIP安全防護層級,支援高防EIP(DDoS防護增強EIP)。若配置多個,請通過 說明 僅ack-extend-network-controller外掛程式版本為v0.9.0及以上時支援使用。 |
指定EIP執行個體
您可以通過指定EIP執行個體ID的方式綁定已有的EIP。Pod Annotation不會對EIP執行個體配置進行修改,僅將EIP綁定到指定的Pod。
此功能不適用於多副本類型的控制器,請確保EIP執行個體只有一個Pod引用。建議您僅在有狀態應用StatefulSet中使用。
Pod Annotations | value |
network.alibabacloud.com/pod-eip-instanceid k8s.aliyun.com/pod-eip-instanceid | 使用指定的EIP,請填寫EIP執行個體ID,例如:eip-bp14qxxxxxxx。 重要 請避免將相同EIP執行個體分配到不同名稱的Pod上。EIP控制器會在Pod退出後處理EIP解除綁定,在此期間,您不能在新容器內使用相同的EIP執行個體。您可以通過檢查和Pod同名的Pod EIP資源是否存在,來判斷Pod和EIP解除綁定是否完成。 |
k8s.aliyun.com/eci-eip-instanceid(相容) |
設定EIP回收策略的Annotation介紹
固定EIP可以保證Pod重建後依然使用之前的EIP地址。該策略可與自動分配EIP能力結合,用於有狀態應用的固定EIP。
此能力僅在ack-extend-network-controller中支援,且僅適用於有狀態類型的副本控制器,您無法為無狀態類型的控制器使用。
指定EIP執行個體ID,不會釋放EIP執行個體。
Pod Annotation | value |
network.alibabacloud.com/pod-eip-release-strategy k8s.aliyun.com/pod-eip-release-strategy | Pod EIP的回收策略。取值:
可直接配置到期時間。支援Go類型時間運算式。例如, |
在ack-extend-network-controller或Terway叢集中啟用EIP
在ack-extend-network-controller中啟用
ack-extend-network-controller需要訪問阿里雲OpenAPI來建立資源,您需要在RAM中配置相應的許可權。然後再在應用市場中安裝ack-extend-network-controller,並通過Annotation為指定Pod建立和關聯EIP。
通過Annotation為指定Pod建立和關聯EIP
通過指定Pod中的Annotation可以建立或關聯EIP到此Pod中。關於Annotation的詳細資料,請參見下文常見問題。
建立應用,並為指定Pod建立和關聯EIP。
Deployment
使用如下樣本建立一個Deployment控制器,為每個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" spec: readinessGates: - conditionType: "k8s.aliyun.com/eip" containers: - name: example image: nginx
Pod建立成功後,執行以下命令,訪問Pod同名的資源
podeips.alibabacloud.com
,跟蹤分配的EIP資訊。kubectl get podeip -n <namespace> <podname> -o yaml
預期輸出:
apiVersion: alibabacloud.com/v1beta1 kind: PodEIP metadata: creationTimestamp: "2023-12-15T04:25:37Z" finalizers: - podeip-controller.alibabacloud.com/finalizer generation: 1 name: example-xxx namespace: default resourceVersion: "222800" uid: 43xxx-f1xx-4xxx-b3xx-969faxxx spec: allocationID: eip-2ze2qe8zsxxx allocationType: releaseStrategy: Follow type: Auto status: eipAddress: 39.102.XX.XX internetChargeType: PayByTraffic isp: BGP networkInterfaceID: eni-2zeagv8f3xxxx podLastSeen: "2023-12-15T05:18:47Z" privateIPAddress: 192.168.XX.XX resourceGroupID: rg-acfmwxxxxxsq status: InUse
Statefulset
使用如下樣本建立一個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資訊。kubectl get podeip -n <namespace> -o yaml
預期輸出:
apiVersion: v1 items: - apiVersion: alibabacloud.com/v1beta1 kind: PodEIP metadata: creationTimestamp: "2023-12-15T03:28:01Z" finalizers - podeip-controller.alibabacloud.com/finalizer generation: 1 name: example-0 namespace: default resourceVersion: "227221" uid: 79954xx-17xx-4dxx-b7xx-15b84xxx spec: allocationID: eip-2ze08metxxx allocationType: releaseAfter: 10m releaseStrategy: TTL type: Auto status: eipAddress: 39.105.XX.XX internetChargeType: PayByTraffic isp: BGP networkInterfaceID: eni-2ze4tkg4xxx podLastSeen: "2023-12-15T05:31:34Z" privateIPAddress: 192.168.XX.XX resourceGroupID: rg-acfmwxxx status: InUse - apiVersion: alibabacloud.com/v1beta1 kind: PodEIP metadata: creationTimestamp: "2023-12-15T03:28:03Z" finalizers: - podeip-controller.alibabacloud.com/finalizer generation: 1 name: example-1 namespace: default resourceVersion: "227222" uid: 1339xxxe7-97xx-46xx-9bxx-537690xxx spec: allocationID: eip-2zetwhffqxxx allocationType: releaseAfter: 10m releaseStrategy: TTL type: Auto status: eipAddress: 39.105.XX.XX internetChargeType: PayByTraffic isp: BGP networkInterfaceID: eni-2zeagv8f3wxxx podLastSeen: "2023-12-15T05:31:34Z" privateIPAddress: 192.168.XX.XX resourceGroupID: rg-acfmwqnwxxx status: InUse - apiVersion: alibabacloud.com/v1beta1 kind: PodEIP metadata: creationTimestamp: "2023-12-15T04:25:37Z" finalizers: - podeip-controller.alibabacloud.com/finalizer generation: 1 name: example-5bxxx-9xx namespace: default resourceVersion: "227220" uid: 43cdfxxx-f1xx-42xx-b3xx-969fxxx spec: allocationID: eip-2ze2qe8zsmnxxx allocationType: releaseStrategy: Follow type: Auto status: eipAddress: 39.102.XX.XX internetChargeType: PayByTraffic isp: BGP networkInterfaceID: eni-2zeagv8f3wxxx podLastSeen: "2023-12-15T05:31:34Z" privateIPAddress: 192.168.XX.XX publicIpAddressPoolID: pippool-2ze498cxxx resourceGroupID: rg-acfmwqnxxx status: InUse kind: List metadata: resourceVersion: ""
此有狀態應用的Pod刪除後,PodEIP CR會保留10分鐘後再刪除,在此期間建立的同名稱Pod,將繼續使用相應的EIP。
驗證配置。
當Pod變成Running狀態之後,可以觀察部署後的Pod中Annotation k8s.aliyun.com/allocated-eipAddress的值來查看它分配到的關聯EIP地址,通過該EIP即可訪問到Pod。
在Terway中啟用
部署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 # 如果您安裝的是terway-eni組件,請將terway-eniip換成terway-eni。
通過Annotation為Pod建立和關聯EIP。
通過指定Pod中的Annotation可以建立或關聯EIP到此Pod中。EIP的使用限制,請參見使用限制。
根據不同情境,配置註解方式如下:
k8s.aliyun.com/pod-with-eip: "true"
:為目標Pod分配一個獨立的公網EIP。k8s.aliyun.com/eip-bandwidth: "5"
:指定EIP的頻寬,預設頻寬為5 Mbps(與EIP的預設值保持一致)。由於單個EIP不支援關聯多個Pod,所以不適用於Deployment和StatefulSet等情境。
預設情況下,如果EIP已經綁定了執行個體,則會建立EIP失敗。如果希望解除綁定之前的執行個體再綁定新的執行個體,需要在上述修改ConfigMap中配置"allow_eip_rob": "true"。
指定EIP執行個體ID的情境只能用於單個副本執行個體的情況。例如,Deployment不能超過1個Replicas。
驗證配置。
當Pod變成Running狀態之後,可以觀察部署完後的Pod中Annotations network.alibabacloud.com/allocated-eipAddress的值來查看它分配到的關聯EIP地址,通過該EIP即可訪問到Pod。
自動分配EIP情境
添加以下註解,為Pod自動分配EIP,並指定EIP的頻寬。
樣本YAML如下。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-basic
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
annotations:
network.alibabacloud.com/pod-with-eip: "true" # 為Nginx容器自動分配公網EIP地址。
network.alibabacloud.com/eip-bandwidth: "5" # 指定EIP的頻寬,預設頻寬為5 Mbps(與EIP的預設值保持一致)。
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
指定EIP情境
添加以下註解,為Pod指定EIP執行個體ID:
k8s.aliyun.com/pod-eip-instanceid: "<youreipInstanceId>"
常見問題
為什麼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:
network.alibabacloud.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\\/allocated-eipAddress=\\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