使用ELB实现多地域服务暴露

在Kubernetes集群中,需要通过Service使Pod应用能够从外部访问,从而解耦前端和后端的关联,实现松耦合的微服务设计。ACK Edge集群支持通过使用负载均衡类型的服务对外暴露应用,本文以边缘负载均衡ELB(Edge Load Balancer)为例,为您介绍如何使用ELB实现多地域下ENS(边缘节点服务)节点池的服务暴露。

方案介绍

ACK Edge集群可以被划分为云上节点池和云下节点池(边缘节点池),在ACK Edge集群中,您可以选择通过在云上节点池使用负载均衡类型Service暴露应用,也可以在云下(边缘)节点池上使用负载均衡Service暴露应用。

本文以边缘(云下)节点池使用ELB负载均衡服务暴露应用为例,如下图所示,ACK Edge集群控制面位于阿里云VPC,边缘侧支持多个网络的数据中心计算资源接入,并支持同一组业务在多个地域进行服务暴露,即一个Service在多个数据中心对应多个接入点。

本示例中分别在合肥、成都地域创建了ENS节点池,通过ELB将这两个地域的应用请求进行转发。

image

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节点池下的每个节点上都部署该应用。

  1. 使用以下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 #需要在服务中暴露该端口。
  2. 执行以下命令,部署示例应用。

    kubectl apply -f cube.yaml
  3. 执行以下命令,确认示例应用状态正常。

    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节点池分别执行如下操作。

  1. 执行以下命令添加网络ID。

    kubectl annotate np np-chengdu alibabacloud.com/ens-network-id=n-xxx 
  2. 执行以下命令添加ENS节点ID(VPC ID)。

    kubectl annotate np np-chengdu alibabacloud.com/ens-region-id=cn-xxx-xxx
  3. 执行以下命令添加虚拟交换机ID。

    kubectl annotate np np-chengdu alibabacloud.com/ens-vswitch-id=vsw-xxx,vsw-xxx
  4. 执行以下命令添加Service Label。

    kubectl label nodepool np-chengdu 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。

  1. 使用以下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
  2. 执行以下命令,部署cube-svc服务,并通过该服务对外公开应用。

    kubectl apply -f cube-svc.yaml
  3. 执行以下命令,确认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
  4. 执行以下命令,访问示例应用。

    说明

    请将命令中的<YOUR-External-IP>替换为上一步骤中返回的EXTERNAL-IP

    curl http://<YOUR-External-IP>:80  

通过已有的多地域的ELB Service公开应用

  1. 使用以下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
  2. 执行以下命令,部署cube-svc服务,并通过该服务对外公开应用。

    kubectl apply -f cube-svc.yaml
  3. 执行以下命令查看自动创建的PoolService资源。

    kubectl get ps 

    预期输出如下:

    NAME                             AGE
    cube-svc-np-heifei               32s
    cube-svc-np-chengdu              32s
  4. 执行以下命令分别为多个地域的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
  5. 执行以下命令,确认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
  6. 执行以下命令,访问示例应用。

    说明

    请将命令中的<YOUR-External-IP>替换为上一步骤中返回的EXTERNAL-IP

    curl http://<YOUR-External-IP>:80

ELB更新策略

资源对象

用户管理的ELB(您手动创建的ELB)

ECM管理的ELB(由ECM自动创建的ELB)

ELB属性

  • 创建:必须指定节点池选择器和ELB的ID,设置annotation:

    • service.openyurt.io/nodepool-labelselector

    • service.beta.kubernetes.io/alibaba-cloud-loadbalancer-managed-by-user

  • 更新:不支持更新ELB实例属性。

  • 删除:不释放ELB实例。

  • 创建:必须指定节点池选择器。设置annotation:

    service.openyurt.io/nodepool-labelselector

  • 更新:不支持更新ELB实例属性。

  • 删除:释放ELB实例。

后端服务组

  • 创建:根据Service与Pod的状态变更。

  • 更新:Local模式会动态增加、删除后端服务器。

  • 删除:不删除ELB的后端服务组,需要用户手动删除 。

  • 创建:根据Service与Pod的状态变更。

  • 更新:Local模式会动态增加、删除后端服务器。

  • 删除:全部删除释放。

监听

  • 创建:根据Service的spec.Ports增加监听。

  • 更新:根据Service的端口变化会增加、更新、删除该Service管理的监听。

  • 删除:不删除残留监听端口,需要用户手动删除。

  • 创建:根据Service的spec.Ports增加监听。

  • 更新:根据Service的端口变化会增加、更新、删除该Service管理的监听。

  • 删除:全部删除释放。

EIP属性

  • 创建:不支持创建,需要您手动管理

  • 更新:不支持配置属性的更新。

  • 删除:不删除EIP实例。

  • 创建:自动在ELB所在地域创建。

  • 更新:支持EIP带宽的升降配。

  • 删除:删除EIP实例。

相关文档