我正在尝试在 EC2 实例上启动一对 kubernetes 工作程序,但遇到了一个问题,即服务似乎无法“看到”它应该能够看到的所有 pod。
我的实际环境是一对 AWS Snowball,红色和蓝色,我的集群看起来像control
、worker-red
和worker-blue
[1]。我正在部署一个虚拟 Python 服务器,它等待端口 8080 上的 GET,并使用本地主机名进行回复。我已为其设置了足够的副本,使worker-red
和worker-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
答案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 共同拥有的地址。
我希望这能解答您的困惑!