如何在 VKE 中使用 Vultr 負載均衡器

介紹

Vultr Load Balancer 是一個完全託管的解決方案,用於將流量分配給服務器組,將後端服務的可用性與單個服務器的狀態分離。 Vultr Load Balancer 通過在多台服務器上分配負載來確保您的服務保持在線,以確保服務器不會過載。

如果您是 Vultr 負載均衡器的新手,您應該首先閱讀負載均衡器快速入門指南。

Vultr Kubernetes Engine (VKE) 是一個完全託管的 Kubernetes 產品。 將應用程序部署到 VKE 時,Kubernetes 會自動將 pod 分佈到集群中的不同節點,以提高可用性。

Vultr 負載均衡器與 VKE 兼容,可以在不同節點上的多個 pod 之間分配流量。 VKE 上的 Vultr 負載均衡器提供與獨立場景的完全託管解決方案相同的特性和功能。

本指南解釋瞭如何在 Vultr Kubernetes Engine (VKE) 上部署和配置 Vultr 負載均衡器,並提供詳細的配置信息。

以前的要求

在開始之前,您必須:

  • 部署一個至少包含三個節點的 Vultr Kubernetes 集群。

  • 設置 kubectl 和 git 在你的機器上。

  • 如果您想遵循 TLS/SSL 證書部分,請擁有一個域名。

1. 實現網絡服務器

本節介紹如何使用部署將 Web 服務器部署到 Kubernetes 集群。

本文中的 Web 服務器是一個 Python Web 服務器,它返回 pod 的主機名和 HTTP 請求標頭。

這個示例應用程序有一個公共 docker 鏡像 (quanhua92/whoami)在 DockerHub 上。 你可以去這個 GitHub 存儲庫查看應用程序的源代碼。

  1. 創建一個名為 deployment.yaml 內容如下:

                              
                                apiVersion: apps/v1
    
    kind: Deployment
    
    metadata:
    
        name: whoami
    
    spec:
    
        replicas: 3
    
        selector:
    
            matchLabels:
    
                name: whoami
    
        template:
    
            metadata:
    
                labels:
    
                    name: whoami
    
            spec:
    
                containers:
    
                    - name: whoami
    
                      image: quanhua92/whoami:latest
    
                      imagePullPolicy: Always
    
                      ports:
    
                          - containerPort: 8080
    
                              
                            
  2. 使用部署應用程序 kubectl

                              
                                $ kubectl apply -f deployment.yaml
    
                              
                            

請注意,此示例中的實現名稱是 whoami Pod 監聽端口上的請求 8080 .

2. 為 HTTP 流量實施負載均衡器

本節介紹如何在端口 80 上為 HTTP 流量實現負載均衡器。它實現了一個 Kubernetes 服務 LoadBalancer 編寫和使用元數據註釋來配置 VKE 負載均衡器。

默認的負載平衡算法是 Round Robin 算法。 這是通過依次使用負載均衡器後面的每個服務器來實現的。

  1. 創建一個名為 service.yaml 內容如下。 應用選擇器 whoami 匹配現有的實現和目標端口 8080 匹配上一步中的容器端口。

                              
                                apiVersion: v1
    
    kind: Service
    
    metadata:
    
        name: whoami-lb
    
        annotations:
    
            service.beta.kubernetes.io/vultr-loadbalancer-protocol: "http"
    
    spec:
    
        type: LoadBalancer
    
        selector:
    
            name: whoami
    
        ports:
    
            - name: http
    
              port: 80
    
              targetPort: 8080
    
                              
                            
  2. 實施服務使用 kubectl

                              
                                $ kubectl apply -f service.yaml
    
                              
                            
  3. 運行以下命令查看VKE Load Balancer配置進度:

                              
                                $ kubectl get service whoami-lb -w
    
                              
                            

結果應如下所示:

                      
                        NAME        TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE

whoami-lb   LoadBalancer   10.108.167.185   <pending>     80:32365/TCP   9s

whoami-lb   LoadBalancer   10.108.167.185   139.180.143.107   80:32365/TCP   81s

                      
                    

你也可以去客戶門戶中的負載均衡器頁面檢查您的負載均衡器。

您可以導航到負載均衡器的 IP 地址以訪問該應用程序。

請注意,您可能需要幾分鐘才能通過負載均衡器 IP 地址訪問該應用程序。

應用程序響應應如下所示:

                      
                        Hostname: whoami-84798c47cd-2gnhd

