session - 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?
提前致谢
解决方案
我认为您可以将 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 负载均衡器始终将流量发送到一个 pod
希望有帮助
推荐阅读
- r - 在单个 RDS 文件中保存多个变量
- react-native - 初始路线名称在我的 DrawerNavigator 中不起作用
- javascript - Vuejs 实例之外的 VueJS 应用程序元素的侦听器不在 Firefox 和 IE 中工作,但在 chrome 中工作
- excel - Excel VBA将固定值粘贴到范围
- angular - 角度创建 CacheService 的新实例
- mysql - 无法使用 nginx-ingress 公开在 kubernetes 集群内运行的 mysql tcp 服务
- php - Laravel 5.4 - instanceof Collection 在被传递时不返回 true 似乎是一个 Collection
- javascript - 如何使用 $this 从 DIV 中选择数据?
- c# - 没有重载方法需要 0 个参数
- java - 我可以在编译时使用 gradle 重新设计我的应用程序吗?