【问题标题】:Kubernetes - Affinity Cookie - requests are not coming back to the same pod replicaKubernetes - Affinity Cookie - 请求不会返回到同一个 pod 副本
【发布时间】:2020-02-23 04:42:09
【问题描述】:

我一直在寻找如何在 GKE 中使用 cookie 亲和性。我成功实现了它(感谢这个问题:Problems configuring Ingress with cookie affinity),现在我可以看到我收到了 GCLB Cookie,但由于某种原因,请求没有返回到同一个 pod 副本

我创建了一个包含以下内容的 YAML:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-bsc-deployment
spec:
  selector:
    matchLabels:
      purpose: bsc-config-demo
  replicas: 3
  template:
    metadata:
      labels:
        purpose: bsc-config-demo
    spec:
      containers:
      - name: hello-app-container
        image: gcr.io/google-samples/hello-app:1.0
---
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: my-bsc-backendconfig
spec:
  timeoutSec: 40
  connectionDraining:
    drainingTimeoutSec: 60
  sessionAffinity:
    affinityType: "GENERATED_COOKIE"
    affinityCookieTtlSec: 50
---
apiVersion: v1
kind: Service
metadata:
  name: my-bsc-service
  labels:
    purpose: bsc-config-demo
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
spec:
  type: NodePort
  selector:
    purpose: bsc-config-demo
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-bsc-ingress
spec:
  backend:
    serviceName: my-bsc-service
    servicePort: 80
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-bsc-service
          servicePort: 80
---

什么可能导致这样的问题?

【问题讨论】:

    标签: kubernetes google-cloud-platform google-kubernetes-engine kubernetes-pod


    【解决方案1】:

    原因是这样的,来自 GCP HTTP(S) 负载均衡器documentation

    您必须创建一个防火墙规则,允许来自 130.211.0.0/22 和 35.191.0.0/16 以访问您的实例。这些是负载均衡器用于连接后端的 IP 地址范围 实例。

    您的用户不直接连接到后端,而是通过这些“代理”,因此会话亲和性发生,但不是您想要的。事实上,如果你使用 GCLB,你应该避免会话亲和性。

    【讨论】:

    • 这是真的,但是允许来自 GCLB 的源 IP 范围并不能保证每次客户端有新请求时来自同一个客户端的请求都会转到同一个 pod。范围只需要允许livenessProbereadynessProbe
    • 我的意思是请求不是来自用户的 IP 地址,而是来自这些负载均衡器的 IP 范围,因此不会发生会话亲和性。
    • 是的,您的观点很明确并且是正确的,这是允许来自 GCLB 的流量所必需的,但他问的是因为流量不会流向“相同的 pod 副本”,这意味着流量来自GCLB 但未正确应用会话亲和性
    【解决方案2】:

    亲和力正在发挥作用,只是不是您期望的方式。目前在 GCP LB 和它的后端(节点,而不是 pod)之间发生关联。一旦流量到达您的节点,服务就会将请求转发到 Pod。由于服务没有亲和性,它基本上是随机选择一个 pod。有两种方法可以完成这项工作。

    1. 使用container native load balancing using network endpoint groups。这将导致 Pod 充当负载均衡器的后端,因此 cookie 亲和性应该保持不变。

    2. 保持 Ingress 不变,使用 spec.sessionAffinity 配置您的 NodePort 服务。在 GKE 上,仅支持 clientIP 作为该字段的值。下一步是确保客户端IP实际使用正确,添加spec.externalTrafficPolicy: Local字段。

    或者,您可以使用 Nginx 入口,它不会像 GCP 入口那样导致 2 层负载平衡,因此亲和性更直接,但不受 Google 支持。

    【讨论】:

      【解决方案3】:

      我必须面对同样的问题,流量平衡的最后一层是kubeproxy,这个代理根本不支持会话亲和性。

      要解决此问题,您必须使用不同的入口控制器将kubeproxy 替换为支持会话亲和性的代理服务,在我的情况下,我使用 Nginx。您在 GitHub 存储库here 上有一些很好的示例,说明了如何实现它,基本用法here,您还可以根据每个入口的需要使用注释来配置 Nginx,完整的注释列表here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-31
        • 2019-02-28
        • 1970-01-01
        • 1970-01-01
        • 2018-12-16
        • 2021-06-26
        • 2018-07-05
        • 1970-01-01
        相关资源
        最近更新 更多