web-dev-qa-db-ja.com

DockerSwarmでZookeeperクラスターをセットアップする方法

環境:6サーバーDockerスウォームクラスター(2マスターと4ワーカー)

要件:既存のDockerスウォームに動物園の飼育係クラスターをセットアップする必要があります。

ブロックオン:クラスターでzookeeperをセットアップするには、各サーバー構成ですべてのzkサーバーを提供し、myidファイルで一意のIDを提供する必要があります。

質問:docker swarmでzookeeperのレプリカを作成する場合、各レプリカに一意のIDを提供するにはどうすればよいですか。また、Zoo.cfg構成ファイルを各ZookeeperコンテナのIDで更新するにはどうすればよいですか。

7
Sunil Agarwal

これは現在、簡単な質問ではありません。完全にスケーラブルなステートフルアプリケーションクラスターは、各クラスターメンバーが一意のIDとストレージボリュームを必要とする場合に注意が必要です。

Docker Swarmでは、今日、作成ファイルで各クラスターメンバーを個別のサービスとして実行することをお勧めします( 1z4/zookeeper-docker を参照)。

version: '2'
services:
    Zoo1:
        image: 31z4/zookeeper
        restart: always
        ports:
            - 2181:2181
        environment:
            Zoo_MY_ID: 1
            Zoo_SERVERS: server.1=Zoo1:2888:3888 server.2=Zoo2:2888:3888 server.3=Zoo3:2888:3888

    Zoo2:
        image: 31z4/zookeeper
        restart: always
        ports:
            - 2182:2181
        environment:
            Zoo_MY_ID: 2
            Zoo_SERVERS: server.1=Zoo1:2888:3888 server.2=Zoo2:2888:3888 server.3=Zoo3:2888:3888
..
..

最先端の(しかしまだ進化している)ソリューションについては、Kubernetesをチェックすることをお勧めします。

Statefulsets の新しい概念は多くの可能性を提供します。 Docker Swarmは、各コンテナインスタンスに一意の「スティッキー」ホスト名が割り当てられ、一意の識別子の基礎として使用できる、同様の機能がやがて成長することを期待しています。

8
Mark O'Connor

それを正確に実行する公式のイメージを拡張したDockerイメージを作成しました。 entrypoint.shは、各コンテナの起動時に残りのzookeeperノードを自動検出し、現在のノードを適切に構成するように変更されました。

画像は docker store および github にあります。

:現在、障害の原因となるコンテナの再作成などのケースは処理していません。

編集(2018年6月11日)

最新のイメージは、次のような場合にzookeeperクラスターの再構成をサポートします。

  • Dockerサービスのスケールアップ(コンテナーの追加)
  • Dockerサービスのスケールダウン(コンテナーの削除)
  • コンテナは、障害の原因であるdocker swarmによって再スケジュールされます(新しいIPが割り当てられます)
2
chaliasos

DockerSwarmモードでZookeeperクラスターをデプロイしようとしています。

DockerSwarmネットワークに接続された3台のマシンを展開しました。私の要件は、アンサンブルを形成するこれらの各ノードで3つのZookeeperインスタンスを実行してみることです。このスレッドを通過し、DockerSwarmにZookeeperをデプロイする方法についていくつかの洞察を得ました。

@juniusが提案したように、私はdockercomposeファイルを作成しました。 docker swarmが制約を無視するため、制約を削除しました。参照 https://forums.docker.com/t/docker-swarm-constraints-being-ignored/31555

私のZookeeperdocker作成ファイルは次のようになります

version: '3.3'

