首页 文章

Kubernete:为非 Cloud 集群询问L4负载 balancer 解决方案

提问于
浏览
0

我在本地数据中心 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 回答

  • 1

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

    我建议你仔细阅读Ingressingress-controller的概念 . 特别是nginx-ingress-controller在这里非常有用 .

    优点是您只需要设置一次自定义外部负载均衡器,而不是您要公开的所有服务 . 您的负载均衡器应 balancer 到入口控制器的流量,然后根据提供的 Ingress 资源执行内部负载 balancer .

    要部署入口控制器,应该足以执行以下操作:

    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 ,用于所有不匹配的入口 . 它基本上只返回 404

    第二行默认创建一个带有1个副本的 Deployment . 在prod环境中,您可能希望通过扩展部署或使用 nginx-ingress-controller.yaml 文件的本地修改副本来更改副本计数 . 此外,我建议在入口控制器中使用专用节点(通过使用DaemonSet NodeAffinity Taints Tolerations),以防您需要大量流量 .

    入口控制器现在可以在不暴露的情况下运行 . 我假设暴露控制器不是示例的一部分,因为这根据使用的基础设施而变化太大 . 在您的情况下,您应该创建一个Kubernetes 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 资源以将外部流量定向到内部服务 . 例如:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: example-ingress
    spec:
      rules:
      - host: example.company.org
        http:
          paths:
          - path: /
            backend:
              serviceName: example-service
              servicePort: 8080
    

    如果您的数据中心DNS设置要将 example.company.org 解析为外部负载均衡器,则调用它将直接将您带到 example-service

    所有这些听起来可能更复杂,只需使用NodePort并更改外部负载均衡器的配置以用于新服务 . 但如果设置一次,配置和自动化就会大大简化 . 它还提供了大量新功能,否则必须手动实现 . 例如,通过简单地向 Ingress 资源添加注释,nginx-ingress-controller本身支持基本身份验证 . 当与 kube-lego 结合使用时,它还支持letsencrypt . 正如开头所说,你应该阅读有关入口的文档,以找出它带来的免费内容 .

  • 1

    独立于 LoadBalancer 所在的位置,您可以在节点之间 balancer 虚拟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流量 .

    缺点是外部负载 balancer 器的配置和服务的IP分配不是自动的,必须手动完成 . 要缓解此问题,您可以实现自己的提供程序(请参阅其他provider implementations on Github),也可以从etcd读取服务配置并将其用作配置外部负载均衡器 .

相关问题