将流量路由回特定的 pod

Routing traffic back to a specific pod

我有如下入口资源:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: "app-ingress"
  labels:
    app: "app"
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
    cert-manager.io/cluster-issuer: letsencrypt
spec:
  tls:
    - hosts:
        - api.example.com
      secretName: tls-secret
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /grpc
            pathType: ImplementationSpecific
            backend:
              service:
                name: "app-server"
                port:
                  number: 50051
          - path: /callback
            pathType: ImplementationSpecific
            backend:
              service:
                name: "app-server"
                port:
                  number: 80

app-server 运行两个服务(在同一个 pod 上),一个 grpc 网络服务器和一个 http 网络服务器。首先,客户端向 api.example.com/grpc 发出请求。为了完成请求,服务器向第三方服务发出请求,等待 api.example.com/callback 上的回调,然后完成客户端的请求(api.example.com/callback 仅由第三方服务访问,而不是客户)。

问题是,我如何才能明确地将 api.example.com/callback 路由回发出初始请求的同一个 pod?显然,如果 pod1 向第三方服务发出请求,而 pod2 收到回调, pod1 将永远不会收到回调,客户端请求将不得不超时。我可以将信息附加到从第三方服务收到的回调中,那么有没有一种方法可以附加某种 pod id,以便 kubernetes 将回调路由回启动它的 pod?

我已经考虑过使用 StatefulSets,但我不确定它究竟如何工作。或者有一种接收回调并将它们路由到正确的 pod 的“通知 pod”会更好吗?

一种方法是给用户 sticky sessons
如果您想确保来自特定客户端的连接每次都传递到同一个 Pod,您可以 select 通过将 service.spec.sessionAffinity 设置为“ClientIP”(默认为“None”)。您还可以通过适当设置 service.spec.sessionAffinityConfig.clientIP.timeoutSeconds 来设置最大会话粘滞时间(默认值为 10800,即 3 小时)。

另一种方法是设计应用程序,无论哪个 pod 接收回调请求都无关紧要,具有待处理客户端连接的适当 pod 将收到通知(并提供数据),并将响应发送回客户端。要传达请求数据,您可以使用某种消息服务或分布式内存数据存储,如 Redis。