Zookeeper: не удается разрешить имя хоста

Я запускаю Zookeeper в среде OpenShift / Kubernetes. Я установил zookeeper как StatefulSet, чтобы надежно сохранять данные конфигурации.

Я настроил три сервера в моем zoo.cfg по имени хоста, но при запуске разрешение имени хоста не работает. Я подтвердил, что имена хостов действительно разрешимы с помощью nslookup внутри моего кластера.

zoo.cfg:

clientPort=2181
dataDir=/var/lib/zookeeper/data
dataLogDir=/var/lib/zookeeper/log
tickTime=2000
initLimit=10
syncLimit=2000
maxClientCnxns=60
minSessionTimeout= 4000
maxSessionTimeout= 40000
autopurge.snapRetainCount=3
autopurge.purgeInteval=0
server.1=zookeeper-0.zookeeper-headless:2888:3888
server.2=zookeeper-1.zookeeper-headless:2888:3888
server.3=zookeeper-2.zookeeper-headless:2888:3888

Соответствующие части моей конфигурации OpenShift / Kubernetes:

  # StatefulSet
  - apiVersion: apps/v1beta1
    kind: StatefulSet
    metadata:
      labels:
        app: zookeeper
      name: zookeeper
    spec:
      serviceName: zookeeper-headless
      replicas: 3
      template:
        metadata:
          labels:
            app: zookeeper
        spec:
          containers:
            - image: 172.30.158.156:5000/os-cloud-platform/zookeeper:latest
              name: zookeeper
              ports:
                - containerPort: 2181
                  protocol: TCP
                  name: client
                - containerPort: 2888
                  protocol: TCP
                  name: server
                - containerPort: 3888
                  protocol: TCP
                  name: leader-election
          dnsPolicy: ClusterFirst
          schedulerName: default-scheduler

  # Service
  - apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: zookeeper
      name: zookeeper
    spec:
      ports:
        - name: client
          port: 2181
          protocol: TCP
          targetPort: 2181
      selector:
        app: zookeeper
      sessionAffinity: None
      type: ClusterIP

  - apiVersion: v1
    kind: Service
    metadata:
      name: zookeeper-headless
      labels:
        app: zookeeper
    spec:
      ports:
        - port: 2888
          name: server
        - port: 3888
          name: leader-election
      clusterIP: None
      selector:
        app: zookeeper

Однако журналы OpenShift показывают UnknownHostExceptions:

2017-10-06 10:59:18,289 [myid:] - WARN  [main:QuorumPeer$QuorumServer@155] - Failed to resolve address: zookeeper-2.zookeeper-headless
java.net.UnknownHostException: zookeeper-2.zookeeper-headless: No address associated with hostname
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
    at java.net.InetAddress.getAllByName0(InetAddress.java:1276)
    at java.net.InetAddress.getAllByName(InetAddress.java:1192)
    at java.net.InetAddress.getAllByName(InetAddress.java:1126)
    at java.net.InetAddress.getByName(InetAddress.java:1076)
    at org.apache.zookeeper.server.quorum.QuorumPeer$QuorumServer.recreateSocketAddresses(QuorumPeer.java:148)
    at org.apache.zookeeper.server.quorum.QuorumPeer$QuorumServer.<init>(QuorumPeer.java:133)
    at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parseProperties(QuorumPeerConfig.java:228)
    at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parse(QuorumPeerConfig.java:140)
    at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:101)
at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:78)
...

Что может быть причиной? Я подтвердил, что имя хоста (например, zookeeper-2.zookeeper-headless) доступно из других модулей через nslookup.


person Franz Wimmer    schedule 06.10.2017    source источник
comment
Вы можете посмотреть официальную документацию о том, как запустить zookeeper в кубернетах: kubernetes.io / docs / tutorials / stateful-application / zookeeper   -  person vascop    schedule 08.10.2017
comment
Я использовал эту документацию для создания своего ансамбля zookeeper.   -  person Franz Wimmer    schedule 09.10.2017


Ответы (1)


Я нашел рабочее решение этой проблемы. ZooKeeper читает список серверов в ансамбле при запуске и ищет свою «собственную» запись. Затем он использует эту запись, чтобы определить, какой порт и интерфейс следует прослушивать.

