无法从除 Pod 之外的其他工作节点访问 Kubernetes NodePort

无法从除 Pod 之外的其他工作节点访问 Kubernetes NodePort

我正在管理一个安装在 CentOS 7 上的独立 kubernetes(v 1.17.2)集群,该集群具有单个 API 服务器和两个用于 pod 的工作节点。

其中一个服务配置为节点端口服务,但我无法从其他节点访问该服务。我对 Kubernetes 不是很有经验,但以下是我所知道的

  • kube-proxy正在执行其工作。相关端口 (31505) 在每个节点上均已打开(使用 进行检查lost -i)。

  • 服务已启动,我可以从运行 pod 的节点端口正常访问它。

  • Docker 配置有no-iptables选项,所有防火墙规则由 Kubernetes 本身管理。
    • 停止kubeletdocker刷新所有 IPTables 规则并强制 kubernetes 重新创建它们并不能解决问题。
  • Kubernetes 集群内的所有其他服务均按预期运行。

服务详情kubectl get svc -o wide --namespace docker-registry docker-registry-deployment如下:

NAME                         TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE   SELECTOR
docker-registry-deployment   NodePort   10.104.194.201   <none>        5000:31505/TCP   67d   app=docker-registry

的输出kubectl describe svc docker-registry-deployment --namespace registry如下:

Name:                     docker-registry-deployment
Namespace:                registry
Labels:                   app=docker-registry
Annotations:              <none>
Selector:                 app=docker-registry
Type:                     NodePort
IP:                       10.104.194.201
Port:                     <unset>  5000/TCP
TargetPort:               5000/TCP
NodePort:                 <unset>  31505/TCP
Endpoints:                10.244.1.65:5000
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Cluster IP:5000在当前状态下,无法从任何节点通过 访问该 pod ,但Endpoint:5000可以访问并且其响应应有。


更新(2020-04-14)

服务和 Pod 没有命名空间问题。它们位于同一个命名空间中。

我已经完全更新了安装(包括 Docker 和 Kubernetes),问题已经发生了变化。现在,其他节点也响应了,但恰好在 63 秒之后

将尝试调试问题并在此报告。

答案1

我终于找到问题了。

它是flannel、复杂的cni网络结构和虚拟化的结合。

flannel 正在实现其节点到节点路由网络,vxlan并在 vxlan 设备上启用卸载功能。

在 flannel 设备上启用卸载时,NodePort跨节点访问会经历 63 秒的路由延迟。使用以下方法关闭卸载后,延迟会消失:

ethtool --offloading tx off rx off flannel.1

我的集群在 Proxmox 环境中运行,网卡是virtio设备。我认为问题不在于虚拟化层,因为我在同一个 Proxmox 节点上还有另一个集群,一切运行正常。由于它是一个生产集群,因此更新频率并不高。

所以这个被标记为 flannel 错误。现在我将尝试更新 flannel 并查看会发生什么。

更新:法兰绒在这个特定的集群上进行了更新,并且运行良好。

答案2

如果我理解正确的话,问题在于除非您直接向 EndPoint 发送请求,否则您无法访问应用程序。

对我来说,这似乎是 的问题Service。根据您提供的信息,服务是在 中创建的,--namespace docker-registry并且应该将流量传递给app=docker-registry位于 下的docker-registry-deployment不同命名空间中创建的 (Namespace: registry)。

请注意,NodePort 服务应该在与部署相同的命名空间中创建。如果你真的需要你的服务和应用程序位于不同的 NS 中,请查看此主题堆栈溢出

我已经创建了部署和两个服务(一个与部署在同一个NS中,另一个在不同的NS中)。

我的配置如下所示。命名空间

$ kubectl get namespaces
NAME                   STATUS   AGE
default                Active   108d
namespace-a            Active   48d

服务:

$ kubectl get svc --namespace namespace-a knp-hello-go-deploy-namespace-a
NAME                  TYPE       CLUSTER-IP   PORT(S)          AGE     SELECTOR
knp-hello-go-deploy   NodePort   10.0.0.253   8180:30050/TCP   2m53s   app=knp-hello-go-app

$ kubectl get svc --namespace default knp-hello-go-deploy -o wide 
NAME                  TYPE       CLUSTER-IP   PORT(S)          AGE     SELECTOR
knp-hello-go-deploy   NodePort   10.0.12.114  8180:32673/TCP   3h21m   app=knp-hello-go-app

我运行了 2 个 GKE 节点。因此我检查了我的 pod 所在的节点并登录到另一个节点。

通过 CLUSTER-IP 检查

gke-node-mnnv:~$ curl 10.0.12.114:8180/test
Hello from ServerGo. You requested: /test 

gke-node-mnnv:~$ curl 10.0.0.253:8180
curl: (7) Failed to connect to 10.0.0.253 port 8180: Connection refused

通过 GKE-Node 外部 IP 检查:

gke-node-mnnv:~$ curl GKE_NodeIP:32673/test
Hello from ServerGo. You requested: /test

gke-node-mnnv:~$ curl GKE_NodeIP:30050/test
curl: (7) Failed to connect to GKE_NodeIP port 30050: Connection refused

希望有帮助!)

答案3

简短回答:您必须打开 UDP 通信协议才能进行节点通信。

长答案:问题出在 VXLAN 隧道上,我在环境中使用 AWS,并且我只允许节点之间使用所有 TCP,而不允许使用 UDP,因此使用 VXLAN 的工作人员之间的通信无法进行。

更新安全组后,一切都按预期运行。

相关内容