services:
    Zoo1:
        image: zookeeper:3.4.12
        hostname: Zoo1
        ports:
            - target: 2181
              published: 2181
              protocol: tcp
              mode: Host
            - target: 2888
              published: 2888
              protocol: tcp
              mode: Host
            - target: 3888
              published: 3888
              protocol: tcp
              mode: Host
        networks:
            - net
        deploy:
            restart_policy:
                condition: on-failure
        environment:
            Zoo_MY_ID: 1
            Zoo_SERVERS: server.1=0.0.0.0:2888:3888 server.2=Zoo2:2888:3888 server.3=Zoo3:2888:3888
        volumes:
            - /home/zk/data:/data
            - /home/zk/datalog:/datalog
            - /etc/localtime:/etc/localtime:ro
    Zoo2:
        image: zookeeper:3.4.12
        hostname: Zoo2
        ports:
            - target: 2181
              published: 2181
              protocol: tcp
              mode: Host
            - target: 2888
              published: 2888
              protocol: tcp
              mode: Host
            - target: 3888
              published: 3888
              protocol: tcp
              mode: Host
        networks:
            - net
        deploy:
            restart_policy:
                condition: on-failure
        environment:
            Zoo_MY_ID: 2
            Zoo_SERVERS: server.1=Zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=Zoo3:2888:3888
        volumes:
            - /home/zk/data:/data
            - /home/zk/datalog:/datalog
            - /etc/localtime:/etc/localtime:ro
    Zoo3:
        image: zookeeper:3.4.12
        hostname: Zoo3
        ports:
            - target: 2181
              published: 2181
              protocol: tcp
              mode: Host
            - target: 2888
              published: 2888
              protocol: tcp
              mode: Host
            - target: 3888
              published: 3888
              protocol: tcp
              mode: Host
        networks:
            - net
        deploy:
            restart_policy:
                condition: on-failure
        environment:
            Zoo_MY_ID: 3
            Zoo_SERVERS: server.1=Zoo1:2888:3888 server.2=Zoo2:2888:3888 server.3=0.0.0.0:2888:3888
        volumes:
            - /home/zk/data:/data
            - /home/zk/datalog:/datalog
            - /etc/localtime:/etc/localtime:ro
networks:
    net:

Dockerstackコマンドを使用してデプロイされます。

docker stack deploy -c Zoo3.ymlzkネットワークの作成zk_netサービスの作成zk_Zoo3サービスの作成zk_Zoo1サービスの作成zk_Zoo2

Zookeeperサービスは、各ノードで問題なく正常に起動します。

docker stack services zk ID NAME MODE REPLICAS IMAGE PORTS rn7t5f3tu0r4 zk_Zoo1レプリケート1/1 zookeeper:3.4.12 0.0.0.0:2181-> 2181/tcp、0.0.0.0:2888-> 2888/tcp、0.0.0.0:3888-> 3888/tcp u51r7bjwwm03 zk_Zoo2複製1/1 zookeeper:3.4.12 0.0.0.0:2181->2181/tcp、0.0.0.0:2888->2888/tcp、0.0.0.0:3888->3888/tcp zlbcocid57xzzk_Zoo3複製1/1 zookeeper:3.4.12 0.0.0.0:2181->2181/tcp、0.0.0.0:2888->2888/tcp、0.0.0.0:3888->3888/tcp

ここで説明したこの問題を再現しました。動物園の飼育係のスタックを停止して再開したときです。

docker stack rm zk docker stack deploy -c Zoo3.yml zk

今回は飼育係のクラスターは形成されません。 dockerインスタンスは以下をログに記録しました

ZooKeeper JMX enabled by default
Using config: /conf/Zoo.cfg
2018-11-02 15:24:41,531 [myid:2] - WARN  [WorkerSender[myid=2]:QuorumCnxManager@584] - Cannot open channel to 1 at election address Zoo1/10.0.0.4:3888
Java.net.ConnectException: Connection refused (Connection refused)
        at Java.net.PlainSocketImpl.socketConnect(Native Method)
        at Java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.Java:350)
        at Java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.Java:206)
        at Java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.Java:188)
        at Java.net.SocksSocketImpl.connect(SocksSocketImpl.Java:392)
        at Java.net.Socket.connect(Socket.Java:589)
        at org.Apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.Java:558)
        at org.Apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.Java:534)
        at org.Apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.Java:454)
        at org.Apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.Java:435)
        at Java.lang.Thread.run(Thread.Java:748)
