Kubernetes:使用NodePort服务后,集群外负载均衡的外部集群IP是什么?
好问题!其实NodePort类型的服务本身并不会提供一个统一的外部集群IP,它的设计就是通过每个集群节点的IP加上分配的NodePort端口来暴露服务。不过我们有几种方案可以实现你想要的「统一入口+请求负载均衡」效果,结合你用VirtualBox搭建的本地Ubuntu集群环境,我给你详细说明:
1. 云环境专属:LoadBalancer类型服务(如果你的集群在云服务商平台)
如果你的集群是运行在AWS EKS、GCP GKE、Azure AKS这类托管K8s服务上,只需要把服务类型改成LoadBalancer,云平台会自动为你分配一个公网负载均衡IP,所有外部请求都会通过这个IP自动转发到后端的Pod,并且完成负载均衡。
执行命令修改服务类型:
sudo kubectl expose deployment/nginx-deployment --type=LoadBalancer # 或者修改已有的服务 sudo kubectl patch service nginx-deployment -p '{"spec":{"type":"LoadBalancer"}}'
执行后用kubectl get services查看,EXTERNAL-IP字段会显示云平台分配的公网IP,直接访问这个IP就能统一访问后端服务,无需再加端口(默认会映射80端口)。
2. 本地/私有环境:自建负载均衡器
因为你是在VirtualBox的本地虚拟机集群,没有云服务商的负载均衡支持,最直接的方式是在宿主机或者额外的虚拟机上搭建一个简单的负载均衡器,把请求转发到两个工作节点的NodePort地址。
用Nginx搭建负载均衡示例
创建一个Nginx配置文件lb.conf:
http { upstream nginx_backend { # 两个工作节点的NodePort地址 server 192.168.56.4:32446; server 192.168.56.6:32446; # 默认轮询策略,也可以配置权重、ip_hash等 } server { listen 80; # 负载均衡器监听的端口 location / { proxy_pass http://nginx_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }
启动这个Nginx负载均衡器后,访问它的IP(比如宿主机的IP或者负载均衡器虚拟机的IP),就能统一访问后端的Nginx Pod,并且实现请求的负载均衡。
3. 更灵活的方案:Ingress Controller
如果你需要更复杂的路由规则(比如基于域名、路径转发),可以部署Ingress Controller(比如Nginx Ingress Controller)。它相当于集群的统一入口网关,你只需要配置Ingress规则来指定服务的路由,之后通过Ingress Controller的入口IP就能访问所有服务。
部署Ingress Controller后,你可以创建这样的Ingress资源:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: nginx-deployment port: number: 80
之后访问Ingress Controller暴露的IP(同样可以是NodePort或者LoadBalancer,本地环境用NodePort即可),就能统一访问你的Nginx服务。
补充:当前NodePort服务的隐性负载均衡
其实你当前的NodePort服务已经具备一定的负载均衡能力:当你访问任意一个节点的http://<节点IP>:32446时,Kube-proxy会把请求转发到任意一个后端Pod(不管Pod是否在当前节点上)——这是因为你的服务External Traffic Policy默认是Cluster(从你describe service的输出可以看到)。也就是说,你访问任意一个节点的IP,请求都会被均衡到两个Pod上,只是没有一个统一的入口IP而已。
内容的提问来源于stack exchange,提问作者codependent




