Kubernetes集群中的Pod之间出现连接拒绝错误

5

我刚开始学习Kubernetes,并正在新的Kubernetes群集中部署应用程序。

目前,正在运行的服务有多个pod需要相互通信。我正在寻求一种通用方法来调试此问题,而不是涉及到服务的具体规范,因为这样的问题将变得过于特定。

群集中的Pod会抛出错误: err="Get \"http://testpod.mynamespace.svc.cluster.local:8080/": dial tcp 10.10.80.100:8080: connect: connection refused" 这两个Pod都在同一个群集中。

有哪些最佳步骤可以调试此问题?

我尝试运行: kubectl exec -it testpod --namespace mynamespace -- cat /etc/resolv.conf 并返回以下内容: search mynamespace.svc.cluster.local svc.cluster.local cluster.local us-east-2.compute.internal 我在这里找到了它:https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/


2
我猜测这是因为你的Pod绑定到了127.0.0.1而不是0.0.0.0(最近这是一个常见的主题);此外,那些URL通常是用于“Service”名称而不是“Pod”名称,所以要注意你正在请求的对象是否是你认为的对象。 - mdaniel
1
感谢@mdaniel的评论,在我疯狂地花了一天时间寻找我的清单文件有什么问题后,你的评论拯救了我,结果发现它绑定到了127.0.0.1。 - Iszlai Lehel
1个回答

10

首先,以下模式:

my-svc.my-namespace.svc.cluster-domain.example

仅适用于服务的FQDNs,不适用于具有以下形式的Pods:

pod-ip-address.my-namespace.pod.cluster-domain.example

e.g.:

172-17-0-3.default.pod.cluster.local

事实上,您正在向集群DNS查询名为“testpod”的Service的FQDN,而不是Pod的FQDN。从成功解析的事实来看,这样的Service已经存在于您的集群中,但很可能配置不正确。您收到“连接被拒绝”的错误消息,可能意味着以下情况:
  1. 您的 Service FQDN testpod.mynamespace.svc.cluster.local 已成功解析(否则您将收到类似于 curl: (6) Could not resolve host: testpod.default.svc.cluster.local 的错误信息)。
  2. 您已成功访问了您的 testpod Service(否则,如果存在但未在您尝试连接的 8080 端口上监听,则会收到 timeout 错误信息,例如 curl: (7) Failed to connect to testpod.default.svc.cluster.local port 8080: Connection timed out)。
  3. 您已经访问了由 testpod Service 公开的 Pod(您已被 testpod Service 成功重定向到它)。
  4. 但是一旦访问了 Pod,您正在尝试连接到不正确的端口,这就是服务器拒绝连接的原因。
我的最佳猜测是,您的Pod实际上监听了不同的端口,比如80,但您通过指定只有--port值的ClusterIPService来暴露它。
kubectl expose pod testpod --port=8080

在这种情况下,--portService的端口)和--targetPortPod的端口)将具有相同的值。换句话说,您创建了一个如下所示的Service
apiVersion: v1
kind: Service
metadata:
  name: testpod
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

你可能应该这样公开它:

kubectl expose pod testpod --port=8080 --targetPort=80

或者使用以下的yaml清单:
apiVersion: v1
kind: Service
metadata:
  name: testpod
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 80

当然,你的targetPort可能与80不同,但在这种情况下connection refused只能意味着一个问题: 目标http服务器(运行在Pod中)拒绝连接到8080端口(很可能是因为它没有在监听该端口)。你没有指定使用的镜像是什么,是标准的nginx Web服务器还是基于你自定义的镜像。但如果是nginx且未进行不同配置,则会监听端口80

如需进一步调试,可以连接到你的Pod

kubectl exec -it testpod --namespace mynamespace -- /bin/sh

如果没有netstat命令(这是最有可能的情况),请运行:

apt update && apt install net-tools

然后使用 netstat -ntlp 命令检查您的容器监听的端口。

我希望这可以帮助您解决问题。如有疑问,请随时询问。


1
谢谢 - 是的,它给了我足够的信息完全解决了这个问题。 - fuzzi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接