【问题标题】:GKE Load Balancer - Ingress - Service - Session Affinity (Sticky Session)GKE 负载均衡器 - 入口 - 服务 - 会话关联性(粘性会话)
【发布时间】:2018-09-09 21:29:13
【问题描述】:

我在我的开发环境中使用以下配置的 minibike 进行了粘性会话:

入口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gl-ingress
  annotations:
    nginx.ingress.kubernetes.io/affinity: cookie
    kubernetes.io/ingress.class: "gce"
    kubernetes.io/ingress.global-static-ip-name: "projects/oceanic-isotope-199421/global/addresses/web-static-ip"
spec:
  backend:
    serviceName: gl-ui-service
    servicePort: 80
  rules:
  - http:
      paths:
      - path: /api/*
        backend:
          serviceName: gl-api-service
          servicePort: 8080

服务:

apiVersion: v1
kind: Service
metadata:
  name: gl-api-service
  labels:
    app: gl-api
  annotations:
    ingress.kubernetes.io/affinity: 'cookie'
spec:
  type: NodePort
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: gl-api

现在我已将我的项目部署到 GKE 粘性会话不再起作用。我认为原因是 GKE 中配置的全局负载均衡器与 NGINX Ingress 控制器没有会话亲和性。任何人有运气把这个连接起来吗?任何帮助,将不胜感激。我想建立会话亲和性:客户端浏览器 > 负载均衡器 > 入口 > 服务。实际会话存在于服务后面的 pod 中。它是一个 API 网关(使用 Zuul 构建)。

【问题讨论】:

    标签: kubernetes google-kubernetes-engine


    【解决方案1】:

    对于入口负载均衡器的 BackendConfig,可以在此处找到文档: https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features

    类型生成 cookie 的示例 sn-p 是:

    spec:
      timeoutSec: 1800
      connectionDraining:
        drainingTimeoutSec: 1800
      sessionAffinity:
        affinityType: "GENERATED_COOKIE"
        affinityCookieTtlSec: 1800
    

    【讨论】:

      【解决方案2】:

      我正在尝试使用以下版本的 gke 教程:1.11.6-gke.6(可用的最新版本)。 粘性不存在...唯一有效的选择是在服务上 sessing externalTrafficPolicy":"Local"...

      spec:
        type: NodePort
        externalTrafficPolicy: Local
      

      我向谷歌打开了同样的缺陷,他们接受了它,没有承诺 eta。 https://issuetracker.google.com/issues/124064870

      【讨论】:

        【解决方案3】:

        好消息!他们终于支持这些调整作为测试版功能!

        从 GKE 版本 1.11.3-gke.18 开始,您可以使用 Ingress 来配置后端服务的这些属性:

        • 超时
        • 连接耗尽超时
        • 会话亲和性

        后端服务的配置信息保存在名为 BackendConfig 的自定义资源中,您可以将其“附加”到 Kubernetes 服务。

        连同其他甜蜜的 Beta 功能(如 CDN、Armor 等),您可以在此处找到操作指南: https://cloud.google.com/kubernetes-engine/docs/how-to/configure-backend-service

        【讨论】:

          【解决方案4】:

          基于此:https://github.com/kubernetes/ingress-gce/blob/master/docs/annotations.md 没有可用的注释,这可能会影响由于入口创建而创建的 Google Cloud LoadBalancer (GCLB) 的会话亲和性设置。因此:

          1. 这必须手动打开:或者按照上面的建议通过自己创建 LB,或者让入口控制器这样做,然后更改每个后端的后端配置(通过 GUI 或 gcloud cli)。恕我直言,后者似乎更快,更不容易出错。 (经测试,配置变更自动传播后,LB返回cookie“GCLB”,后续请求包括cookie均路由到同一节点)
          2. 正如 Matt-y-er 正确指出的那样:必须将 service.spec “externalTrafficPolicy”设置为本地“Local”,以禁用从 GCLB 选择的节点到另一个节点的转发。但是:
          3. 仍然需要确保:
            • GCLB 不应向不运行 pod 的节点发送流量或
            • 确保所有节点上都有一个 pod 运行(并且只有一个 pod,因为 externalTrafficPolicy 设置不会阻止在多个本地 pod 上进行负载平衡)

          关于#3,简单的解决方案:

          更复杂的解决方案(但允许 pod 少于节点):

          注意:上述反亲和版本于 2018 年 7 月 24 日在运行 COS(默认 GKE VM 映像)的 2 节点集群上使用 1.10.4-gke.2 kubernetes 版本进行测试

          【讨论】:

            【解决方案5】:

            GCE/GKE Ingress 控制器中尚不提供会话亲和性。

            与此同时,作为解决方法,您可以直接使用 GCE API 来创建 HTTP 负载平衡器。请注意,您不能在同一个集群中同时使用 Ingress。

            1. 为 Kubernetes 服务使用 NodePort。在spec.ports[*].nodePort中设置端口的值,否则会随机分配一个
            2. Disable kube-proxy SNAT load balancing
            3. 从 GCE API 创建负载均衡器,启用cookie session affinity。作为后端,使用 1 中的端口。

            【讨论】:

              猜你喜欢
              • 2021-09-06
              • 2018-03-20
              • 2013-04-18
              • 2017-10-22
              • 1970-01-01
              • 2016-08-12
              • 1970-01-01
              • 1970-01-01
              • 2014-09-21
              相关资源
              最近更新 更多