我正在管理一个安装在 CentOS 7 上的独立 kubernetes(v 1.17.2)集群,该集群具有单个 API 服务器和两个用于 pod 的工作节点。
其中一个服务配置为节点端口服务,但我无法从其他节点访问该服务。我对 Kubernetes 不是很有经验,但以下是我所知道的
kube-proxy
正在执行其工作。相关端口 (31505) 在每个节点上均已打开(使用 进行检查lost -i
)。服务已启动,我可以从运行 pod 的节点端口正常访问它。
- Docker 配置有
no-iptables
选项,所有防火墙规则由 Kubernetes 本身管理。- 停止
kubelet
并docker
刷新所有 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 的工作人员之间的通信无法进行。
更新安全组后,一切都按预期运行。