如何解决有状态集合中的pod启动与服务DNS查找之间的竞争

时间:2019-05-26 17:48:32

标签: kubernetes dns kubernetes-service kubernetes-statefulset

我正在尝试编写一个所有Pod相互连接的应用程序。我已经读过documentation

  

Pods的序号,主机名,SRV记录和A记录名称未更改,但是与Pod关联的IP地址可能已更改。在本教程使用的集群中,它们具有。这就是为什么不要配置其他应用程序通过IP地址连接到StatefulSet中的Pod的原因。

     

如果需要查找并连接到StatefulSet的活动成员,则应查询无头服务(nginx.default.svc.cluster.local)的CNAME。与CNAME关联的SRV记录将仅包含StatefulSet中处于运行和就绪状态的Pod。

     

如果您的应用程序已经实现了测试活动性和就绪状态的连接逻辑,则可以使用Pod(web-0.nginx.default.svc.cluster.localweb-1.nginx.default.svc.cluster.local)的SRV记录,因为它们是稳定的,因此您的应用程序将当Pod转换为Running and Ready时,便能够发现它们的地址。

我可以通过以下方式做到这一点:

  • 查找服务的SRV记录以检查哪些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. / _hello-world._tcp.hello-world.default.svc.cluster.local.的A / SRV记录并打印以进行调试
  • 绑定到3080端口并开始侦听(未实现连接逻辑)
  • 打开8080端口

我希望hello-world-0的A / SRV记录为空,hello-world-1会包含hello-world-0,hello-world-N+1会包含hello-world-0至{{ 1}}。在滚动更新期间,A / SRV记录将包含所有其他对等项。

但是,似乎DNS记录是异步更新的,因此即使检测到Pod hello-world-N的生命周期并启动Pod n,也不能保证Pod n + 1会看到地址DNS中的pod n + 1

1 个答案:

答案 0 :(得分:0)

在服务定义中添加以下注释

  annotations:
    service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"