Kubernete:为非云集群提出L4负载均衡解决方案

时间:2017-02-21 01:21:37

标签: kubernetes load-balancing

我在本地数据中心建立了一个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个地址之间提供负载均衡服务吗?为这种情况寻求更好的解决方案。

2 个答案:

答案 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)

正如您已经注意到的那样,您必须设置自定义负载均衡器才能使其正常工作。此负载均衡器必须位于群集外部并由您自己配置。

我建议你仔细阅读Ingressingress-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。正如开头所说的那样,你应该阅读有关入口的文档,以便找出它带来的免费内容。