2018-11-02 15:24:41,538 [myid:2] - WARN  [WorkerSender[myid=2]:QuorumCnxManager@584] - Cannot open channel to 3 at election address Zoo3/10.0.0.2:3888
Java.net.ConnectException: Connection refused (Connection refused)
        at Java.net.PlainSocketImpl.socketConnect(Native Method)
        at Java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.Java:350)
        at Java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.Java:206)
        at Java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.Java:188)
        at Java.net.SocksSocketImpl.connect(SocksSocketImpl.Java:392)
        at Java.net.Socket.connect(Socket.Java:589)
        at org.Apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.Java:558)
        at org.Apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.Java:534)
        at org.Apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.Java:454)
        at org.Apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.Java:435)
        at Java.lang.Thread.run(Thread.Java:748)
2018-11-02 15:38:19,146 [myid:2] - WARN  [QuorumPeer[myid=2]/0.0.0.0:2181:Learner@237] - Unexpected exception, tries=1, connecting to /0.0.0.0:2888
Java.net.ConnectException: Connection refused (Connection refused)
        at Java.net.PlainSocketImpl.socketConnect(Native Method)
        at Java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.Java:350)
        at Java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.Java:204)
        at Java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.Java:188)
        at Java.net.SocksSocketImpl.connect(SocksSocketImpl.Java:392)
        at Java.net.Socket.connect(Socket.Java:589)
        at org.Apache.zookeeper.server.quorum.Learner.connectToLeader(Learner.Java:229)
        at org.Apache.zookeeper.server.quorum.Follower.followLeader(Follower.Java:72)
        at org.Apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.Java:981)
2018-11-02 15:38:20,147 [myid:2] - WARN  [QuorumPeer[myid=2]/0.0.0.0:2181:Learner@237] - Unexpected exception, tries=2, connecting to /0.0.0.0:2888
Java.net.ConnectException: Connection refused (Connection refused)
        at Java.net.PlainSocketImpl.socketConnect(Native Method)
        at Java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.Java:350)
        at Java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.Java:204)
        at Java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.Java:188)
        at Java.net.SocksSocketImpl.connect(SocksSocketImpl.Java:392)
        at Java.net.Socket.connect(Socket.Java:589)
        at org.Apache.zookeeper.server.quorum.Learner.connectToLeader(Learner.Java:229)
        at org.Apache.zookeeper.server.quorum.Follower.followLeader(Follower.Java:72)
        at org.Apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.Java:981)

よく観察すると、このスタックを初めてデプロイしたときに、ID:2のZooKeeperインスタンスがノード1で実行されていました。これにより、値2のmyidファイルが作成されました。

猫/ home/zk/data/myid 2

スタックを停止して再開すると、今回はID:3のZooKeeperインスタンスがノード1で実行されていることがわかりました。

docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 566b68c11c8b zookeeper:3.4.12 "/ docker-entrypoin ..." 6分前アップ6分0.0.0.0:2181-> 2181/tcp、0.0.0.0:2888-> 2888 /tcp、0.0.0.0:3888->3888/tcp zk_Zoo3.1.7m0hq684pkmyrm09zmictc5bm

ただし、myidファイルの値は2のままです。これは、以前のインスタンスによって設定されたものです。

そのため、ログには[myid:2]が表示され、ID 1および3のインスタンスに接続しようとして、失敗します。

さらにデバッグすると、docker-entrypoint.shファイルに次のコードが含まれていることがわかりました

# Write myid only if it doesn't exist
if [[ ! -f "$Zoo_DATA_DIR/myid" ]]; then
    echo "${Zoo_MY_ID:-1}" > "$Zoo_DATA_DIR/myid"
fi

これは私にとって問題を引き起こしています。 docker-entrypoint.shを次のように編集しました。

if [[ -f "$Zoo_DATA_DIR/myid" ]]; then
    rm "$Zoo_DATA_DIR/myid"
fi

echo "${Zoo_MY_ID:-1}" > "$Zoo_DATA_DIR/myid"

そして、docker-entrypoint.shをcomposeファイルにマウントしました。

この修正により、スタックを複数回停止および開始でき、Zookeeperクラスターが接続の問題にぶつかることなくアンサンブルを形成できるようになります。

私のdocker-entrypoint.shファイルは次のとおりです

#!/bin/bash

set -e

# Allow the container to be started with `--user`
if [[ "$1" = 'zkServer.sh' && "$(id -u)" = '0' ]]; then
    chown -R "$Zoo_USER" "$Zoo_DATA_DIR" "$Zoo_DATA_LOG_DIR"
    exec su-exec "$Zoo_USER" "$0" "$@"
