处于未就绪状态的Pod的dns条目

时间:2020-01-15 23:00:27

标签: mongodb kubernetes dns

我正在尝试在kubernetes中构建一个简单的mongo副本集集群。

我有一个StatefulSet mongod实例,其中

      livenessProbe:
        initialDelaySeconds: 60
        exec:
          command:
            - mongo
            - --eval
            - "db.adminCommand('ping')"
      readinessProbe:
        initialDelaySeconds: 60
        exec:
          command:
            - /usr/bin/mongo --quiet --eval 'rs.status()' | grep ok | cut -d ':' -f 2 | tr -dc '0-9' | awk '{ if($0=="0"){ exit 127 }else{ exit 0 } }'

如您所见,我的readinessProbe正在检查mongo copyerSet是否正常工作。

但是,我对(和现有的)集群报告有了循环依赖:

        "lastHeartbeatMessage" : "Error connecting to mongo-2.mongo:27017 :: caused by :: Could not find address for mongo-2.mongo:27017: SocketException: Host not found (authoritative)",

(其中mongo-2正在进行滚动更新)。

进一步看:

$ kubectl  run --generator=run-pod/v1 tmp-shell --rm -i --tty --image nicolaka/netshoot -- /bin/bash

bash-5.0# nslookup mongo-2.mongo
Server:     10.96.0.10
Address:    10.96.0.10#53

** server can't find mongo-2.mongo: NXDOMAIN

bash-5.0# nslookup mongo-0.mongo
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   mongo-0.mongo.cryoem-logbook-dev.svc.cluster.local
Address: 10.27.137.6

所以问题是,是否有办法让kubernetes始终保留dns条目,使mongo pod始终存在?看来我遇到了麻烦,如果整个Pod未通过其就绪性和活动性检查,则不会创建dns条目,因此其他mongod实例将无法访问它。

2 个答案:

答案 0 :(得分:1)

我最终只是为每个statefulset实例添加一个ClusterIP服务,并为https://websockets.readthedocs.io/en/stable/intro.html#browser-based-example添加一个selector

apiVersion: v1
kind: Service
metadata:
  name: mongo-0
spec:
  clusterIP: 10.101.41.87
  ports:
  - port: 27017
    protocol: TCP
    targetPort: 27017
  selector:
    role: mongo
    statefulset.kubernetes.io/pod-name: mongo-0
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

,然后重复其他sts个。关键是选择器:

statefulset.kubernetes.io/pod-name: mongo-0

答案 1 :(得分:0)

我相信您会误解该错误。

找不到mongo-2.mongo:27017 的地址:SocketException:找不到主机(权威)”

已创建一个已附加IP的Pod。然后将其注册到DNS:

Pod-0的IP为10.0.0.10,现在它的FQDN为 Pod-0.servicename.namespace.svc.cluster.local

Pod-1的IP为10.0.0.11,现在它的FQDN为 Pod-1.servicename.namespace.svc.cluster.local

Pod-2的IP为10.0.0.12,现在它的FQDN为 Pod-2.servicename.namespace.svc.cluster.local

但是DNS是实时服务,IP是动态分配的,不能重复。 因此,无论何时收到请求:

“使用 Pod-A.servicename.namespace.svc.cluster.local 与我联系”

它尝试到达注册的IP,并且如果Pod由于滚动更新而脱机,它将认为Pod不可用,并返回”“找不到Pod-0.servicename的地址(IP)”。 “ ,直到Pod再次联机或IP保留期结束,然后DNS注册表才会被回收。

DNS不会公开已注册的DNS名称,只是在回答它当前处于脱机状态。

您可以忽略滚动过程中的错误,也可以重新考虑脚本,然后尝试使用注释中提到的内部js环境来连续监视mongo状态。

编辑:

  • 在部署带有N个副本的StatefulSet中的Pod时,将按从{0..N-1}开始的顺序依次创建它们。
  • 删除Pod时,它们以相反的顺序从{N-1..0}终止。
  • 这是预期的/期望的默认行为。
  • 所以这种错误是预料之中的,因为rollingUpdate使得容器暂时不可用。