【问题标题】:Kubernetes ingress to pod running on same host?Kubernetes入口到在同一主机上运行的pod?
【发布时间】:2021-06-01 13:50:39
【问题描述】:

我们刚刚开始使用 k8s(Ubuntu 20.04 上的裸机)。负载均衡服务的入口流量是否可以到达主机上运行的 Pod(如果有的话)?

我们有一些应用使用客户端一致性哈希(使用客户 ID)来选择要调用的服务实例。服务实例是无状态的,但在内存中为每个客户维护 ML 模型。因此,将给定客户的重复请求转到相同的服务是有用的(但不是必需的)。然后我们可以使用 antiAffinity 让每个主机拥有一个 pod。

我们现有的服务发现机制让客户端可以找到服务的所有实例以及它们正在运行的节点。我们所有的 k8s 节点都在运行 Nginx 入口控制器。

【问题讨论】:

标签: kubernetes kubernetes-ingress


【解决方案1】:

我终于弄明白了。这比 IMO 更难! 更新:它不起作用。流量经常流向错误的 pod。

服务需要externalTrafficPolicy: Local(见docs)。

apiVersion: v1
kind: Service
metadata:
  name: starterservice
spec:
  type: LoadBalancer
  selector:
    app: starterservice
  ports:
    - port: 8168
  externalTrafficPolicy: Local

Ingress 需要nginx.ingress.kubernetes.io/service-upstream: "true" (service-upstream docs)。

nginx.ingress.kubernetes.io/server-alias: "~^starterservice-[a-z0-9]+\\.example\\.com" 位是因为我们的服务发现会更新 DNS,因此服务的每个实例都在其 DNS 名称中包含运行它的主机的名称。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: starterservice
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/server-alias: "~^starterservice-[a-z0-9]+\\.example\\.com"
    nginx.ingress.kubernetes.io/service-upstream: "true"
spec:
  rules:
    - host:  starterservice.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: starterservice
                port:
                  number: 8168

所以现在调用 https://starterservice-foo.example.com 将转到在 k8s 主机 foo 上运行的实例。

【讨论】:

  • 更新:它不起作用。流量经常流向错误的 pod。
【解决方案2】:

我相信Sticky Sessions 是您正在寻找的。 Ingress 不直接与 Pod 通信,而是与服务通信。粘性会话尝试通过设置关联 cookie 将来自同一个客户端的请求绑定到同一个 pod。

这用于例如 SignalR 会话,其中协商请求必须与以下 websocket 连接位于同一主机上。

例子:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/affinity-mode: persistent
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

亲和模式“平衡”是默认设置。如果您的 pod 数量没有改变,您的部分客户端将丢失会话。使用“持久”让用户始终连接到同一个 pod(当然,除非它死了)。延伸阅读:https://github.com/kubernetes/ingress-nginx/issues/5944

【讨论】:

  • 问题是来电都来自同一个IP。因此,分配有效地由有效负载(客户 ID)而不是调用者决定。所以我认为设置 cookie 不适用于这个用例。
  • 我们有很多相关的用例。我们有在所有实例之间共享消息队列的无状态服务。每个实例都有一个仪表板,显示他们的队列集发生了什么。所以我们需要能够以某种方式在实例(pod)之间切换。 Web UI 当前具有指向所有实例的链接。
  • 嗯好吧,这更复杂。客户id是怎么传的,headers/path/body/cookie?
  • 它在体内。我们可以改变一些东西把它放在别的地方。目前客户端正在选择实例:它具有主机和 pod 名称,并且可以通过服务发现提供任何其他可能有帮助的信息。如果我们能解决这个问题,我们可以非常快速地将我们的大量基础设施放入 k8s,因为遗留和 k8s 的东西将无缝互操作。
猜你喜欢
  • 2021-08-06
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-17
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多