server.1=zookeeper-0.zookeeper-headless:2888:3888
server.2=zookeeper-1.zookeeper-headless:2888:3888
server.3=zookeeper-2.zookeeper-headless:2888:3888

Поскольку предоставленное имя хоста будет преобразовано в 127.0.0.1 на этом компьютере, ZooKeeper будет прослушивать локальный интерфейс обратной петли и, следовательно, не принимает подключения от других серверов ZooKeeper.

server.1=0.0.0.0:2888:3888
server.2=zookeeper-1.zookeeper-headless:2888:3888
server.3=zookeeper-2.zookeeper-headless:2888:3888

Чтобы автоматизировать процессы в кластере, я написал сценарий bash, который заменит одну «собственную» запись при запуске контейнера.

РЕДАКТИРОВАТЬ: Как указано в комментариях, вот мой ENTRYPOINT скрипт, который позаботится о размещении файла myid и установке соответствующего имени хоста для каждого zoo.cfg:

#!/bin/bash
# This script extracts the number out of the pod's hostname and sets it as zookeepers id.

# Exact paths may vary according to your setup
MYID_FILE="/var/lib/zookeeper/data/myid"
ZOOCFG_FILE="/conf/zoo.cfg"

# Create myid-file
# Extract only numbers from hostname
id=$(hostname | tr -d -c 0-9)
echo $id > "${MYID_FILE}"

# change own hostname to 0.0.0.0
# otherwise, the own hostname will resolve to 127.0.0.1
# https://stackoverflow.com/a/40750900/5764665
fullHostname="$(hostname).zookeeper-headless"
sed -i -e "s/${fullHostname}/0.0.0.0/g" "${ZOOCFG_FILE}"

echo "Executing $@"
exec "$@"
person Franz Wimmer    schedule 16.10.2017
comment
Привет, Франц. У меня такая же проблема. Я хотел спросить, как изменить конкретный сервер пода, чтобы разрешить его локальный хост. Также не могли бы вы поделиться скриптом bash, пожалуйста? Это было бы действительно полезно. Большое спасибо - person Sibtain; 29.01.2018
comment
Большое спасибо за сценарий. Подскажите, пожалуйста, где запустить этот скрипт (initContainer или что-то в этом роде?). Извините, я новичок в Kubernetes - person Sibtain; 29.01.2018
comment
Этот сценарий является ВХОДНОЙ ТОЧКОЙ вашего образа Docker. Он выполнит все args, переданные вами в настройках Kubernetes. - person Franz Wimmer; 29.01.2018
comment
Я использовал configmap для монтирования тома, а затем использовал этот смонтированный том для запуска скрипта в моем контейнере, например, command: ['/bin/bash', '/var/lib/zk-init.sh']. Но у меня ошибка sed: /conf/zoo.cfg: No such file or directory. Хотя когда я успешно запустил container. Он действительно содержит /conf/zoo.cfg. Подскажите пожалуйста, что я делаю не так? ПРИМЕЧАНИЕ. /var/lib - это mountPath - person Sibtain; 29.01.2018
comment
Извините, что беспокою вас снова. но мне действительно нужно знать, как вы запускали скрипт в качестве точки входа в образ докера - person Sibtain; 29.01.2018
comment
Вы должны добавить скрипт в контекст сборки и ADD его в свой Dockerfile. Для этого нет необходимости в томе. - person Franz Wimmer; 29.01.2018
comment
@FranzWimmer просто хотел сказать вам, что это помогло и с контекстом kubernetes / istio. zookeeper отлично работал в кубернетах, но как только я развернул zk с боковой картой istio, экземпляры zk больше не могли разговаривать друг с другом. после изменения конфигурации сервера, как описано, он снова заработал. Большое Вам спасибо. - person christian; 08.04.2019
comment
@FranzWimmer, я не могу понять, как вы реализовали это с помощью карты конфигурации. Он запускается перед командой start-zookeeper или после? Не могли бы вы поделиться своим реальным манифестом zookeeper? Что бы я ни пытался, разрешение имен продолжает терпеть неудачу. - person Dave; 09.04.2021