我正在尝试编写一个所有 pod 都相互连接的应用程序。我已阅读文档:
Pod 的序号、主机名、SRV 记录和 A 记录名称未更改,但与 Pod 关联的 IP 地址可能已更改。在本教程使用的集群中,他们有。这就是为什么不要将其他应用程序配置为通过 IP 地址连接到 StatefulSet 中的 Pod 很重要的原因。
如果您需要查找并连接到 StatefulSet 的活动成员,则应查询无头服务的 CNAME (
nginx.default.svc.cluster.local
)。与 CNAME 关联的 SRV 记录将仅包含 StatefulSet 中正在运行和就绪的 Pod。如果您的应用程序已经实现了测试活动性和就绪性的连接逻辑,您可以使用 Pod 的 SRV 记录 (
web-0.nginx.default.svc.cluster.local
,web-1.nginx.default.svc.cluster.local
),因为它们是稳定的,并且您的应用程序将能够在 Pod 转换为 Running 和准备好。
我虽然可以通过以下方式做到这一点:
- 查找服务的 SRV 记录以检查哪些 pod 已准备就绪
- 连接到所有准备好的 pod
- 打开表示准备就绪的端口
但是,当我开始在 minikube 上实现它时,它似乎很活泼,当我查询 A/SRV 记录时:
- 在第一个节点上,我在打开端口之前没有找到记录错误(听起来不错)
- 在第二个节点上,有时我找不到记录,有时只有一条记录
- 在第三个节点上,我有时会得到一条记录,有时会得到两条记录
在我看来,更新 DNS 记录和 statefulset 启动之间存在竞争。我不完全确定我做错了什么以及我如何误解了文档。
apiVersion: v1
kind: Service
metadata:
name: hello-world-lb
labels:
app: hello-world-lb
spec:
ports:
- port: 8080
name: web
type: LoadBalancer
selector:
app: hello-world
---
apiVersion: v1
kind: Service
metadata:
name: hello-world
labels:
app: hello-world
spec:
ports:
- port: 8080
name: web
- port: 3080
name: hello-world
clusterIP: None
selector:
app: hello-world
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: hello-world
spec:
selector:
matchLabels:
app: hello-world
serviceName: "hello-world"
replicas: 3
template:
metadata:
labels:
app: hello-world
spec:
terminationGracePeriodSeconds: 10
containers:
- name: hello-world
image: hello-world
imagePullPolicy: Never
ports:
- containerPort: 8080
name: web
- containerPort: 3080
name: hello-world
livenessProbe:
tcpSocket:
port: 8080
编辑目前代码如下:
hello-world.default.svc.cluster.local.
查询/的A / SRV记录_hello-world._tcp.hello-world.default.svc.cluster.local.
并打印调试- 绑定3080端口开始监听(连接逻辑未实现)
- 打开8080端口
我预计 A/SRV 记录 forhello-world-0
将为空, forhello-world-1
将包含 hello-world-0 并且 forhello-world-N+1
将包含hello-world-0
to hello-world-N
。在滚动更新期间,A/SRV 记录将包含所有其他对等点。
然而,DNS 记录似乎是异步更新的,因此即使n
检测到 pod的生命周期并n + 1
启动 pod,也不能保证 pod会在 DNS 中n + 1
看到 pod 的地址。n