Kubernetes 服务在访问不同工作进程上的 Pod 时超时

Kubernetes 服务在访问不同工作进程上的 Pod 时超时

我正在尝试在 EC2 实例上启动一对 kubernetes 工作程序,但遇到了一个问题,即服务似乎无法“看到”它应该能够看到的所有 pod。

我的实际环境是一对 AWS Snowball,红色和蓝色,我的集群看起来像controlworker-redworker-blue[1]。我正在部署一个虚拟 Python 服务器,它等待端口 8080 上的 GET,并使用本地主机名进行回复。我已为其设置了足够的副本,使worker-redworker-blue至少各有一个 pod。最后,我创建了一个服务,其规范看起来像

spec:
    type: NodePort
    selector:
        app: hello-server
    ports:
        - port: 8080
          targetPort: 8080
          nodePort: 30080

我现在可以检查我的 Pod 是否已启动

kubectl get pods -o wide
NAME                                      READY   STATUS    RESTARTS   AGE   IP              NODE          NOMINATED NODE   READINESS GATES
hello-world-deployment-587468bdb7-hf4dq   1/1     Running   0          27m   192.168.1.116   worker.red    <none>           <none>
hello-world-deployment-587468bdb7-mclhm   1/1     Running   0          27m   192.168.1.126   worker.blue   <none>           <none>

现在我可以尝试卷曲它们

curl worker-red:30080
greetings from hello-world-deployment-587468bdb7-hf4dq
curl worker-blue:30080
greetings from hello-world-deployment-587468bdb7-mclhm

大约有一半的时间会发生这种情况。另一半时间,curl 会因超时错误而失败。具体来说 - curl worker-red 只会产生来自 hf4dq 的响应,而 curl worker-blue 只会产生来自 mclhm 的响应。如果我封锁并排空 worker-blue,这样我的两个 pod 都在 worker-red 上运行,就不会出现超时,并且两个 pod 都会响应。

似乎 NodePort 服务无法到达我正在 curl 的主机上没有的 pod。据我了解,这不是服务应该的工作方式。我遗漏了什么?

[1] 如果我这样设置,让两个工作者都在红色上,那么就会发生我所描述的相同问题,但这是我的主要用例,因此我会集中精力于此。

答案1

很难简单地说出这里可能出了什么问题,但您可以采取一些步骤来解决问题:

  1. 调试 Pod,特别检查日志中是否有可疑的内容:
  • kubectl logs ${POD_NAME} ${CONTAINER_NAME}

  • kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}

  1. 调试服务,例如通过检查:
  • 该服务存在吗?

  • 该服务是否通过 DNS 名称工作?

  • 该服务通过 IP 运作吗?

  • 服务定义是否正确?

  • 该服务有任何端点吗?

  • kube-proxy 正在工作吗?

完成这些步骤将帮助您找到问题的原因并更好地了解服务背后的机制。

答案2

您正在使用NodePort类型服务,在这种情况下,您所观察到的情况是非常符合预期的。

您的服务与在两个不同节点上运行的 2 个 pod 相匹配。由于服务类型为NodePort,因此服务的 pod 与其运行的节点之间存在固有关联。如果您 curl 端点worker-red,您将仅有的从 pod 获得响应worker-red,这是因为另一个 pod 绑定到另一个端点worker-blue:<node-port>,无法从worker-red端点访问。是的,它是同一项服务,但它由 2 个端点支持,每个端点都有不同的主机名。

这就是NodePort服务的基本运作方式。

当您将它们捆绑在同一个节点上时,两个 pod 都可以从同一个节点主机名访问,因此对它们进行 curl 操作将起作用。从现在起,两个端点都映射到不同的端口,但相同的主机名

为了进一步理解这一点,您可以尝试将服务类型更改为LoadBalancer。您会注意到,无论将两个 Pod 安排在何处,您都可以使用相同的主机名访问它们。此主机名/IP 地址将是LoadBalancer服务中所有 Pod 共同拥有的地址。

我希望这能解答您的困惑!

相关内容