首页 文章

Kubernetes中的真正负载均衡?

提问于
浏览
4

什么是负载均衡器?

负载 balancer 可改善跨多种计算资源(例如计算机,计算机群集,网络链接,中央处理单元或磁盘驱动器)的工作负载分布

NodePort

NodePort不是负载均衡器 . (我知道,一旦流量在集群内部, kube-proxy 负载均衡pod之间的流量)我的意思是,最终用户点击 http://NODEIP:30111 (例如)URL来访问应用程序 . 即使POD之间的流量负载均衡,用户仍然会遇到单个节点,即"Node",这是K8s的小兵,但是真正的负载均衡器,对吧?

入口服务

在这里也是如此,想象一下入口控制器的部署和入口服务 . 我们在入口服务中指定的子域应指向K8s集群中的“a”节点,然后入口控制器负载 balancer pod之间的流量 . 在这里,终端用户也会遇到单个节点,这是K8s的仆从,但是真正的负载均衡器,对吗?

来自 Cloud 提供商的

负载均衡器(例如AWS ELB)

我有一个疑问, Cloud 提供商的LB如何进行负载 balancer ?那些是否真的将流量分配到部署了PODS的适当节点,或者只是将流量转发到主节点或小型设备?

如果以上是真的 . 在pod /适当节点之间 balancer 流量的真实负载在哪里 .

我可以在K8中实现真正的负载 balancer 吗?我问了一个相关的question here

1 回答

  • 1

    NodePort不是负载均衡器 .

    你是以某种方式对待这一点,是的,它不是设计为负载均衡器 .

    用户仍然点击一个节点,即“节点”,这是K8s的小兵,但真正的负载均衡器,对吗?

    使用NodePort,您必须在任何时候点击一个节点,但您必须记住 kube-proxy 正在所有节点上运行 . 因此,您可以在群集中的任何节点上点击NodePort(即使是一个节点,工作负载仍然没有达到您想要命中的 endpoints . 这在以后变得很重要 .

    我们在ingress-service中指定的子域应指向K8s群集中的“a”节点

    不,这不是它的工作原理 .

    您的入口控制器需要外部暴露 . 如果您使用的是 Cloud 提供商,则常用的模式是使用 Type=LoadBalancer 服务公开您的入口控制器 . LoadBalancing仍然适用于服务,但Ingress允许您以更加用户友好的方式使用该服务 . 不要将入口与负载均衡混淆 .

    我怀疑 Cloud 提供商LB如何进行负载 balancer ?那些是否真的将流量分配到部署了PODS的适当节点,或者只是将流量转发到主节点或小型设备?

    如果你看一下Kubernetes的配置服务,你会明白为什么它有意义 .

    这是一个类型LoadBalancer的服务:

    kubectl get svc nginx-ingress-controller -n kube-system                                                                    
    NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP        PORT(S)                      AGE
    nginx-ingress-controller   LoadBalancer   <redacted>   internal-a4c8...   80:32394/TCP,443:31281/TCP   147d
    

    你可以看到我部署了一个类型为LoadBalancer的入口控制器 . 这创建了一个AWS ELB,但也注意到,就像 NodePort 它将入口控制器pod上的端口80映射到端口 32394 .

    那么,让我们看一下AWS中的实际LoadBalancer:

    aws elb describe-load-balancers --load-balancer-names a4c80f4eb1d7c11e886d80652b702125
    
    {
        "LoadBalancerDescriptions": [
            {
                "LoadBalancerName": "a4c80f4eb1d7c11e886d80652b702125",
                "DNSName": "internal-a4c8<redacted>",
                "CanonicalHostedZoneNameID": "<redacted>",
                "ListenerDescriptions": [
                    {
                        "Listener": {
                            "Protocol": "TCP",
                            "LoadBalancerPort": 443,
                            "InstanceProtocol": "TCP",
                            "InstancePort": 31281
                        },
                        "PolicyNames": []
                    },
                    {
                        "Listener": {
                            "Protocol": "HTTP",
                            "LoadBalancerPort": 80,
                            "InstanceProtocol": "HTTP",
                            "InstancePort": 32394
                        },
                        "PolicyNames": []
                    }
                ],
                "Policies": {
                    "AppCookieStickinessPolicies": [],
                    "LBCookieStickinessPolicies": [],
                    "OtherPolicies": []
                },
                "BackendServerDescriptions": [],
                "AvailabilityZones": [
                    "us-west-2a",
                    "us-west-2b",
                    "us-west-2c"
                ],
                "Subnets": [
                    "<redacted>",
                    "<redacted>",
                    "<redacted>"
                ],
                "VPCId": "<redacted>",
                "Instances": [
                    {
                        "InstanceId": "<redacted>"
                    },
                    {
                        "InstanceId": "<redacted>"
                    },
                    {
                        "InstanceId": "<redacted>"
                    },
                    {
                        "InstanceId": "<redacted>"
                    },
                    {
                        "InstanceId": "<redacted>"
                    },
                    {
                        "InstanceId": "<redacted>"
                    },
                    {
                        "InstanceId": "<redacted>"
                    },
                    {
                        "InstanceId": "<redacted>"
                    }
                ],
                "HealthCheck": {
                    "Target": "TCP:32394",
                    "Interval": 10,
                    "Timeout": 5,
                    "UnhealthyThreshold": 6,
                    "HealthyThreshold": 2
                },
                "SourceSecurityGroup": {
                    "OwnerAlias": "337287630927",
                    "GroupName": "k8s-elb-a4c80f4eb1d7c11e886d80652b702125"
                },
                "SecurityGroups": [
                    "sg-8e0749f1"
                ],
                "CreatedTime": "2018-03-01T18:13:53.990Z",
                "Scheme": "internal"
            }
        ]
    }
    

    这里要注意的最重要的事情是:

    LoadBalancer将ELB中的端口80映射到NodePort:

    {
                    "Listener": {
                        "Protocol": "HTTP",
                        "LoadBalancerPort": 80,
                        "InstanceProtocol": "HTTP",
                        "InstancePort": 32394
                    },
                    "PolicyNames": []
     }
    

    您还会看到有多个目标 Instances ,而不是一个:

    aws elb describe-load-balancers --load-balancer-names a4c80f4eb1d7c11e886d80652b702125 | jq '.LoadBalancerDescriptions[].Instances | length'
    8
    

    最后,如果你看一下我的集群中的节点数,你实际上已经添加到LoadBalancer的所有节点了:

    kubectl get nodes -l "node-role.kubernetes.io/node=" --no-headers=true | wc -l                                             
    8
    

    总而言之--Kubernetes确实使用服务(无论是NodePort还是LoadBalancer类型)实现真正的LoadBalancing,并且入口只是使外部世界更容易访问该服务

相关问题