通过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)。计费规则,请参见什么是边缘负载均衡ELB。 | 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。