通過Service YAML文件中的Annotation(注解),可以實現豐富的負載均衡功能。本文從邊緣負載均衡(Edge Load Balancer,ELB)、監聽和后端服務器組以及邊緣彈性公網IP(邊緣EIP)四種資源維度來介紹通過注解可以對ELB進行的常見配置操作。
注意事項
注解內容區分大小寫,規定統一使用小寫。
Service類型必須指定為
type: LoadBalancer
。使用ELB作為負載均衡必須指定LB類型:
loadBalancerClass: alibabacloud.com/elb
。
邊緣負載均衡ELB
負載均衡規格、付費方式請參見CreateLoadBalancer,負載均衡一經創建不支持配置更新。
創建一個由EdgeControllerManager管理的ELB
必須指定NodePoolSelector,目前支持兩種形式:
key1=val1,key2=val2
,即同時符合key1=val1
和key2=val2
條件的ENS節點池會被選中創建ELB,多個Label之間是And關系。key in (val1,val2)
,即符合key=val1
或key=val2
條件的ENS節點池會被選中創建ELB,多個Value之間為Or的關系。
openyurt.io/topologyKeys: openyurt.io/nodepool
為指定節點池內的服務拓撲,確保流量只會轉發到本節點池內的負載Pod上。對應的YAML:
apiVersion: v1 kind: Service metadata: name: nginx namespace: default annotations: openyurt.io/topologyKeys: openyurt.io/nodepool #開啟流量拓撲 service.openyurt.io/nodepool-labelselector: key1=val1 #選擇ENS節點池 spec: ports: - name: nginx-80 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer loadBalancerClass: alibabacloud.com/elb
創建ELB時指定規格
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec | 負載均衡實例規格,請參見實例規格和計費,通過該參數可以創建指定規格的ELB。 | elb.s2.small |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-pay-type | 負載均衡付費類型,僅支持按量付費(PostPaid)。計費規則,請參見計費說明。 | PostPaid |
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: elb.s1.small
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-pay-type: PostPaid
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
創建ELB時指定網絡暴露類型
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type | 負載均衡暴露類型:
| internet |
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: internet
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
創建公網暴露服務時,選擇EIP規格
公網暴露會購買一個私網ELB和一個公網EIP。
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-bandwidth | 公網帶寬為峰值帶寬。單位:Mbps。 | 10 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-isp | 運營商信息:
| 無 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-instance-charge-type | EIP的實例計費方式,僅支持按量付費(PostPaid)。 | PostPaid |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-internet-charge-type | EIP的公網帶寬計費方式,僅支持月95帶寬計費(95BandwidthByMonth)。 | 95BandwidthByMonth |
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool #開啟流量拓撲
service.openyurt.io/nodepool-labelselector: key1=val1 #選擇ENS節點池
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: internet
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-bandwidth: "10"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-isp: cmcc
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-instance-charge-type: "PostPaid"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-eip-internet-charge-type: "95BandwidthByMonth"
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
后端服務器組
采用Local模式的外部流量策略僅將掛載應用Pod的節點作為后端服務器。若多個Service共享一個ELB,則不支持設置為Local模式的外部流量策略。
外部流量策略采用Cluster模式,將會將制定VPC內所有的ENS集群節點作為后端服務器。
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool #開啟流量拓撲
service.openyurt.io/nodepool-labelselector: key1=val1 #選擇ENS節點池
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
externalTrafficPolicy: Local
使用指定Label的邊緣節點作為后端服務器
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-backend-label | 指定通過Label指定CLB后端掛載哪些Worker節點。多個Label以英文半角逗號(,)分隔,例如 | 無 |
如需排除邊緣節點作為后端服務器,在邊緣節點上打標簽:node.kubernetes.io/exclude-from-external-load-balancers=true
。
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-backend-label: key2=val2
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
externalTrafficPolicy: Local
配置ELB后端權重
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-backend-weight | 如果監聽采用權重輪詢(WRR)方法,則會根據后端的權重均衡訪問請求到后端服務器,其中多個節點與權重以逗號分隔。 例如 | base=100 |
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1,key2=val2
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-backend-weight: base=50,node1=80,node2=90
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
監聽
ECM會根據Service的Spec.ports的端口自動創建監聽,后端監聽端口由集群分配。如需指定后端監聽端口,則需要設置nodePort: ${YOUR_SPEC_PORT}
。YAML如下:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1
ports:
- name: nginx-80
port: 80
protocol: TCP
nodePort: 30080
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
為監聽設置調度算法
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler | 監聽端口對后端的調度算法:
| rr |
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler: "wrr"
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
nodePort: 30080
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
為TCP類型端口配置會話保持時間
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-persistence-timeout | 會話保持時間。僅針對TCP協議的監聽。如果負載均衡實例配置了多個TCP協議的監聽端口,則默認將該配置應用到所有TCP協議的監聽端口。 單位:秒。取值[0, 3600]。為0表示會話保持關閉。 | 0 |
為TCP類型端口配置連接超時時間
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-established-timeout | 連接超時時間。單位:秒。取值范圍為[10, 900]。 | 500 |
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1,key2=val2
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-established-timeout: "900"
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
nodePort: 30080
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
配置監聽的健康檢查
注解內容 | 描述 | 默認值 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-healthy-threshold | 健康檢查連續成功多少次后,將后端服務器的健康檢查狀態由 fail(后臺服務器不可達)判定為 success(后臺服務器可達)。取值范圍為[2~10]。 | 3 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-unhealthy-threshold | 健康檢查連續失敗多少次后,將后端服務器的健康檢查狀態由 success(后臺服務器可達)判定為 fail(后臺服務器不可達)。取值范圍為[2~10]。 | 3 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-check-interval | 健康檢查的時間間隔。取值范圍為[2~10]。單位:秒。 | 2 |
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-connect-timeout | 接收來自運行狀況檢查的響應需要等待的時間。如果后端 ECS 在指定的時間內沒有響應,則判定為健康檢查失敗。取值范圍為[1~300]。單位:秒。 | 5 |
對應的YAML:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
annotations:
openyurt.io/topologyKeys: openyurt.io/nodepool
service.openyurt.io/nodepool-labelselector: key1=val1,key2=val2
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-healthy-threshold: "5"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-unhealthy-threshold: "5"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-interval: "2"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-health-check-connect-timeout: "5"
spec:
ports:
- name: nginx-80
port: 80
protocol: TCP
nodePort: 30080
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerClass: alibabacloud.com/elb
高級配置
本節介紹兩種進階方式配置負載均衡。
在不同的場景創建Service。
指定已有的ELB
使用既存的負載均衡時,需要指定網絡的ID以及其對應的負載均衡ID。
按以下YAML創建Service。
apiVersion: v1 kind: Service metadata: name: nginx namespace: default annotations: openyurt.io/topologyKeys: openyurt.io/nodepool #開啟流量拓撲 service.openyurt.io/nodepool-labelselector: key1=val1 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-managed-by-user: "true" spec: ports: - name: nginx-80 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer loadBalancerClass: alibabacloud.com/elb
多個Service復用一個ELB
只可采用Cluster模式的外部流量策略。
需要用戶自己管理的ELB實例,并且指定使用的ELB。
如果開啟EIP提供公網訪問能力,需要用戶自己創建EIP實例并且管理。
需要指定強制覆蓋監聽為true。
對應的YAML:
apiVersion: v1 kind: Service metadata: name: nginx namespace: default annotations: openyurt.io/topologyKeys: openyurt.io/nodepool #開啟流量拓撲 service.openyurt.io/nodepool-labelselector: key1=val1 service.openyurt.io/elb-force-override-listeners: "true" service.beta.kubernetes.io/alibaba-cloud-loadbalancer-managed-by-user: "true" spec: ports: - name: nginx-80 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer loadBalancerClass: alibabacloud.com/elb
找到對應節點池(ENS VPC)的PoolService,執行以下命令為其配置指定負載均衡。
kubectl annotate ps {<SERVICENAME>-NodePoolID} service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id=<lb_ID>
說明上述命令中的
<SERVICENAME>
請替換為實際的節點池(ENS VPC)的PoolService的名稱;<lb_ID>
請替換為實際的LoadBalancer ID。