使用Ingress來負載分發微服務


目錄  

使用Ingress來負載分發微服務 html

  • Demo規劃 前端

  • 準備Demo並完成部署 node

  • 建立部署(Deployment)資源 nginx

  • 建立服務(Service)資源 docker

  • 建立Ingress資源並配置轉發規則 編程

 

使用Ingress來負載分發微服務

NodePort Service存在太多缺陷,不適合生產環境。LoadBlancer Service則不太靈活,好比針對微服務架構,那麼不一樣服務是否須要多個負載均衡服務呢?那麼,咱們還有其餘選擇麼?那就是Ingress。後端

Ingress將集羣外部的HTTP和HTTPS路由暴露給集羣中的Service,至關於集羣的入口,而入口規則則由Ingress定義的規則來控制。在使用Ingress以前,咱們先須要有一個Ingress Controller(入口控制器),例如ingress-nginx。Ingress負責定義抽象的規則,而Ingress Controller負責具體實現。一般狀況下,Ingress搭配負載均衡一塊兒使用。接下來,筆者結合一個簡單的微服務Demo來使用Ingress進行負載分發。因爲須要使用到負載均衡服務,本教程使用騰訊雲容器服務進行講解。api

 

Demo規劃

 爲了便於你們理解,咱們先作一個簡單的規劃。總體規劃圖以下所示:架構

如圖所示,總體步驟以下所示:app

    1. 咱們須要開發兩個應用,分別爲apidemo1和apidemo2,並提供不一樣的接口服務;

    2. 而後須要將兩個應用分別部署到k8s集羣,而且分別建立不一樣的Service;

    3. 接下來,咱們須要建立Ingress,配置不一樣的轉發規則;

    4. 最後,爲了訪問方便,咱們須要配置域名映射。

 

準備Demo並完成部署

 如上所述,接下來咱們進入開發環節。

爲了完成咱們上述的目標,咱們須要提供如下兩個demo(不限編程語言):

  • apidemo1

以下圖所示,apidemo1的訪問路徑爲https://{hostname}:{port}/api/demo1,輸出JSON「["value1","value2"]」。

注意:apidemo1和apidemo2均需支持80端口和443端口訪問。

  • apidemo2

以下圖所示,apidemo2的訪問路徑爲https://{hostname}:{port}/api/demo2,輸出JSON「["value3","value4"]」。

 

 

 因爲Demo比較簡單,這裏咱們就不貼代碼了。Demo準備完成後,咱們須要推送docker鏡像到目標倉儲,而後建立部署(Deployment)以及服務(Service)。

 

建立部署(Deployment)資源

整個過程在前面的章節咱們均有詳細講述,所以這裏就不贅述了,這裏咱們僅提供參考的YAML定義文件:

apiVersion: apps/v1beta2 #api版本
kind: Deployment #使用部署對象
metadata:
  labels: #標籤列表
    app: apidemo1
  name: apidemo1 #部署名稱
  namespace: default #命名空間
spec:
  replicas: 1 #副本數
  selector: #選擇器
    matchLabels:
      app: apidemo1
  template: #Pod模板
    metadata:
      labels:
        app: apidemo1
    spec:
      containers: #容器列表
      - env: #環境變量設置
        - name: PATH
          value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        - name: ASPNETCORE_URLS
          value: http://+:80
        - name: DOTNET_RUNNING_IN_CONTAINER
          value: "true"
        - name: ASPNETCORE_VERSION
          value: 2.2.6
        image: ccr.ccs.tencentyun.com/magicodes/apidemo1:latest #鏡像地址
        imagePullPolicy: Always #鏡像拉取策略,Always表示老是拉取最新鏡像,IfNotPresent表示若是本地存在則不拉取,Never則表示只使用本地鏡像
        name: apidemo1  #容器名稱
        resources:  #資源限制
          limits: #最高限制
            cpu: 500m
            memory: 256Mi
          requests: #預分配
            cpu: 250m
            memory: 64Mi
        workingDir: /app  #工做目錄
      dnsPolicy: ClusterFirst #DNS策略
      restartPolicy: Always #重啓策略
      terminationGracePeriodSeconds: 30 #刪除須要時間

鏡像是公開的,基於以上YAML定義,各位能夠直接基於騰訊雲的容器服務的【YAML建立資源】進行建立,步驟以下:

  1. 進入容器服務,選擇已有集羣進入

  2. 進入工做負載面板,選擇【Deployment】,點擊右上角的【YAML建立資源】按鈕

  3. 貼入剛剛定義的YAML,以下圖所示,而後點擊建立

4.接下來,須要確保建立成功。咱們使用上述參考的YAML分別建立Deployment「apidemo1」和「apidemo2」以下圖所示:

 

 

 

 

建立服務(Service)資源

接下來,咱們來分別建立「apidemo1」和「apidemo2」Service資源。參考YAML以下所示:

apiVersion: v1
kind: Service #資源類型
metadata:
  name: apidemo1  #服務名稱
  namespace: default