Host: 139.180.143.107

Cache-Control: max-age=0

Dnt: 1

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Accept-Encoding: gzip, deflate

Accept-Language: en-US,en;q=0.9,vi;q=0.8,la;q=0.7,nl;q=0.6

Cookie: session=eyJteV9zZXNzaW9uIjoiVDk4UVUifQ.YoqD3g.o1pyE6s6vTkQqnbvPhG08_6tvOI

X-Forwarded-Proto: http

X-Forwarded-For: 113.172.203.231

Connection: close

Session: T98QU

                      
                    

請多次更新網站。 請注意,主機名會在幾次請求後發生變化,這意味著負載均衡器可以在多個 pod 之間分配流量。

3.使用最小連接數負載均衡算法

最少連接負載均衡算法是一種動態負載均衡算法,在負載均衡器收到客戶端請求時,將客戶端請求分配給活躍連接數最少的應用服務器。 該算法在應用程序服務器具有相似功能的環境中效果最佳。

  1. 改變 service.yaml 如下:

                              
                                apiVersion: v1
    
    kind: Service
    
    metadata:
    
        name: whoami-lb
    
        annotations:
    
            service.beta.kubernetes.io/vultr-loadbalancer-protocol: "http"
    
            service.beta.kubernetes.io/vultr-loadbalancer-algorithm: "least_connections"
    
    spec:
    
        type: LoadBalancer
    
        selector:
    
            name: whoami
    
        ports:
    
            - name: http
    
              port: 80
    
              targetPort: 8080
    
                              
                            
  2. 實施服務使用 kubectl

                              
                                $ kubectl apply -f service.yaml
    
                              
                            

4.在VKE負載均衡器上配置健康檢查

Vultr 負載均衡器提供健康檢查以確定應用程序服務器是否正在響應客戶端請求。

以下是您可以自定義的一些設置:

以下是您可以自定義的一些設置:

  • healthcheck-protocol – 負載平衡器用於執行健康檢查的協議。 兩個可能的值是 tcp http . 默認是 tcp

  • healthcheck-path :負載均衡器用於驗證應用程序服務器的 URL 路徑。 默認是根路徑, / .

  • healthcheck-port : 負載均衡器用來檢測應用服務器的端口。 Kubernetes 定義了這個值。 在正常情況下,您不應更改此值。

  • healthcheck-check-interval :以秒為單位的健康檢查之間的間隔。 默認是 15 .

  • healthcheck-response-timeout :以秒為單位的響應等待時間。 默認是 5 .

  • healthcheck-unhealthy-threshold :負載均衡器從池中刪除應用程序服務器之前的錯誤請求數。 默認是 5 .

  • healthcheck-healthy-threshold – 在負載平衡器將應用程序服務器添加回池之前的健康請求數。 默認是 5 .

示例 本文中的應用程序有一個健康檢查端點 /health。 使用 /health 而不是 / 的好處是:

  • 您可以減少運行健康檢查所需的計算。

  • 您可以減少響應時間和內容的長度。

在應用程序代碼示例中,端點返回一個狀態為 200 的空響應,沒有任何復雜的計算。

  1. 更改 service.yaml 如下:

                              
                                apiVersion: v1
    
    kind: Service
    
    metadata:
    
        name: whoami-lb
    
        annotations:
    
            service.beta.kubernetes.io/vultr-loadbalancer-protocol: "http"
    
            service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-protocol: "http"
    
            service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-path: "/health"
    
            service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-check-interval: "10"
    
            service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-response-timeout: "5"
    
            service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-unhealthy-threshold: "5"
    
            service.beta.kubernetes.io/vultr-loadbalancer-healthcheck-healthy-threshold: "5"
    
    spec:
    
        type: LoadBalancer
    
        selector:
    
            name: whoami
    
        ports:
    
            - name: http
    
              port: 80
    
              targetPort: 8080
    
                              
                            
  2. 實施服務使用 kubectl

                              
                                $ kubectl apply -f service.yaml
    
                              
                            

5. 使用來自 Let's Encrypt 的免費 TLS/SSL 證書公開應用程序

本節介紹如何為端口 443 上的 HTTPS 流量實施負載均衡器。

以下是獲取 TLS/SSL 證書的一些方法:

  • Self-Signed Certificates – 使用您自己的證書頒發機構創建和簽署 TLS/SSL 證書。 這是開發環境的絕佳選擇。

  • Purchase TLS/SSL Certificates – 對於生產用例,您必須從已知的證書頒發機構購買 TLS/SSL 證書。

  • Use Free TLS/SSL Certificates - 使用來自 Let's Encrypt 或 ZeroSSL 的免費 TLS/SSL 證書。

