【问题标题】:Kubernetes nginx ingress session affinity across ports跨端口的 Kubernetes nginx 入口会话亲和性
【发布时间】:2020-07-26 13:34:09
【问题描述】:

我有一个我们已经开始在 Kubernetes 中运行的遗留应用程序。该应用程序侦听两个不同的端口,一个用于一般网页,另一个用于 Web 服务。从长远来看,我们可能会尝试更改其中的一些内容,但目前我们正在尝试让遗留应用程序按原样运行。当前配置为两个端口提供单一服务:

apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  selector:
    app: my-app
  ports:
  - name: web
    port: 8080
    protocol: TCP
    targetPort: 8080
  - name: service
    port: 8081
    protocol: TCP
    targetPort: 8081

然后我使用单个入口根据路径将流量路由到正确的服务端口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
spec:
  rules:
  - host: myapp.test.com
    http:
      paths:
      - backend:
          serviceName: app
          servicePort: 8080
        path: /app
      - backend:
          serviceName: app
          servicePort: 8081
        path: /service

这非常适合路由。进入入口的请求会根据路径路由到正确的服务端口。但是,我遇到的问题是,要让这个遗留应用程序工作,对端口 8080 和 8081 的请求需要路由到每个客户端的同一个 pod。您可以看到我尝试添加 upstream-hash-by 注释。这似乎确保了一个客户端对 8080 的所有请求都发送到同一个 pod,并且一个客户端对 8081 的所有请求都发送到同一个 pod,但对于任何一个客户端来说,这些请求都不是同一个 pod。当我使用单个 pod 实例运行时,一切都很好,但是当我开始启动额外的 pod 时,一些客户端将 /app 请求路由到一个 pod 并将 /service 请求路由到另一个 pod,并且在这个当前不起作用的应用程序中。我在入口中尝试了其他注释,包括 nginx.ingress.kubernetes.io/affinity: "cookie" 和 nginx.ingress.kubernetes.io/affinity-mode: "persistent" 以及尝试将 sessionAffinity: ClientIP 添加到服务但到目前为止似乎没有任何效果。目标是任何一个客户端对任一路径的所有请求都被路由到同一个 pod。任何帮助将不胜感激。

【问题讨论】:

    标签: kubernetes kubernetes-ingress nginx-ingress kubernetes-service


    【解决方案1】:

    会话持久性设置只有在您设置 kube 代理设置时才会起作用,这样它只会将请求转发到本地 pod 而不是集群中的随机 pod。

    您可以通过将服务级别设置设置为:

    service.spec.externalTrafficPolicy:本地

    您可以在这里阅读更多内容:

    https://kubernetes.io/docs/tutorials/services/source-ip/

    完成此操作后,您的入口注释应该可以工作。我只使用外部负载均衡器对此进行了测试,但没有使用入口。

    保持其他一切相同并拥有此服务定义应该可以工作

    apiVersion: v1
    kind: Service
    metadata:
      name: app
    spec:
      externalTrafficPolicy: Local
      selector:
        app: my-app
      ports:
      - name: web
        port: 8080
        protocol: TCP
        targetPort: 8080
      - name: service
        port: 8081
        protocol: TCP
        targetPort: 8081

    【讨论】:

    • 感谢您的回复。属性“externalTrafficPolicy”仅适用于 LoadBalancer 类型的服务,用于在云环境中自动配置负载均衡器。我没有在云提供商中运行,这是一个使用 nginx 作为入口的本地私有 Kubernetes 集群。因此,如果我尝试使用 type=LoadBalancer 部署服务,它只会处于挂起状态。
    • 不,我不这么认为。它适用于所有服务类型,请尝试我发布的服务定义
    • 我做了,它给出了以下错误:“ExternalTrafficPolicy 只能在 NodePort 和 LoadBalancer 服务上设置”。所以我对“仅类型 LoadBalancer”是错误的,它可能是 LoadBalancer 或 NodePort,但不适用于具有默认类型 ClusterIP 的服务。
    • 是的,你需要让它成为节点端口。它没有任何区别
    • 这似乎与原始配置具有相同的行为。对 8080 的所有请求都转到同一个 pod,对 8081 的所有请求都转到同一个 pod,但是对于任何一个客户端,该 pod 都不相同。 externalTrafficPolicy 的描述听起来像是关于将客户端 IP 获取到最终 pod。在选择 pod 时,我试图让入口和服务将两个不同的端口绑定在一起。我不在乎应用程序看到什么。我发现了几种不同的方法可以将客户端固定到给定端口的 pod,但到目前为止还没有办法将客户端固定到服务中所有端口的 pod。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2021-10-21
    • 2019-06-05
    • 2020-08-14
    • 2021-05-31
    • 1970-01-01
    相关资源
    最近更新 更多