spec:
  ports: #端口列表
  - name: tcp-80-80
    nodePort: 31010 #節點端口
    port: 80  #當前端口
    protocol: TCP #協議
    targetPort: 80  #目標端口
  selector: #標籤選擇器
    app: apidemo1
  type: NodePort  #NodePort 類型的Service

注意:由於Ingress不會暴露任意端口或協議,所以用於外部訪問時,Service類型必須爲NodePort或者LoadBalancer類型。

使用上述相似的「YAML建立資源」的步驟建立Service以下圖所示:

咱們建立的Service類型爲NodePort,所以能夠經過節點公網IP和上述定義的nodePort訪問,以下圖所示:

建立Ingress資源並配置轉發規則

接下來咱們須要建立Ingress並配置好轉發規則達成以下目標:

  • 使用同一個IP訪問多個API服務,這裏咱們對應的是「apidemo1」和「apidemo2」

  • 地址http://{IP}/api/demo1將訪問應用「apidemo1」

  • 地址http://{IP}/api/demo2將訪問應用「apidemo2」

根據以上目標,咱們定義YAML以下所示:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: qcloud #註釋,不一樣的Ingress控制器支持不一樣的註釋
  name: demo-ip
  namespace: default
spec:
  rules: #規則列表
  - http: #HTTP規則
      paths: #路徑列表
      - backend: #後端配置
          serviceName: apidemo1 #後端服務名稱
          servicePort: 80 #服務端口
        path: /api/demo1 #路徑,同一個域名路徑需不一樣
  - http:
      paths:
      - backend:
          serviceName: apidemo2 #後端服務名稱
          servicePort: 80 #服務端口
        path: /api/demo2  #路徑,同一個域名路徑需不一樣

使用以上YAML建立資源,騰訊雲會自動建立負載均衡服務而且提供負載均衡IP,以下圖所示:

 

 

 咱們來驗證下經過此IP訪問是否可以達到預期結果,測試分別以下圖所示:

 

雖然咱們達成了目標,可是經過IP訪問體驗並不友好,如何經過域名訪問呢?YAML定義定義以下所示:

 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: qcloud #註釋,不一樣的Ingress控制器支持不一樣的註釋
    kubernetes.io/ingress.http-rules: '[{"host":"demo.xin-lai.com","path":"/api/demo1","backend":{"serviceName":"apidemo1","servicePort":80}},{"host":"demo.xin-lai.com","path":"/api/demo2","backend":{"serviceName":"apidemo2","servicePort":80}}]' #HTTP轉發規則
    kubernetes.io/ingress.https-rules: "null"
    kubernetes.io/ingress.rule-mix: "true"
    random: "7778255514276773869"
  name: demo
  namespace: default
spec:
  rules: #規則列表
  - host: demo.xin-lai.com #主機名,可選。如不填寫,則使用IP地址。
    http: #HTTP規則
      paths: #路徑列表
      - backend: #後端配置
          serviceName: apidemo1 #後端服務名稱
          servicePort: 80 #服務端口
        path: /api/demo1 #路徑,同一個域名路徑需不一樣
  - host: demo.xin-lai.com #主機名,可選。如不填寫,則使用IP地址。
    http:
      paths:
      - backend:
          serviceName: apidemo2 #後端服務名稱
          servicePort: 80 #服務端口
        path: /api/demo2  #路徑,同一個域名路徑需不一樣

值得注意的是,不一樣的Ingress控制器支持不一樣的註釋,所以註釋的編寫請參閱所使用的Ingress控制器的說明。轉發規則中,host爲空則使用IP。

建立完成以後,騰訊雲一樣會自動建立負載均衡服務而且提供負載均衡IP,以下圖所示,接下來咱們須要將域名「demo.xin-lai.com」解析到該負載均衡IP「193.112.232.48」:

 

 

解析完成後,咱們一樣進行驗證:

如上圖所示,咱們使用域名完成了如下目標:

  • 使用同一個域名「demo.xin-lai.com」訪問了「apidemo1」和「apidemo2」

  • 地址http://demo.xin-lai.com/api/demo1將訪問應用「apidemo1」

  • 地址http://demo.xin-lai.com/api/demo2將訪問應用「apidemo2」

至此,一個簡單的使用Ingress來負載分發微服務的Demo完成。固然這僅僅是微服務架構的萬里長征第一步,畢竟Nginx Ingress控制器僅僅解決了服務的分發,並不具有完整的接口網關功能,對於這塊,筆者推薦你們使用Kong+Kong Ingress Controller,架構以下圖所示:

接下來,咱們再談談微服務應用服務的管理問題。微服務每每有許多小服務,每一個微服務都可以獨立進行部署和擴展,那麼必然提升了應用管理的複雜度,它們的配置、分發、版本管理等等都是一個管理的難題。在這塊,有什麼更好的解決方案嗎?那就Helm。

 

往期內容連接

集羣故障處理之處理思路以及健康狀態檢查(三十二)

集羣故障處理之處理思路以及聽診三板斧(三十三)

開源導入導出通用庫Magicodes.ExporterAndImporter發佈

使用Kubectl部署應用

經過Service訪問應用 (1)

經過Service訪問應用 (2)

相關文章
相關標籤/搜索