单个服务公开的多个 Pod 的会话关联设置
Posted
技术标签:
【中文标题】单个服务公开的多个 Pod 的会话关联设置【英文标题】:Session Affinity Settings for multiple Pods exposed by a single service 【发布时间】:2019-10-12 20:59:02 【问题描述】:我将 Metallb 设置为 LB,并在 K8S 集群上安装了 nginx Ingress。 我已经阅读了有关会话亲和性及其重要性的信息,但到目前为止我还没有清楚的了解。
如何创建一个服务来公开同一应用程序的多个 pod? 创建单服务入口点后,如何将具体的客户端 IP 映射到服务抽象的 Pod 上?
是否有任何博客根据客户端 IP 和 POD 之间的映射是如何在 kubernetes 中完成这个概念来解释这个概念的?
但我在 YAML 中没有看到客户的 IP。那么,该服务如何将流量映射到各个客户端到其端点?这是我的问题。
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10000
【问题讨论】:
因为你使用 nginx 作为入口控制器,我们谈论的是 http 会话,这意味着你需要在入口规则中设置 cookie 粘性,如果你进入 nginx 入口的 github repo控制器,你有很多例子 @c4f4t0r 我想在基于 cookie 之前使用正常的会话亲和性。另外,我想验证一下 Client 请求是否根据其 IP 映射到 Pod。 如果你有web应用根据ip做粘性不太好,如果你有移动用户,ip可以多次变化 我正在尝试首先验证此功能。如果使用粘性会话的 Web 应用程序很有用,那么您是对的。这是我想说的会话控制中更高级的部分。我想我需要先学习基本的映射。 【参考方案1】:会话关联的主要概念是将流量从一个客户端始终重定向到特定节点。请记住,会话亲和性是一种尽力而为的方法,在某些情况下它会由于 pod 重启或网络错误而失败。 Session Affinity 主要有两种类型:
1) 基于客户端 IP
此选项适用于每个 IP 只有一个客户端的情况。在这种方法中,您不需要 K8s 服务和客户端之间的 Ingress/Proxy。 客户端 IP 应该是静态的,因为每次客户端更改 IP 时,他都会被重定向到另一个 pod。
要在 Kubernetes 中启用会话亲和性,我们可以在服务定义中添加以下内容。
service.spec.sessionAffinity: ClientIP
因为社区提供了适当的清单来使用这种方法,所以我不会重复。
2) 基于 Cookies
当有来自同一个 IP 的多个客户端时,它可以工作,因为它存储在网络浏览器级别。此方法需要 Ingress 对象。可以在 Session affinity based on Cookie 部分下找到应用此方法的步骤以及更详细的信息。
创建 NGINX 控制器部署 创建 NGINX 服务 创建入口 将您的公共 DNS 名称重定向到 NGINX 服务公共/外部 IP。关于映射ClientIP和POD,根据Documentation kube-proxy 负责 SessionAffinity。 Kube-Proxy 工作之一 正在写信给 IPtables,更多细节here 就是这样 映射。
可能有助于理解 Session Affinity 的文章: https://sookocheff.com/post/kubernetes/building-stateful-services/ https://medium.com/@diegomrtnzg/redirect-your-users-to-the-same-pod-by-using-session-affinity-on-kubernetes-baebf6a1733b
【讨论】:
【参考方案2】:按照会话亲和性的服务参考
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10000
【讨论】:
是的,到目前为止,我已经看到这个 YAML 到处都被用作示例。但我在 YAML 中没有看到客户的 IP。该服务如何将流量映射到各自的客户端到其端点?这是我的问题。 sessionAffinity: ClientIP 上述属性会根据clientIP将流量路由到同一个后端pod 我们是否需要对 Ingress 文件进行任何更改?或单独的服务文件足以满足上述粘性会话配置。 是的,您可能需要启用 nginx.ingress.kubernetes.io/affinity以上是关于单个服务公开的多个 Pod 的会话关联设置的主要内容,如果未能解决你的问题,请参考以下文章
Swift:如何设置与其他人优雅混合的音频会话(又名 Pod)