我在本地数据中心建立了一个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'网络服务。使用' 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&#39;服务。像:
curl http://niubi01:30145
curl http://niubi02:30145
curl http://niubi03:30145
curl http://niubi04:30145
curl http://niubi05:30145
来自外面。 问题是我们无法保证任何节点永远有效,甚至是主节点。我们应该使用哪个URL? 如何像Haproxy这样的LoadBalance为这项服务提供高可用性? 我们应该让另外一台服务器在这5个地址之间提供负载均衡服务吗?为这种情况寻求更好的解决方案。
答案 0 :(得分:1)
独立于LoadBalancer
所在位置,您可以在节点之间平衡虚拟IP地址并将其包含在服务定义中,如图所示in the documentation:
---
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
externalIPs:
- 80.11.12.10
此IP(80.11.12.10
)的流量点击任何节点后,kube-proxy
会将其重定向到您的服务。
实现这一点的一个选择是在节点上使用Pacemaker,如许多blog posts中所述。但是在集群前面有一个专用的负载均衡器也可以正常工作。
使用虚拟IP的好处是您不必在防火墙或相关配置中弄乱NodePort。另一个好处是,这不仅限于HTTP流量。
缺点是外部负载均衡器的配置和服务的IP分配不是自动的,必须手动完成。要缓解此问题,您可以实现自己的提供程序(请参阅其他provider implementations on Github),也可以从etcd读取服务配置,并将其用作外部负载均衡器配置的源。
答案 1 :(得分:1)
正如您已经注意到的那样,您必须设置自定义负载均衡器才能使其正常工作。此负载均衡器必须位于群集外部并由您自己配置。
我建议你仔细阅读Ingress
和ingress-controller
的概念。特别是nginx-ingress-controller在这里非常有用。
优点是您只需要设置一次自定义外部负载均衡器,而不是仅为您要公开的所有服务设置。您的负载均衡器应该平衡流量到入口控制器,然后根据提供的Ingress
资源进行内部负载平衡。
要部署入口控制器,应该足以执行以下操作:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress/master/examples/deployment/nginx/default-backend.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress/master/examples/deployment/nginx/nginx-ingress-controller.yaml
第一行创建一个default-backend
,用于所有不匹配的入口。它基本上只返回{{1}}
默认情况下,第二行创建一个404
,其中包含1个副本。在prod环境中,您可能希望通过扩展Deployment或使用Deployment
文件的本地修改副本来更改副本计数。另外,我建议使用专用节点(通过使用DaemonSet + NodeAffinity + Taints + Tolerations)来控制入口控制器,以防万一你需要大量的流量。
入口控制器现在可以在不暴露的情况下运行。我假设暴露控制器不是示例的一部分,因为这根据使用的基础设施而变化太大。在您的情况下,您应该创建一个Kubernetes nginx-ingress-controller.yaml
,通过部署此资源将入口控制器公开为Service
:
NodePort
请注意,此处明确指定了apiVersion: v1
kind: Service
metadata:
name: nginx-ingres-controller-svc
labels:
name: nginx-ingres-controller-svc
namespace: kube-system
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
name: http
- port: 443
nodePort: 30443
name: https
selector:
k8s-app: nginx-ingress-controller
。这可以在配置外部负载均衡器时使生活更轻松。
设置完毕后,您可以创建nodePort
资源,将外部流量引导到内部服务中。例如:
Ingress
如果您的数据中心DNS设置已将apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.company.org
http:
paths:
- path: /
backend:
serviceName: example-service
servicePort: 8080
解析为外部负载均衡器,则调用它会直接将您带到example.company.org
所有这些听起来可能更复杂,只需使用NodePort并更改外部负载均衡器的配置以获得新服务。但如果设置一次,配置和自动化就会大大简化。它还提供了大量新功能,否则必须手动实现。例如,通过简单地向example-service
资源添加注释,nginx-ingress-controller本身支持基本身份验证。当与Ingress
结合使用时,它还支持letsencrypt。正如开头所说的那样,你应该阅读有关入口的文档,以便找出它带来的免费内容。