全部產品
Search
文件中心

Container Service for Kubernetes:使用ELB實現多地區服務暴露

更新時間:Jun 19, 2024

在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資源,該地區的Server Load Balancer執行個體生命週期會跟這個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執行個體。

相關文檔