用于 websocket 应用程序的 nginx-ingress 粘性会话

Posted

技术标签:

【中文标题】用于 websocket 应用程序的 nginx-ingress 粘性会话【英文标题】:nginx-ingress sticky-session for websocket application 【发布时间】:2019-10-13 04:07:41 【问题描述】:

我在 K8s 集群中有一个 websocket .net 应用程序。我需要使用 nginx 开源实现 websocket 的粘性会话。

我已经阅读了 nginx 和 kubernetes 的文档。 https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#session-affinity

它说我们可以将以下配置用于粘性会话:

nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "ingresscoookie"
nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800

但这似乎不起作用。在这里https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/affinity/cookie/ingress.yaml尝试了kubernetes提供的示例代码。

这对我有用,所以我相信基于 cookie 的会话亲和性似乎不适用于 websocket。

在进一步挖掘文档时,它说我可以使用 IP 哈希 算法。所以我尝试使用下面的注释。

nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"

这也失败了。请求仍然使用默认算法进行平衡。

如何实现会话持久化?

【问题讨论】:

【参考方案1】:

我知道过时的帖子,但可能对其他人有所帮助。您是否删除/注释掉了相关性和会话注释?

这个 sn-p 对我有用,但如果您将其他注释留在其中(像您一样,我无法让基于 cookie 的亲和力工作 - 我需要粘性会话,因为防伪令牌是在本地创建到我的网络服务)。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-world-ingress
  namespace: nginx
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.org/ssl-services: "hello-world-svc"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/upstream-hash-by: $remote_addr
spec:
  tls:
    - hosts:
      - nginx.mydomain.co.uk
      secretName: tls-certificate
  rules:
  - host: nginx.mydomain.co.uk
    http:
      paths:
      - path: /web1(/|$)(.*)      
        backend:
          serviceName: hello-world-svc
          servicePort: 80

【讨论】:

以上是关于用于 websocket 应用程序的 nginx-ingress 粘性会话的主要内容,如果未能解决你的问题,请参考以下文章

docker 中的 nginx + websocket 代理 + Ratchet

用于 SSL PHP 站点和 Websockets WSS 的 Nginx 配置?

用于 Playframework Websockets 的 VHosts Nginx 配置

Websocket 适用于 EC2 url,但不适用于 ElasticBeanstalk URL

我应该使用nginx作为WAMP的代理吗?

Nginx支持WebSocket配置