fi

# Generate the config only if it doesn't exist
if [[ ! -f "$Zoo_CONF_DIR/Zoo.cfg" ]]; then
    CONFIG="$Zoo_CONF_DIR/Zoo.cfg"

    echo "clientPort=$Zoo_PORT" >> "$CONFIG"
    echo "dataDir=$Zoo_DATA_DIR" >> "$CONFIG"
    echo "dataLogDir=$Zoo_DATA_LOG_DIR" >> "$CONFIG"

    echo "tickTime=$Zoo_TICK_TIME" >> "$CONFIG"
    echo "initLimit=$Zoo_INIT_LIMIT" >> "$CONFIG"
    echo "syncLimit=$Zoo_SYNC_LIMIT" >> "$CONFIG"

    echo "maxClientCnxns=$Zoo_MAX_CLIENT_CNXNS" >> "$CONFIG"

    for server in $Zoo_SERVERS; do
        echo "$server" >> "$CONFIG"
    done
fi

if [[ -f "$Zoo_DATA_DIR/myid" ]]; then
    rm "$Zoo_DATA_DIR/myid"
fi

echo "${Zoo_MY_ID:-1}" > "$Zoo_DATA_DIR/myid"

exec "$@"

私のdockerは次のようにファイルを作成します

version: '3.3'

services:
    Zoo1:
        image: zookeeper:3.4.12
        hostname: Zoo1
        ports:
            - target: 2181
              published: 2181
              protocol: tcp
              mode: Host
            - target: 2888
              published: 2888
              protocol: tcp
              mode: Host
            - target: 3888
              published: 3888
              protocol: tcp
              mode: Host
        networks:
            - net
        deploy:
            restart_policy:
                condition: on-failure
        environment:
            Zoo_MY_ID: 1
            Zoo_SERVERS: server.1=0.0.0.0:2888:3888 server.2=Zoo2:2888:3888 server.3=Zoo3:2888:3888
        volumes:
            - /home/zk/data:/data
            - /home/zk/datalog:/datalog
            - /home/zk/docker-entrypoint.sh:/docker-entrypoint.sh
            - /etc/localtime:/etc/localtime:ro
    Zoo2:
        image: zookeeper:3.4.12
        hostname: Zoo2
        ports:
            - target: 2181
              published: 2181
              protocol: tcp
              mode: Host
            - target: 2888
              published: 2888
              protocol: tcp
              mode: Host
            - target: 3888
              published: 3888
              protocol: tcp
              mode: Host
        networks:
            - net
        deploy:
            restart_policy:
                condition: on-failure
        environment:
            Zoo_MY_ID: 2
            Zoo_SERVERS: server.1=Zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=Zoo3:2888:3888
        volumes:
            - /home/zk/data:/data
            - /home/zk/datalog:/datalog
            - /home/zk/docker-entrypoint.sh:/docker-entrypoint.sh
            - /etc/localtime:/etc/localtime:ro
    Zoo3:
        image: zookeeper:3.4.12
        hostname: Zoo3
        ports:
            - target: 2181
              published: 2181
              protocol: tcp
              mode: Host
            - target: 2888
              published: 2888
              protocol: tcp
              mode: Host
            - target: 3888
              published: 3888
              protocol: tcp
              mode: Host
        networks:
            - net
        deploy:
            restart_policy:
                condition: on-failure
        environment:
            Zoo_MY_ID: 3
            Zoo_SERVERS: server.1=Zoo1:2888:3888 server.2=Zoo2:2888:3888 server.3=0.0.0.0:2888:3888
        volumes:
            - /home/zk/data:/data
            - /home/zk/datalog:/datalog
            - /home/zk/docker-entrypoint.sh:/docker-entrypoint.sh
            - /etc/localtime:/etc/localtime:ro
networks:
    net:

これにより、作成ファイルにホスト名をハードコーディングすることなく、swarmモードを使用してzookeeperインスタンスをdockerで起動して実行することができます。ノードの1つがダウンした場合、サービスはswarm上の使用可能なノードで問題なく開始されます。

ありがとう

0
Santhosh S Kani