在Kubernetes集群中,需要通过Service使Pod应用能够从外部访问,从而解耦前端和后端的关联,实现松耦合的微服务设计。ACK Edge集群支持通过使用负载均衡类型的服务对外暴露应用,本文以边缘负载均衡ELB(Edge Load Balancer)为例,为您介绍如何使用ELB实现多地域下ENS(边缘节点服务)节点池的服务暴露。
方案介绍
ACK Edge集群可以被划分为云上节点池和云下节点池(边缘节点池),在ACK Edge集群中,您可以选择通过在云上节点池使用负载均衡类型Service暴露应用,也可以在云下(边缘)节点池上使用负载均衡Service暴露应用。
本文以边缘(云下)节点池使用ELB负载均衡服务暴露应用为例,如下图所示,ACK Edge集群控制面位于阿里云VPC,边缘侧支持多个网络的数据中心计算资源接入,并支持同一组业务在多个地域进行服务暴露,即一个Service在多个数据中心对应多个接入点。
本示例中分别在合肥、成都地域创建了ENS节点池,通过ELB将这两个地域的应用请求进行转发。
ACK Edge集群提供了一个新的自定义集群资源PoolService,云上托管组件edge-controller-manager(以下称ECM)会根据您创建的负载均衡Service,自动选中一个由节点池管理的PoolService资源,该地域的负载均衡实例生命周期会跟这个PoolService资源进行绑定。
注意事项
- ECM只会为 - Type=LoadBalancer类型的服务配置负载均衡。ECM版本需>=2.1.0。
- ECM管理的ELB实例的名称命名规则为 - k8s/${Service_Name}/${Service_Namespace}/${NodePool_Id}/${Cluster_Id},请勿设置重名导致误删。
- ECM管理的EIP实例的名称命名规则为 - k8s/${Service_Name}/${Service_Namespace}/${NodePool_Id}/${Cluster_Id},请勿设置重名导致误删。
- 多个Service复用一个ELB,必须采用用户管理的ELB和EIP,并且外部流量策略为Cluster类型。 
- 建议您自建边缘网络,并且创建无公网网卡的ENS实例(可绑定EIP或采用NAT使之具有公网访问能力)通过ELB对公网暴露。 
- 如果您创建的具有公网网卡的ENS实例也需要用到ELB,请在ENS节点的主机网络上加入路由规则。 - # 示例 其中10.0.0.3为内网网卡,10.0.0.1为内网网关地址 ip rule add from 10.0.0.3 lookup 4 ip route add default via 10.0.0.1 table 4
步骤一:部署示例应用
本操作以部署一个Cube应用为例,您需要在边缘侧ENS节点池下的每个节点上都部署该应用。
- 使用以下YAML内容创建一个DaemonSet。 - apiVersion: apps/v1 kind: DaemonSet metadata: name: cube labels: app: cube spec: selector: matchLabels: app: cube template: metadata: labels: app: cube spec: containers: - name: cube image: registry.cn-hangzhou.aliyuncs.com/acr-toolkit/ack-cube:1.0 ports: - containerPort: 80 #需要在服务中暴露该端口。
- 执行以下命令,部署示例应用。 - kubectl apply -f cube.yaml
- 执行以下命令,确认示例应用状态正常。 - kubectl get ds cube- 预期输出如下: - NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE cube 4 4 4 4 4 <none> 3d1h
步骤二:为每个节点池添加属性Annotation和服务Label
您需要为边缘侧所有地域下的每个ENS节点池都分别添加属性Annotation和服务Label。本文以成都地域和合肥地域为例,您需要在这两个地域下的ENS节点池分别执行如下操作。
- 执行以下命令获取节点池名称。 - kubectl get nodepool
- 执行以下命令添加网络ID。 - kubectl annotate nodepool np-xxx alibabacloud.com/ens-network-id=n-xxx
- 执行以下命令添加ENS节点ID(VPC ID)。 - kubectl annotate nodepool np-xxx alibabacloud.com/ens-region-id=cn-xxx-xxx
- 执行以下命令添加虚拟交换机ID。 - kubectl annotate nodepool np-xxx alibabacloud.com/ens-vswitch-id=vsw-xxx,vsw-xxx
- 执行以下命令添加Service Label。 - kubectl label nodepool np-xxx k8s-svc=cube
步骤三:通过多地域下的ELB Service公开应用
- 创建服务时,Service类型必须指定为 - type: LoadBalancer。
- 使用ELB作为负载均衡,必须指定LB类型为 - loadBalancerClass: alibabacloud.com/elb。
您可以使用已有的ELB实例暴露服务,如果尚未创建ELB,也可通过自动创建ELB的方式暴露服务。
这两种方式下ELB的更新策略有所差异,具体内容,请参见ELB更新策略。
通过自动创建多地域的ELB Service公开应用
以下场景会删除自动创建的ELB实例和EIP实例,请谨慎操作。
- 删除Service,会删除所有节点池对应的ELB。 
- 删除节点池,会删除对应的ELB。 
- Service的节点池选择器更新,会删除不符合选择器的节点池内的ELB 
- 节点池label更新,导致该节点池不符合Service节点池选择器,删除该节点池内的ELB。 
- 使用以下YAML内容创建名为cube-svc.yaml的文件。 - apiVersion: v1 kind: Service metadata: name: cube-svc labels: app: cube annotations: openyurt.io/topologyKeys: openyurt.io/nodepool #开启流量拓扑 service.openyurt.io/nodepool-labelselector: k8s-svc=cube #选择ENS节点池 spec: selector: app: cube type: LoadBalancer loadBalancerClass: alibabacloud.com/elb externalTrafficPolicy: Local ports: - name: cube port: 80 protocol: TCP targetPort: 80
- 执行以下命令,部署cube-svc服务,并通过该服务对外公开应用。 - kubectl apply -f cube-svc.yaml
- 执行以下命令,确认cube-svc服务已成功创建。 - kubectl get cube-svc- 预期输出: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cube-svc LoadBalancer 192.168.xxx.xxx 39.106.XX.XX,144.121.XX.XX 80:30081/TCP 5m
- 执行以下命令,访问示例应用。 说明- 请将命令中的<YOUR-External-IP>替换为上一步骤中返回的 - EXTERNAL-IP。- curl http://<YOUR-External-IP>:80
通过已有的多地域的ELB Service公开应用
- 使用以下YAML内容创建名为cube-svc的文件。 - apiVersion: v1 kind: Service metadata: name: cube-svc labels: app: cube annotations: openyurt.io/topologyKeys: openyurt.io/nodepool #开启流量拓扑 service.openyurt.io/nodepool-labelselector: k8s-svc=cube #选择ENS节点池 service.beta.kubernetes.io/alibaba-cloud-loadbalancer-managed-by-user: "true" #指定该Service挂载用户指定的LB spec: selector: app: cube type: LoadBalancer loadBalancerClass: alibabacloud.com/elb externalTrafficPolicy: Local ports: - name: cube port: 80 protocol: TCP targetPort: 80
- 执行以下命令,部署cube-svc服务,并通过该服务对外公开应用。 - kubectl apply -f cube-svc.yaml
- 执行以下命令查看自动创建的PoolService资源。 - kubectl get ps- 预期输出如下: - NAME AGE cube-svc-np-heifei 32s cube-svc-np-chengdu 32s
- 执行以下命令分别为多个地域的PoolService指定已有的ELB。 - 本示例以合肥地域和成都地域为例。 - 为合肥地域的节点池指定已有的ELB。 - kubectl annotate ps cube-svc-np-heifei service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id=lb-xxx
- 为成都地域的节点池指定已有的ELB。 - kubectl annotate ps cube-svc-np-chengdu service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id=lb-xxx
 
- 执行以下命令,确认cube-svc服务已成功创建。 - kubectl get cube-svc- 预期输出如下: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cube-svc LoadBalancer 192.168.xxx.xxx 39.106.XX.XX,144.121.XX.XX 80:30081/TCP 5m
- 执行以下命令,访问示例应用。 说明- 请将命令中的<YOUR-External-IP>替换为上一步骤中返回的 - EXTERNAL-IP。- curl http://<YOUR-External-IP>:80
ELB更新策略
| 资源对象 | 用户管理的ELB(您手动创建的ELB) | ECM管理的ELB(由ECM自动创建的ELB) | 
| ELB属性 | 
 | 
 | 
| 后端服务组 | 
 | 
 | 
| 监听 | 
 | 
 | 
| EIP属性 | 
 | 
 | 
相关文档
- 通过Service YAML文件中的Annotation(注解),可以实现更丰富的负载均衡功能。更多配置,请参见通过Annotation配置ELB。 
- ELB服务更多信息,请参见什么是边缘负载均衡ELB。