我在本地数据中心 Build 了一个Kubernete集群 . 有4个节点和1个主节点 . 寻找内部服务的L4负载均衡解决方案 .
root@niubi01:/home/mesos# kubectl get nodes
NAME STATUS AGE
niubi01 Ready,master 7d
niubi02 Ready 7d
niubi03 Ready 7d
niubi04 Ready 7d
niubi05 Ready 7d
假设我们有三个带有'hello world'网络服务的Pod . 使用“NodePort”创建具有外部外部IP的服务 . 外部IP是“节点”,端口是30145 .
root@niubi01:/home/mesos# kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
example-service 10.100.220.21 <nodes> 8080:30145/TCP 6d
如上所述,我们可以访问任何节点IP来访问这个“hello world”服务 . 喜欢:
curl http://niubi01:30145
curl http://niubi02:30145
curl http://niubi03:30145
curl http://niubi04:30145
curl http://niubi05:30145
从外面 . 问题是我们无法保证任何节点永远活跃,即使是高手 . 我们应该使用哪个URL?如何像Haproxy这样的LoadBalance为这项服务提供高可用性?我们应该让另外一台服务器在这5个地址之间提供负载均衡服务吗?为这种情况寻求更好的解决方案 .
2 回答
正如您已经注意到的那样,您必须设置自定义负载均衡器才能使其正常工作 . 此负载均衡器必须位于群集外部并由您自己配置 .
我建议你仔细阅读Ingress和ingress-controller的概念 . 特别是nginx-ingress-controller在这里非常有用 .
优点是您只需要设置一次自定义外部负载均衡器,而不是您要公开的所有服务 . 您的负载均衡器应 balancer 到入口控制器的流量,然后根据提供的
Ingress
资源执行内部负载 balancer .要部署入口控制器,应该足以执行以下操作:
第一行创建
default-backend
,用于所有不匹配的入口 . 它基本上只返回404
第二行默认创建一个带有1个副本的
Deployment
. 在prod环境中,您可能希望通过扩展部署或使用nginx-ingress-controller.yaml
文件的本地修改副本来更改副本计数 . 此外,我建议在入口控制器中使用专用节点(通过使用DaemonSet NodeAffinity Taints Tolerations),以防您需要大量流量 .入口控制器现在可以在不暴露的情况下运行 . 我假设暴露控制器不是示例的一部分,因为这根据使用的基础设施而变化太大 . 在您的情况下,您应该创建一个Kubernetes
Service
,通过部署此资源将入口控制器公开为NodePort
:请注意,
nodePort
在此处明确指定 . 这使您在配置外部负载均衡器时更轻松 .完成所有设置后,您可以创建
Ingress
资源以将外部流量定向到内部服务 . 例如:如果您的数据中心DNS设置要将
example.company.org
解析为外部负载均衡器,则调用它将直接将您带到example-service
所有这些听起来可能更复杂,只需使用NodePort并更改外部负载均衡器的配置以用于新服务 . 但如果设置一次,配置和自动化就会大大简化 . 它还提供了大量新功能,否则必须手动实现 . 例如,通过简单地向
Ingress
资源添加注释,nginx-ingress-controller本身支持基本身份验证 . 当与kube-lego
结合使用时,它还支持letsencrypt . 正如开头所说,你应该阅读有关入口的文档,以找出它带来的免费内容 .独立于
LoadBalancer
所在的位置,您可以在节点之间 balancer 虚拟IP地址并将其包含在服务定义中,如图所示in the documentation:一旦此IP(
80.11.12.10
)的流量到达任何节点,kube-proxy
将重定向到您的服务 .实现这一点的一个选择是在节点上使用Pacemaker,如许多blog posts中所述 . 但是在集群前面有一个专用的负载均衡器也可以正常工作 .
使用虚拟IP的好处是您不必在防火墙或相关配置中弄乱NodePort . 另一个好处是,这不仅限于HTTP流量 .
缺点是外部负载 balancer 器的配置和服务的IP分配不是自动的,必须手动完成 . 要缓解此问题,您可以实现自己的提供程序(请参阅其他provider implementations on Github),也可以从etcd读取服务配置并将其用作配置外部负载均衡器 .