我有一个包含广告管理系统server-0
,server-1
等的状态设置。我想将它们直接暴露在互联网上,网址为server-0.mydomain.com或类似mydomain.com/server- 0
我希望能够扩展StatefulSet并自动从Internet访问新的pod。例如,如果我将其扩展为包含server-2
,我希望mydomain.com/server-2在请求准备就绪时将请求路由到新窗格。我不想也需要扩展其他资源或创建另一个服务来实现这种效果。
我可以使用自定义代理服务来实现这一点,该服务只检查请求路径并在内部转发到正确的pod,但这似乎容易出错且浪费。
有没有办法让Ingress自动路由到StatefulSet中的不同pod,或者其他一些可以避免自定义代码的内置技术?
答案 0 :(得分:3)
我认为你不能这样做。作为同一个有状态集的一部分,所有pod到pod-x都是服务的目标。由于您无法定义哪个pod将获得请求,因此您无法强制将“pod-1.yourapp.com”或“yourapp.com/pod-1”发送到pod-1。它将被发送到服务,服务可能会将其发送到pod-4。
即使可以,您也需要动态更新入口规则,这可能会导致停机时间很短。
使用自定义代理,我认为它也是不可能的。请注意,它基本上需要替换pod后面的服务。如果您的入口控制器知道它需要将数据包传递给服务,那么现在您必须强制它将其传递给您的代理。但是如何?
答案 1 :(得分:1)
Kubernetes服务是一组iptables(或IPVS)规则,它将使用ServiceIP作为目标地址的数据包重定向到具有相同标签的 ONE OF THE PODS 。
来自Kubernetes Services documentation
该服务安装iptables规则,选择后端Pod。默认情况下,后端的选择是随机的。
这指的是服务无法区分同一组中的不同pod。
如果您想通过更改iprules(相当简单)强制选择特定的Pod,或者通过添加任何类型的代理是有问题的:
假设您已配置pod-1
和pod-2
(分别为1.1.1.1
和1.1.1.2
),并且已将iptables规则配置为目标为pod-1.myserver.com
到1.1.1.1
的DNAT请求和pod-2相同。 (你可能会问为什么IP,这只是因为它是区分这些pod的唯一方法)
当pod重新启动时,这种方法将失败,假设pod-1失败,Kubernetes将不会重新创建具有相同IP和名称的相同pod,而是创建具有不同IP的pod-3并相应地更新iptables。因此,在您再次更新代理或iptables之前,所有将转向1.1.1.1的数据包都将被丢弃。
事实上,这是我们使用服务访问pod而不是直接访问pod的原因之一,因为Pod IP可以更改,但服务IP不会。
然而,由于kubernetes的这个非常具体的部分是我过去4个月的工作,我已经开发了一个python script来编辑iptables并选择一个特定的pod,我对该工作的结论是它很省钱,耗时并且会让服务器在更改pod时使其脱机几秒钟,您可以查看代码,它肯定有效但不建议使用。
这个问题是一个kubernetes问题,解决方案正在改变Kube-proxy的源代码,这是我目前的工作。
我建议你阅读我的答案,解释kubernetes服务在这个问题中的确切运作方式:Which service is doing load balancing between kubernetes nodes?