Kubernetes

kubernetes session会话保持

2020-09-23  本文已影响0人  Lemonlzy

前提


基于kubernetes部署Java项目,发现在多pod模式下,会出现登录成功但是页面无法跳转的问题,在单一pod时却可以成功登录并页面正常跳转,于是推测是cookie的问题。

网上的大部分文章提供的解决方案都是在service的配置文件中加入sessionAffinity: ClientIP,功能是选择与请求来源ip更接近的pod,这样就会固定同一个session,但是好像并不适用于我这个项目。

最终的解决当然还是要靠自己读官方的文档,ingress-nginx有大量的注释配置,官方针对这种情况已经做了说明,需要细细阅读,详见Cookie affinity

解决方案


注释nginx.ingress.kubernetes.io/affinity在Ingress的所有上游中启用和设置相似性类型。这样,请求将始终定向到同一上游服务器。Nginx唯一可用的相似性类型是cookie

如果为一个主机定义了多个Ingress nginx.ingress.kubernetes.io/affinity: cookie,并且至少一个Ingress使用,则只有Ingress使用的路径nginx.ingress.kubernetes.io/affinity将使用会话Cookie相似性。通过随机选择后端服务器,可以在主机的其他入口定义的所有路径进行负载均衡。

如果您使用Cookie affinity,则还可以使用注释nginx.ingress.kubernetes.io/session-cookie-name来指定将用于路由请求的cookie名称。 默认是创建一个名为INGRESSCOOKIE的cookie。

注释nginx.ingress.kubernetes.io/affinity-mode定义了会话的粘性。如果将部署规模扩大,balance则将此选项设置为(默认)将重新分配一些会话,从而重新平衡服务器上的负载。将此设置为persistent不会重新平衡与新服务器的会话,因此提供了最大的粘性。

以上是官方文档的直译。

简而言之,在ingress-nginx配置中应做以下操作:

  1. 设置nginx.ingress.kubernetes.io/affinity属性,启用会话保持。

  2. 设置nginx.ingress.kubernetes.io/affinity-mode属性,设置为balance在集群扩大pod时,会自动分配一些会话到新创建的pod上,用于平衡服务器的负载;设置为persistent则永远保证用户访问pod的一致性,不会访问到其他pod。

  3. 设置nginx.ingress.kubernetes.io/session-cookie-name属性,自定义cookie名称。

可见cookie示例

对我用到了其中的三个属性进行描述:

属性名称 描述
nginx.ingress.kubernetes.io/affinity 亲和力类型,设置该属性为 cookie 来启用会话保持 仅支持设置为cookie
nginx.ingress.kubernetes.io/affinity-mode 定义会话的粘性。 进行集群的扩容时,可设置为balanced属性来重新分配某些会话,或者使用persistent来保证用户永远访问至同一个pod。 balanced (默认设置) or persistent
nginx.ingress.kubernetes.io/session-cookie-name 将要被创建的cookie名称 默认设置为 INGRESSCOOKIE,可自定义

配置文件


使用session会话保持可以用于解决多tomcat的pod下,登录由于session问题导致页面无法跳转的问题。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/affinity-mode: "persistent"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
spec:
  tls:
  - hosts:
    - your.host.cn
    secretName: https-secret
  rules:                                                          
  - host: your.host.cn                                            
    http:                                                        
      paths:                                                       
      - path:
        backend:
          serviceName: your service name
          servicePort: 8280

以下为其他网友提供的解决方案:

在service的配置文件中加入sessionAffinity: ClientIP,功能是选择与请求来源ip更接近的pod,这样就会固定同一个session。

apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
    release: canary
  ports:
  - name: http
    targetPort: 8280
    port: 8280
  sessionAffinity: ClientIP

欢迎访问我的个人博客:Lemon - 万事顺遂

上一篇下一篇

猜你喜欢

热点阅读