You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Kubernetes无选择器Service配置后NodePort外部访问异常求助

排查NodePort Service外部访问不通问题

先梳理下你的场景:你创建了无选择器的NodePort Service,关联了指向Apache主机(监听80端口)的Endpoint,集群内部通过ClusterIP能正常访问,但外部用<节点IP>:31000访问失败。先把你的配置和命令输出贴出来方便参考:

你的Service配置(my-service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - protocol: TCP
    port: 9376
    targetPort: 80
    nodePort: 31000
  type: NodePort

你的Endpoint配置(my-endpoint.yaml)

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
- addresses:
  - ip: <IP>
  ports:
  - port: 80

kubectl get service -o wide 输出

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          53m   <none>
my-service   NodePort    10.111.205.207  <none>        9376:31000/TCP   30m   <none>

接下来咱们一步步排查可能的问题:


1. 先确认节点的端口访问权限

NodePort Service的外部访问依赖节点开放对应的端口(这里是31000),不管是节点本地的防火墙,还是云服务商的安全组/网络ACL,都得允许外部流量访问这个端口:

  • 如果是用firewalld的节点,执行:
    sudo firewall-cmd --add-port=31000/tcp --permanent
    sudo firewall-cmd --reload
    
  • 如果是iptables,执行:
    sudo iptables -A INPUT -p tcp --dport 31000 -j ACCEPT
    
  • 云环境的话,要去对应云平台的安全组规则里,添加入站规则允许TCP 31000端口的访问。

2. 验证Endpoint的目标IP可达性

集群内部能访问,说明Service到Endpoint的转发没问题,但外部访问需要节点能先通到Apache主机:

  • 在任意K8s节点上执行curl <你的Apache主机IP>:80,看看能不能正常返回Apache的页面。如果连节点都访问不了Apache,那外部肯定也不行,得先排查Apache主机的网络(比如防火墙是否允许节点访问80端口,IP是否正确)。
  • 确认my-endpoint.yaml里的<IP>是Apache主机的正确可访问IP(不能是localhost或者仅主机内部的IP,得是集群节点能访问到的IP)。

3. 检查kube-proxy的状态

kube-proxy负责维护Service的转发规则,它要是出问题,NodePort的端口可能不会被监听:

  • 先看kube-proxy的pod是否正常运行:
    kubectl get pods -n kube-system | grep kube-proxy
    
    确保所有节点上的kube-proxy pod都是Running状态,如果有异常,删除对应的pod让它重建:
    kubectl delete pod -n kube-system <kube-proxy-pod-name>
    
  • 检查节点上是否有进程监听31000端口:
    ss -tulpn | grep 31000
    
    正常情况下应该能看到kube-proxy在监听这个端口,如果看不到,说明kube-proxy没同步Service配置,可能需要重启kube-proxy或者检查K8s apiserver的连接。

4. 验证iptables转发规则

K8s默认用iptables做流量转发,咱们可以检查对应的规则是否存在:

iptables-save | grep my-service

或者直接搜31000端口的规则:

iptables-save | grep 31000

如果找不到对应的转发规则,大概率是kube-proxy没生成规则,回到第三步排查kube-proxy的问题。

5. 确认访问用的节点IP是否正确

  • 如果是本地集群(比如minikube、kind),要确认你用的是节点的实际内网IP,而不是localhost(除非你做了端口映射)。
  • 如果是云集群,要确认用的是节点的公网IP,而不是内网IP,内网IP只能在集群内部网络访问。

按照上面的步骤排查,应该能找到问题所在。比如最常见的就是节点防火墙/安全组没开31000端口,或者Endpoint的IP配置错误。

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

火山引擎 最新活动