You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从外部访问跨云服务商Linux节点的Kubernetes集群?

问题背景

我有1个Master节点和2个Worker节点,不想使用托管式Kubernetes解决方案,服务器分布在不同云服务商(不确定是否有影响)。我需要访问Web应用,但不确定直接连接Pod还是使用负载均衡方案更合适。目前应用仅运行在一个节点上,但后续需要扩容,因此需要支持动态查找的方案。尚未尝试Ingress,不确定其是否有用。

曾尝试使用NodePort(因为当前仅运行一个副本)但未成功,且了解到NodePort存在安全风险。之后尝试使用MetalLB(由于未使用云负载均衡器),已分配<External-IP>(从两个Worker节点的IP范围中分配的私有IP),本以为可以通过集群内任意节点(例如Worker1访问Worker2)连接应用,但仍然无法连接。优先希望使用MetalLB,若不可行也可以退回NodePort方案。

我知道遗漏了某些配置,可能是iptables规则(未调整过,不清楚需要更新哪个链)或者Service配置错误。当前使用Flannel CNI作为容器网络接口,已安装tcpdump和arping工具,仅在承载负载均衡器的节点上arping可用,其他节点均无法正常使用。作为Kubernetes初学者,肯定存在配置错误,感觉无论是NodePort还是负载均衡方案都接近成功了。

最终目标:
从任意位置执行 curl http://<some-ip>:8000

参考资料:

  • MetalLB相关教程(已更新为最新IPAddressPool CRD)
  • Kubernetes官方NodePort文档
  • 《The Kubernetes Book》及补充阅读材料

我的MetalLB配置:

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: dispatch
  namespace: metallb-system
spec:
  ipAddressPools:
  - config
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  namespace: metallb-system
  name: config
spec:
  addresses:
    - <worker1的IP范围> # 基于worker1的IP
    - <worker2的IP范围> # 基于worker2的IP
apiVersion: v1
kind: Service
metadata:
  name: app-balancer
spec:
  type: LoadBalancer
  ports:
  - name: app
    port: 8000
    protocol: TCP
    targetPort: 8000
  selector:
    app: my-app

解决方案

一、MetalLB问题排查与修复

1. 修正IP地址池配置

MetalLB的L2模式要求分配的IP必须是集群节点所在网络中未被占用的空闲IP段,不能直接使用Worker节点自身的IP(节点已占用该IP)。例如如果Worker1是192.168.1.10、Worker2是192.168.1.11,可配置192.168.1.20-192.168.1.30这类未被使用的IP范围。

2. 验证MetalLB资源状态

执行以下命令检查资源是否正常关联:

kubectl get ipaddresspools -n metallb-system
kubectl get l2advertisements -n metallb-system

确保config IPAddressPool状态为Ready,L2Advertisement的ipAddressPools字段确实关联了该Pool名称。

3. 兼容Flannel网络配置

Flannel默认配置可能影响MetalLB的L2广播,需开启hairpinMode:
编辑Flannel的ConfigMap:

kubectl edit cm kube-flannel-cfg -n kube-system

在net-conf.json中添加"hairpinMode": true,随后重启Flannel DaemonSet:

kubectl rollout restart ds kube-flannel-ds -n kube-system

4. 节点网络与iptables检查

  • 所有节点防火墙需放行8000端口,以及MetalLB集群通信端口:7946/TCP/UDP、4789/UDP。
  • 检查Kubernetes的iptables规则是否包含MetalLB Service条目:
iptables-save | grep app-balancer

若无相关规则,重启kubelet服务:

systemctl restart kubelet

5. 确认Service与Pod标签匹配

检查Service的selectorapp: my-app是否和Pod的标签完全一致:

kubectl get pods --show-labels
kubectl describe service app-balancer

查看Service的Endpoints字段,若为空则说明标签不匹配,需修正Pod或Service的标签。

二、NodePort方案修复

如果MetalLB暂时无法解决,可先让NodePort正常运行:

1. 配置正确的NodePort Service

修改Service为NodePort类型:

apiVersion: v1
kind: Service
metadata:
  name: app-nodeport
spec:
  type: NodePort
  ports:
  - name: app
    port: 8000
    protocol: TCP
    targetPort: 8000
    nodePort: 30000 # 可选,指定30000-32767之间的端口
  selector:
    app: my-app

2. 网络连通性检查

  • 所有Worker节点防火墙放行指定的NodePort(如30000)。
  • 确认Pod的8000端口正在监听:
kubectl exec <pod-name> -- netstat -tulpn | grep 8000
  • 从集群内节点测试:curl http://<worker-ip>:30000,若不通则检查kube-proxy状态:
kubectl get pods -n kube-system | grep kube-proxy
kubectl logs <kube-proxy-pod-name> -n kube-system

三、Ingress的作用(后续扩容建议)

当后续应用扩容多副本后,Ingress可统一管理域名、路径转发、SSL证书等,比直接使用Service更灵活。不过Ingress需要搭配Ingress Controller(如nginx-ingress),可等Service正常运行后再部署。


内容的提问来源于stack exchange,提问作者enjoi4life411

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:04:56