Kubernetes - Affinity Cookie - 请求不会返回到同一个 pod 副本
Kubernetes - Affinity Cookie - requests are not coming back to the same pod replica
我一直在寻找如何在 GKE 中使用 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
---
可能是什么导致了这样的问题?
我不得不面对同样的问题,最后一层流量平衡是 kubeproxy
,这个代理根本不支持会话亲和性。
要解决此问题,您必须使用不同的入口控制器来将 kubeproxy
替换为支持会话亲和性的代理服务,在我的例子中,我使用 Nginx。关于如何在 GitHub 存储库 here, basic usage here and also you can use annotations to configure the Nginx depending on each ingress needs, the complete list of annotations here 上实施它,您有一些很好的示例。
原因是这样的,来自 GCP HTTP(S) 负载平衡器 documentation:
You must create a firewall rule that allows traffic from
130.211.0.0/22 and 35.191.0.0/16 to reach your instances. These are IP address ranges that the load balancer uses to connect to backend
instances.
您的用户不直接连接到后端,而是通过这些 "proxies",因此会发生会话关联,但不是您想要的。事实上,如果你正在使用 GCLB,你应该避免会话关联。
亲和力正在发挥作用,只是不是您所期望的那样。 GCP LB 和它的后端(节点,而不是 pod)之间目前正在发生关联。一旦流量到达您的节点,该服务就会将请求转发到一个 pod。由于该服务没有亲缘关系,它基本上是随机选择一个 pod。有两种方法可以完成这项工作。
使用container native load balancing using network endpoint groups。这将导致 pods 充当负载均衡器的后端,因此 cookie 亲和力应该保持不变。
保持 Ingress 不变,使用 spec.sessionAffinity
配置您的 NodePort 服务。在 GKE 上,仅支持 clientIP
作为此字段的值。下一步是确保客户端IP实际使用正确,添加spec.externalTrafficPolicy: Local
字段。
或者,您可以使用 Nginx 入口,它不会像 GCP 入口那样导致 2 层负载平衡,因此亲和力更直接,但不受 Google 支持。
我一直在寻找如何在 GKE 中使用 cookie affinity。我成功地实现了它(感谢这个问题:
我创建了一个包含以下内容的 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
---
可能是什么导致了这样的问题?
我不得不面对同样的问题,最后一层流量平衡是 kubeproxy
,这个代理根本不支持会话亲和性。
要解决此问题,您必须使用不同的入口控制器来将 kubeproxy
替换为支持会话亲和性的代理服务,在我的例子中,我使用 Nginx。关于如何在 GitHub 存储库 here, basic usage here and also you can use annotations to configure the Nginx depending on each ingress needs, the complete list of annotations here 上实施它,您有一些很好的示例。
原因是这样的,来自 GCP HTTP(S) 负载平衡器 documentation:
You must create a firewall rule that allows traffic from 130.211.0.0/22 and 35.191.0.0/16 to reach your instances. These are IP address ranges that the load balancer uses to connect to backend instances.
您的用户不直接连接到后端,而是通过这些 "proxies",因此会发生会话关联,但不是您想要的。事实上,如果你正在使用 GCLB,你应该避免会话关联。
亲和力正在发挥作用,只是不是您所期望的那样。 GCP LB 和它的后端(节点,而不是 pod)之间目前正在发生关联。一旦流量到达您的节点,该服务就会将请求转发到一个 pod。由于该服务没有亲缘关系,它基本上是随机选择一个 pod。有两种方法可以完成这项工作。
使用container native load balancing using network endpoint groups。这将导致 pods 充当负载均衡器的后端,因此 cookie 亲和力应该保持不变。
保持 Ingress 不变,使用
spec.sessionAffinity
配置您的 NodePort 服务。在 GKE 上,仅支持clientIP
作为此字段的值。下一步是确保客户端IP实际使用正确,添加spec.externalTrafficPolicy: Local
字段。
或者,您可以使用 Nginx 入口,它不会像 GCP 入口那样导致 2 层负载平衡,因此亲和力更直接,但不受 Google 支持。