在本節中,您將安裝NGINX 輸入驅動處理傳入的 SSL/TLS 流量和證書管理器管理來自 Let's Encrypt 的免費 TLS/SSL 證書。

NGINX 輸入驅動創建一個 LoadBalancer 處理傳入流量的服務。 這 LoadBalancer service 也是一個 VKE 負載均衡器,因此您不需要在前面部分中創建的服務。

VKE 負載均衡器將傳入流量路由到一組服務器節點。 然後每個服務器節點將負載路由到 NGINX Ingress Controllers . 每個NGINX 輸入驅動將請求路由到相應的應用程序模塊。

默認只有一個NGINX 輸入驅動. 你可以爬上NGINX 輸入驅動取決於您的系統流量。

證書管理器自動創建和管理來自各種發行源的 TLS/SSL 證書,包括 Let's Encrypt、HashiCorp Vault、Venafi 和公私鑰基礎設施。

您需要一個域名來頒發和管理免費的 TLS/SSL Let's Encrypt 證書。

5.1. 準備請求服務

  1. (可選)使用以下命令刪除上一節中的服務:

                              
                                $ kubectl delete -f service.yaml
    
                              
                            
  2. 創建一個 Service 檔案 service-02.yaml 內容如下。 應用選擇器 whoami 匹配現有的實現和目標端口 8080 匹配上一步中的容器端口。 請注意,此服務不是 LoadBalancer 類型,此服務的名稱是 whoami-service .

                              
                                apiVersion: v1
    
    kind: Service
    
    metadata:
    
        name: whoami-service
    
    spec:
    
        selector:
    
            name: whoami
    
        ports:
    
            - name: http
    
              port: 80
    
              targetPort: 8080
    
                              
                            
  3. 運行命令以創建服務。

                              
                                $ kubectl apply -f service-02.yaml
    
                              
                            

5.2. 安裝 NGINX 網關驅動

  1. 安裝 NGINX 入口驅動程序 (ingress-nginx)

                              
                                $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml
    
                              
                            
  2. 要去您的負載均衡器儀表板並獲取新創建的負載均衡器的 IP 地址。 這是為 NGINX 入口構建的負載均衡器。

  3. (可選)運行以下命令等待新建的負載均衡器的IP。 IP在 EXTERNAL-IP 柱子。

                              
                                $ kubectl get services ingress-nginx-controller -n ingress-nginx -w
    
                              
                            
  4. 在您域的 DNS 中創建指向上述 IP 地址的 A 記錄。

  5. (可選)將 NGINX 輸入處理程序縮放到 03 複製品

                              
                                $ kubectl scale deployment --namespace ingress-nginx ingress-nginx-controller --replicas=3 
    
                              
                            

5.3. 安裝證書管理器

本節介紹如何配置證書管理器以使用 HTTP01 質詢解析器來驗證所有權。 如果您想使用 DNS01 挑戰解決器,請參閱文章使用外部 DNS 自動化 DNS/TLS 和讓我們在 Vultr Kubernetes Engine 上加密

  1. 安裝 cert-manager 來管理 SSL 證書

                              
                                $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.10.1/cert-manager.yaml
    
                              
                            
  2. 創建清單文件 letsencrypt.yaml 處理 Let's Encrypt 證書。 代替 使用您的真實電子郵件。

                              
                                apiVersion: cert-manager.io/v1
    
    kind: ClusterIssuer
    
    metadata:
    
      name: letsencrypt-staging
    
    spec:
    
      acme:
    
        # The ACME server URL
    
        server: https://acme-staging-v02.api.letsencrypt.org/directory
    
        preferredChain: "ISRG Root X1"
    
        # Email address used for ACME registration
    
        email: <YOUR_EMAIL>
    
        # Name of a secret used to store the ACME account private key
    
        privateKeySecretRef:
    
          name: letsencrypt-staging
    
        solvers:
    
          - http01:
    
              ingress:
    
                class: nginx
    
    ---
    
    apiVersion: cert-manager.io/v1
    
    kind: ClusterIssuer
    
    metadata:
    
      name: letsencrypt-prod
    
    spec:
    
      acme:
    
        # The ACME server URL
    
        server: https://acme-v02.api.letsencrypt.org/directory
    
        # Email address used for ACME registration
    
        email: <YOUR_EMAIL>
    
        # Name of a secret used to store the ACME account private key
    
        privateKeySecretRef:
    
          name: letsencrypt-prod
    
        solvers:
    
          - http01:
    
              ingress:
    
                class: nginx
    
                              
                            
  3. 運行命令以安裝以前的 Let's Encrypt 發行者。

                              
                                $ kubectl apply -f letsencrypt.yaml
    
                              
                            

