怎样在 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.部署网络服务器

本节介绍怎样使用 Deployment 将 Web 服务器部署到 Kubernetes 集群。

本文中的 Web 服务器是一个 Python Web 服务器,它返回 pod 的主机名和 HTTP 请求标头。

这个 example 应用程序有一个 公共 Docker 镜像 (quanhua92/whoami) 在 Docker 中心。 你可以去 这个 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
    

请注意,此中的部署名称 example 是 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:负载均衡器用于执行健康检查的协议。 两个可能的值是 tcphttp. 默认值为 tcp

  • healthcheck-path:负载均衡器用于检查应用程序服务器的 URL 路径。 默认值为根路径, /.

  • healthcheck-port:负载均衡器用于检查应用程序服务器的端口。 Kubernetes 定义了这个值。 在正常情况下,您不应更改此值。

  • healthcheck-check-interval:以秒为单位的健康检查之间的间隔。 默认值为 15.

  • healthcheck-response-timeout:以秒为单位的响应超时。 默认值为 5.

  • healthcheck-unhealthy-threshold:负载均衡器从服务器池中移除应用服务器之前的不健康请求数。 默认值为 5.

  • healthcheck-healthy-threshold:负载均衡器将应用程序服务器添加回服务器池之前的健康请求数。 默认值为 5.

这 example 本文中的应用程序有一个用于健康检查的端点 /health。 使用 /health 而不是 / 的好处是:

  • 您可以减少运行健康检查所需的计算。

  • 您可以减少响应时间和内容长度。

在里面 example 应用程序代码,端点返回一个状态为 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 入口控制器 将请求路由到相应的应用程序 pod 中。

默认只有一个 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 Ingress Controller 扩展到 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. 使用 Ingress 公开应用程序

  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 环境中,粘性会话功能有助于保持从客户端到特定应用程序 pod 的会话。 如果应用程序 pod 不可用,负载均衡器会将请求重新路由到另一个应用程序 pod。

本节介绍怎样使用上一节中的 NGINX Ingress Controller 实现粘性会话。

您需要在 Ingress 清单文件中添加以下注释:

  • nginx.ingress.kubernetes.io/affinity:启用粘性会话。 该值必须是 cookie”。

  • nginx.ingress.kubernetes.io/session-cookie-name:cookie 的名称,用于跟踪对每个应用程序 pod 的每个请求的实例。

  • 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 Ingress Controller 尝试将具有相同 cookie 的请求路由到相同的应用程序 pod。

刷新网站几次。 请注意,在 cookie 过期之前,主机名不会更改,这意味着粘性会话按预期工作。

7. 使用代理协议

代理协议是一种网络协议,用于在客户端连接通过代理时保留客户端的连接信息(例如 IP 地址)。 保留客户端信息的能力对于分析流量日志或根据地理 IP 地址更改应用程序功能至关重要。

本节介绍怎样使用代理协议设置 Vultr 负载均衡器,以将流量分配到 NGINX 入口控制器并保留客户端信息。

请注意,您应该将证书管理器设置为使用 DNS01 质询解决程序来颁发 TLS/SSL 证书并避免 HTTP01 质询出现问题。

  1. 下载 NGINX Ingress Controller 的安装清单

    $ 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
    

更多信息

文章标题 名称(可选) 电子邮件(可选) 描述

发送建议

注:本教程在Vultr VPS上测试通过,如需部署请前往Vultr.com