Kubernetes-亲和力Cookie-请求不会返回到相同的Pod副本

时间:2019-10-27 18:16:06

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

我一直在寻找如何在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
---

什么可能导致此类问题?

3 个答案:

答案 0 :(得分:2)

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

  

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

您的用户不是通过这些“代理”直接连接到后端,因此会发生会话亲缘关系,但不是您想要的。实际上,如果您使用的是GCLB,则应避免会话关联。

答案 1 :(得分:0)

我必须面对同样的问题,并且平衡流量的最后一层是kubeproxy,此代理完全不支持会话亲缘关系。

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

答案 2 :(得分:0)

亲和力正在发挥作用,但并非您期望的那样。目前,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支持。