5.4. 通過登錄公開應用程序

  1. 創建一個 Ingress 清單文件 ingress.yaml 內容如下。 取代 使用您在上一步中在 A 記錄上創建的域。 代替 whoami-service 使用您的服務名稱。

                              
                                apiVersion: networking.k8s.io/v1
    
    kind: Ingress
    
    metadata:
    
      name: whoami-ingress
    
      annotations:
    
        kubernetes.io/ingress.class: nginx
    
        cert-manager.io/cluster-issuer: letsencrypt-prod
    
    spec:
    
      tls:
    
        - secretName: whoami-tls
    
          hosts:
    
            - <YOUR_DOMAIN>
    
      rules:
    
        - host: <YOUR_DOMAIN>
    
          http:
    
            paths:
    
              - path: /
    
                pathType: Prefix
    
                backend:
    
                  service:
    
                    name: whoami-service
    
                    port:
    
                      number: 80
    
                              
                            
  2. 運行命令創建條目

                              
                                $ kubectl apply -f ingress.yaml
    
                              
                            
  3. 運行命令 kubectl get ingress 查看新創建的條目。 結果應如下所示:

                              
                                NAME                      CLASS    HOSTS               ADDRESS        PORTS     AGE
    
    whoami-ingress   <none>   <YOUR_DOMAIN>      140.82.41.69   80, 443   37s
    
                              
                            
  4. 查閱證書

                              
                                $ kubectl get certificates
    
                              
                            
  5. 導航 https://<YOUR_DOMAIN> 訪問您的應用程序。

6.固定時段的使用

默認情況下,負載均衡器根據負載均衡算法將每個請求獨立路由到服務器池。 但是,您可以使用粘性會話功能(也稱為會話親和力)將用戶會話綁定到特定服務器。

在 Kubernetes 環境中,粘性會話特性有助於保持客戶端對特定應用程序模塊的會話。 如果應用程序模塊不可用,負載均衡器會將請求重定向到另一個應用程序模塊。

本節介紹如何使用上一節中的 NGINX 輸入處理程序實現粘性會話。

您必須將以下註釋添加到 Ingress 清單文件中:

  • nginx.ingress.kubernetes.io/affinity :啟用粘性會話。 該值必須是 cookie”。

  • nginx.ingress.kubernetes.io/session-cookie-name : cookie 的名稱,用於跟踪對每個應用程序模塊的每個請求的實例。

  • nginx.ingress.kubernetes.io/session-cookie-max-age : cookie過期的時間,以秒為單位

  • nginx.ingress.kubernetes.io/session-cookie-expires : 舊註釋的遺留版本,用於與舊瀏覽器兼容。

  1. 改變 ingress.yaml 如下:

                              
                                apiVersion: networking.k8s.io/v1
    
    kind: Ingress
    
    metadata:
    
        name: whoami-ingress
    
        annotations:
    
            kubernetes.io/ingress.class: nginx
    
            cert-manager.io/cluster-issuer: letsencrypt-prod
    
            nginx.ingress.kubernetes.io/affinity: "cookie"
    
            nginx.ingress.kubernetes.io/session-cookie-name: "sticky"
    
            nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
    
            nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
    
    spec:
    
        tls:
    
            - secretName: whoami-tls
    
              hosts:
    
                  - <YOUR_DOMAIN>
    
        rules:
    
            - host: <YOUR_DOMAIN>
    
              http:
    
                  paths:
    
                      - path: /
    
                        pathType: Prefix
    
                        backend:
    
                            service:
    
                                name: whoami-service
    
                                port:
    
                                    number: 80
    
                              
                            
  2. 使用更改應用 kubectl

                              
                                $ kubectl apply -f ingress.yaml
    
                              
                            
  3. 確認 Ingress 戲劇

                              
                                $ kubectl describe ingress whoami-ingress
    
                              
                            
  4. 檢查服務器是否響應 Set-Cookie 標頭

                              
                                $ curl -I https://<YOUR_DOMAIN>
    
                              
                            
  5. 結果應如下所示:

                              
                                HTTP/2 200
    
    date: Tue, 24 May 2022 17:34:58 GMT
    
    content-type: text/html; charset=utf-8
    
    content-length: 372
    
    set-cookie: sticky=1653413699.542.140.602576|38fb12998d06bbfbeaeccec9bf71c761; Expires=Thu, 26-May-22 17:34:58 GMT; Max-Age=172800; Path=/; Secure; HttpOnly
    
    set-cookie: session=eyJteV9zZXNzaW9uIjoiVDBSQUsifQ.Yo0XQg.qaDgq6kq_P2gMC1vgqLPqN1KQfE; HttpOnly; Path=/
    
    vary: Cookie
    
    strict-transport-security: max-age=15724800; includeSubDomains
    
                              
                            

