【问题标题】:Expose each pod in a statefulset to the internet without a custom proxy在没有自定义代理的情况下将 statefulset 中的每个 pod 公开到 Internet
【发布时间】:2018-06-10 16:14:49
【问题描述】:

我有一个带有 server-0server-1 等 Pod 的 StatefulSet。我想通过诸如 server-0.mydomain.com 或 mydomain.com/server-0 之类的 URL 将它们直接公开到 Internet。

我希望能够扩展 StatefulSet 并自动从 Internet 访问新的 pod。例如,如果我将其扩展为包含 server-2,我希望 mydomain.com/server-2 在新 pod 准备好时将请求路由到它。我不想同时扩展一些其他资源或创建另一个服务来实现这种效果。

我可以使用自定义代理服务来实现这一点,该服务只检查请求路径并在内部转发到正确的 pod,但这似乎容易出错且浪费。

有没有办法让 Ingress 自动路由到 StatefulSet 中的不同 pod,或者其他一些可以避免自定义代码的内置技术?

【问题讨论】:

    标签: kubernetes google-kubernetes-engine kubernetes-ingress


    【解决方案1】:

    我认为你做不到。作为同一个 statefulSet 的一部分,直到 pod-x 的所有 pod 都是服务的目标。由于您无法定义哪个 pod 将获得请求,因此您无法强制将“pod-1.yourapp.com”或“yourapp.com/pod-1”发送到 pod-1。它将被发送到服务,服务可能会将其发送到 pod-4。

    即使可以,您也需要动态更新入口规则,这很容易导致几分钟的停机时间。

    使用自定义代理,我也认为这是不可能的。请注意,它基本上需要替换 pod 后面的服务。如果您的入口控制器知道它需要将数据包传递给服务,那么现在您必须强制它传递给您的代理。但是怎么做呢?

    【讨论】:

    • 我正在想象一个简单的代理服务,它读取请求的 url 并决定代理到哪个 pod。使用 pod dns 名称应该很简单,对吧?入口 -> 代理服务 -> 代理 pod -> server-3.my-namespace.svc.cluster.local 对吗?
    【解决方案2】:

    Kubernetes 服务是一组 iptables(或 IPVS)规则,它将以 ServiceIP 作为目标地址的数据包重定向到具有相同标签的 ONE OF THE PODS

    来自Kubernetes Services documentation

    该服务安装 iptables 规则以选择后端 Pod。默认情况下,后端的选择是随机的。

    这指的是服务无法区分同一集合中的不同 pod。

    如果您想通过更改 iprules(相当简单)或通过添加任何类型的代理来强制从集合中选择特定 Pod 是有问题的: 假设您配置了pod-1pod-2(分别为1.1.1.11.1.1.2),并且您为目标pod-1.myserver.com1.1.1.1 的DNAT 请求配置了iptables 规则,对于pod-2 也是如此。 (你可能会问为什么是IP,只是因为这是区分这些pod的唯一方法) 每当 pod 重新启动时,这种方法都会失败,假设 pod-1 失败,Kubernetes 不会重新创建具有相同 IP 和名称的相同 pod,而是会创建具有不同 IP 的 pod-3 并相应地更新 iptables。因此,所有发往 1.1.1.1 的数据包都将被丢弃,直到您再次更新代理或 iptables。

    事实上,这就是为什么我们使用服务来访问 Pod 而不是直接访问它们的原因之一,因为 Pod IP 可以更改而服务 IP 不会。

    但是,由于 kubernetes 的这个非常具体的部分是我过去 4 个月的工作,所以我开发了一个 python script 来编辑 iptables 并选择一个特定的 pod,我对这项工作的结论是它既昂贵又耗时 -消耗,并且会在 Pod 更改时强制服务器离线几秒钟,您可以查看代码,它确实有效,但不推荐。

    这个问题是kubernetes的问题,解决方法是修改Kube-proxy的源码,这是我目前的工作。

    我建议你阅读我的回答,解释 kubernetes 服务在这个问题中是如何工作的:Which service is doing load balancing between kubernetes nodes?

    【讨论】:

    • 感谢您的深入回答。使用 StatefulSets,我相信会以完全相同的名称重新创建 pod,因此我至少应该能够可靠地代理它们(当然,当 pod 关闭时连接会失败)。
    • 重新调度的 Pod 的 IP 地址会发生变化,即使 Pod 处于 statefulset 中,你将如何根据名称进行转发,你的意思是使用 DNS?
    • 是的,完全正确,使用 DNS。我以前没有这样做过,所以这只是一个想法,但它似乎应该有效?
    猜你喜欢
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多