Kubernetes 中的真正负载均衡?

2024-02-29

什么是负载均衡器?

负载平衡改善了多个工作负载的分配 计算资源,例如计算机、计算机集群、网络 链路、中央处理单元或磁盘驱动器

节点端口

NodePort 不是负载均衡器。 (我知道kube-proxy一旦流量进入集群内部,就对 Pod 之间的流量进行负载平衡)我的意思是,最终用户点击http://NODEIP:30111(例如)访问应用程序的 URL。即使流量在 POD 之间进行负载均衡,用户仍然会访问单个节点,即“节点”,它是 K8s 的 minion,但却是真正的负载均衡器,对吧?

入口服务

这里也同样,假设部署了入口控制器和入口服务。我们在 ingress-service 中指定的子域应该指向 K8s 集群中的“a”节点,然后 ingress-controller 对 Pod 之间的流量进行负载均衡。这里最终用户也访问单个节点,它是 K8s 的 minion,但却是一个真正的负载均衡器,对吧?

来自云提供商的负载均衡器(例如AWS ELB)

我有一个疑问,云提供商的LB如何进行负载均衡?这些是否真的将流量分配到部署 PODS 的适当节点,或者只是将流量转发到主节点或 Minion?

如果以上观点为真。真正的负载均衡 Pod/适当节点之间的流量在哪里。

我可以在K8s中实现真正的负载均衡吗?我问了相关的在这里提问 https://stackoverflow.com/questions/51531312/how-to-access-k8ss-flannel-network-from-outside


NodePort 不是负载均衡器。

从某种程度上来说,你是对的,是的,它并不是被设计成负载均衡器的。

用户仍然访问单个节点,即“Node”,它是 K8s 的 minion,但却是真正的负载均衡器,对吧?

有了 NodePort,您have随时命中单个节点,但您必须记住这一点kube-proxy在所有节点上运行。因此,您可以访问集群中任何节点上的 NodePort(甚至是未运行工作负载的节点),并且您仍然会访问您想要访问的端点。这一点稍后会变得很重要。

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

不,事情不是这样的。

您的入口控制器仍然需要暴露在外部。如果您使用云提供商,常用的模式是通过以下服务公开您的入口控制器Type=LoadBalancer。负载平衡仍然发生在服务中,但 Ingress 允许您以更用户友好的方式使用该服务。不要将入口与负载平衡混淆。

我有一个疑问云提供商LB如何进行负载平衡?这些是否真的将流量分配到部署 PODS 的适当节点,或者只是将流量转发到主节点或 Minion?

如果您查看 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

最后,如果您查看集群中的节点数量,您会发现它实际上是all已添加到LoadBalancer的节点:

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

所以,总而言之 - Kubernetesdoes使用服务(无论是 NodePort 还是 LoadBalancer 类型)实现真正的 LoadBalancing,入口只是使该服务更容易被外界访问

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kubernetes 中的真正负载均衡? 的相关文章

随机推荐