請注意,響應包含一個 set-cookie sticky 鑰匙。 此 cookie 包含有關先前服務器的信息。 NGINX 輸入處理程序嘗試將具有相同 cookie 的請求路由到相同的應用程序模塊。

請多次更新網站。 請注意,在 cookie 過期之前,主機名不會更改,這意味著持久會話按預期工作。

7.使用代理協議

代理協議是一種網絡協議,用於在客戶端連接通過代理時保留客戶端的連接信息(例如 IP 地址)。 保留客戶信息的能力對於分析流量日誌或根據地理 IP 地址更改應用程序功能至關重要。

本節介紹如何使用代理協議配置 Vultr 負載均衡器,以將流量分配到 NGINX 入口控制器並保留客戶端信息。

請注意,您必須將證書管理器配置為使用 DNS01 質詢解析器來頒發 TLS/SSL 證書,以避免 HTTP01 質詢出現問題。

  1. 下載 NGINX 入口驅動程序安裝清單

                              
                                $ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml
    
                              
                            
  2. 打開 deploy.yaml 使用您最喜歡的文本編輯器

  3. 查找文本 kind: ConfigMap 並替換的內容 ConfigMap 資源如下。 替換文字 1.5.1 使用您的 NGINX Ingress Controller 版本。

                              
                                apiVersion: v1
    
    data:
    
      allow-snippet-annotations: "true"
    
    kind: ConfigMap
    
    metadata:
    
      labels:
    
        app.kubernetes.io/component: controller
    
        app.kubernetes.io/instance: ingress-nginx
    
        app.kubernetes.io/name: ingress-nginx
    
        app.kubernetes.io/part-of: ingress-nginx
    
        app.kubernetes.io/version: 1.5.1
    
      name: ingress-nginx-controller
    
      namespace: ingress-nginx
    
    data:
    
      use-proxy-protocol: 'true'
    
      use-forwarded-headers: 'true'
    
      compute-full-forwarded-for: 'true'
    
      ssl-redirect: 'false'
    
                              
                            
  4. 查找文本 type: LoadBalancer 並替換它的內容 Service 如下。 替換文字 1.5.1 使用您的 NGINX Ingress Controller 版本。

                              
                                apiVersion: v1
    
    kind: Service
    
    metadata:
    
      labels:
    
        app.kubernetes.io/component: controller
    
        app.kubernetes.io/instance: ingress-nginx
    
        app.kubernetes.io/name: ingress-nginx
    
        app.kubernetes.io/part-of: ingress-nginx
    
        app.kubernetes.io/version: 1.5.1
    
      name: ingress-nginx-controller
    
      namespace: ingress-nginx
    
      annotations:
    
        service.beta.kubernetes.io/vultr-loadbalancer-proxy-protocol: 'true'
    
    spec:
    
      externalTrafficPolicy: Local
    
      ipFamilies:
    
      - IPv4
    
      ipFamilyPolicy: SingleStack
    
      ports:
    
      - appProtocol: http
    
        name: http
    
        port: 80
    
        protocol: TCP
    
        targetPort: 80
    
      - appProtocol: https
    
        name: https
    
        port: 443
    
        protocol: TCP
    
        targetPort: 443
    
      selector:
    
        app.kubernetes.io/component: controller
    
        app.kubernetes.io/instance: ingress-nginx
    
        app.kubernetes.io/name: ingress-nginx
    
      type: LoadBalancer
    
                              
                            
  5. 使用更改應用 kubectl

                              
                                $ kubectl apply -f deploy.yaml
    
                              
                            

更多信息

文章標題 名稱(可選) 電子郵件(可選) 描述

發送建議

相關文章