首页 > 解决方案 > Kubernetes 服务会话亲和性,如何通过服务而不是端点来坚持会话

问题描述

据我了解,当设置会话亲和力等于“clientIP”的 kubernetes 服务时,内部 iptables 会通过端点(服务 ip 和端口)将规则写入 nat 流量。所以我们有两个相关的连接请求到同一个服务的不同端口,很可能第二个请求会被重定向到另一个 pod。

例如:服务 S 有 1000 和 1001 端口,覆盖了 3 个 Pod A、B、C。我们可能想要的是:来自客户端(IP:xx.xx.xx.xx)的 2 个请求(R1 到端口 1000,R2 到 1001)被发送到服务 S,这 2 个请求应该始终重定向到 pod A。

Kubernetes 现在将 S:1000 和 S:1001 视为两个不同的端点(并且会话亲和性规则分别适用于它们),因此第一个请求将发送到 pod A,第二个请求将发送到 pod B。

无论如何我们可以实现目标:将会话从同一个 ip 到同一个服务到同一个 pod?

提前致谢

标签: sessionkubernetessticky

解决方案


我认为您可以将 Nginx(就像您正确提到的内部 LB 一样)与Nginx Sticky 会话一起使用

Set-Cookie入口控制器使用标头对第一个请求回复响应。cookie 的值将映射到特定的 pod 副本。当后续请求再次返回时,客户端浏览器将附加 cookie,因此入口控制器能够将流量路由到同一个 pod 副本。

配置通常是通过注解来实现的。

完整列表:

nginx.ingress.kubernetes.io/affinity
nginx.ingress.kubernetes.io/affinity-mode
nginx.ingress.kubernetes.io/session-cookie-name
nginx.ingress.kubernetes.io/session-cookie-path
nginx.ingress.kubernetes.io/session-cookie-samesite
nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none
nginx.ingress.kubernetes.io/session-cookie-max-age
nginx.ingress.kubernetes.io/session-cookie-expires
nginx.ingress.kubernetes.io/session-cookie-change-on-failure

示例:通过在 ingress 对象中设置注解,我们可以确保后续请求仍将由同一个 pod 提供服务。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-test
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"

spec:
  rules:
  - host: stickyingress.example.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /

阅读:Kubernetes 中的粘性会话

检查:具有粘性会话的 kubernetes 负载均衡器始终将流量发送到一个 pod

希望有帮助


推荐阅读