【问题标题】:Kube-proxy with IPVS mode doesn't keep a connection具有 IPVS 模式的 Kube-proxy 不保持连接
【发布时间】:2021-03-09 08:01:59
【问题描述】:

我有一个带有ipvs kube-proxy 模式的 k8s 集群和一个 k8s 之外的数据库集群。

为了访问数据库集群,我创建了服务和端点资源:

---
apiVersion: v1
kind: Service
metadata:
  name: database
spec:
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 3306
    targetPort: 3306

---
apiVersion: v1
kind: Endpoints
metadata:
  name: database
subsets:
- addresses:
  - ip: 192.168.255.9
  - ip: 192.168.189.76
  ports:
  - port: 3306
    protocol: TCP

然后我用 MySQL 客户端运行一个 pod 并尝试连接到这个服务:

mysql -u root -p password -h database

在网络转储中,我看到成功的 TCP 握手和成功的 MySQL 连接。在 Pod 运行的节点(以下称为工作节点)上,我看到了下一个已建立的连接:

sudo netstat-nat -n | grep 3306
tcp   10.0.198.178:52642             192.168.189.76:3306            ESTABLISHED

然后我在打开的 MySQL 会话中从 pod 发送一些测试查询。它们都被发送到同一个节点。这是预期的行为。

然后我监控工作节点上已建立的连接。大约 5 分钟后,与数据库节点的已建立连接丢失。

但在网络转储中,我看到 TCP 终结数据包没有从工作节点发送到数据库节点。结果,我在数据库节点上得到了一个泄露的连接。

ipvs 如何决定断开已建立的连接?如果ipvs 断开连接,为什么它不能正确完成 TCP 连接?这是一个错误还是我误解了 kube-proxy 中的 ipvs 模式?

【问题讨论】:

  • 有相关日志吗?

标签: kubernetes kube-proxy ipvs


【解决方案1】:

Kube-proxy 和 Kubernetes 无助于平衡持久连接。

Kubernetes 中长寿命连接的整个概念在this article 中有很好的描述:

Kubernetes 不会对长连接和一些 Pod 进行负载平衡 可能会收到比其他人更多的请求。如果您使用的是 HTTP/2、gRPC、 RSockets、AMQP 或任何其他长期存在的连接,例如数据库 连接,您可能需要考虑客户端负载平衡。

我建议通读一遍,但总的来说可以总结为:

  • Kubernetes 服务旨在涵盖 Web 应用程序的最常见用途。

  • 但是,一旦您开始使用使用持久 TCP 连接的应用程序协议,例如数据库、gRPC 或 WebSockets,它们分崩离析。

  • Kubernetes 不提供任何内置机制来对长期 TCP 连接进行负载平衡。

  • 相反,您应该对应用程序进行编码,以便它可以在上游客户端检索和负载平衡。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2019-08-17
    相关资源
    最近更新 更多