GW
Docker
supervisor
serf

GWに一人さみしくDockerとSerfと戯れてみた(๑´ڡ`๑)

More than 3 years have passed since last update.

少しserfを触りたいなと思ったので、dockerを使って検証できる環境を作りました。


なので、今回はcontainerないでsshdを立てたりしています(ここでは使いませんが)


まだserf members で検証できるレベルです。


今回の検証環境


Dockerイメージ

OS

Ubuntu:16.04 ltsが出ましたね。

入れたもの


  • serf

  • supervisor(理由は後ほど)

FROM ubuntu:16.04

RUN apt-get update -y \
apt-get install -y wget unzip

# Install Serf
RUN wget -nv https://releases.hashicorp.com/serf/0.7.0/serf_0.7.0_linux_amd64.zip && \
echo "b239fdcd1c15fd926ff0cd10bc32a31330d1c74aba9e4d49ff83d5707ef1ba4b serf_0.7.0_linux_amd64.zip" | sha256sum -c - && \
unzip serf_0.7.0_linux_amd64.zip -d /usr/bin && \
rm serf_0.7.0_linux_amd64.zip

# Install supervisor
# https://docs.docker.com/engine/admin/using_supervisord/
RUN apt-get install -y openssh-server apache2 supervisor
RUN mkdir -p /var/lock/apache2 /var/run/apache2 /var/run/sshd /var/log/supervisor

# Clean
RUN apt-get clean && \
rm -rf /tmp/* /var/tmp/*

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

COPY serf.sh /usr/local/bin/serf.sh
RUN chmod a+x /usr/local/bin/serf.sh

EXPOSE 22 7946
CMD ["/usr/bin/supervisord"]


Supervisor

以下のconfファイルを置くだけでいいはずが少しハマりました。。


/etc/supervisor/conf.d/supervisord.conf

[program:serfagent]

command=/usr/local/bin/serf.sh

少し脱線します。ハマった理由は

supervisor: couldn't exec /usr/local/bin/serf.sh: ENOEXEC

supervisor: child process was not spawned

なんでやねん! RUN chmod a+x /usr/local/bin/serf.sh ってしとるやないか


と思いながら調べてたら

最初


/usr/local/bin/serf.sh

#/bin/sh

set -u

このようなファイルになっていました。。。いつもハマる時は簡単なアレ


だけどきづけない。。

修正後は次で記述


Serf実行ファイル

最初に立ち上げるエージェントかどうかで -join をつけるかどうか変わるので


supervisorがserfを直接実行しないように、ラップしたもの


/usr/local/bin/serf.sh

#!/bin/sh

set -u

if [ -z "${NODE_PORT_7946_TCP_ADDR+x}" ]; then
serf agent -bind 0.0.0.0:7946
else
serf agent -bind 0.0.0.0:7946 -join $NODE_PORT_7946_TCP_ADDR:7946
fi


NODE_PORT_7946_TCP_ADDR はコンテナ起動時に設定しています。

link先があれば設定済みで、最初のコンテナには存在しません


では実行


コンテナを立ち上げるためのスクリプト(on mac)


node.sh

#!/bin/sh

num=`docker ps | grep node | wc -l`
num=`echo $num | tr -d " "`
num=$(( num+1 ))
SSH_PORT=$(( 2220 + num ))
node_name=node$num
echo $node_name

SERF_PORT=7945
DOKCER_IMAGE_NAME=shinofara/serf:latest

cmd=""
if [[ $num -eq 1 ]]; then
cmd="docker run -d -t \
--name
${node_name} \
-p
${SERF_PORT} \
-p
${SSH_PORT}:22 \
${DOKCER_IMAGE_NAME}"
else

cmd="docker run -d -t \
--name
${node_name} \
-p
${SERF_PORT} \
-p
${SSH_PORT}:22 \
--link node1:node
\
${DOKCER_IMAGE_NAME}"
fi

echo $cmd && $cmd


ps結果が0件なら最初のエージェントとして起動、それ以外はlinksさせて起動


スクリプト実行(on mac)

$ sh node.sh 

node1
docker run -d -t --name node1 -p 7945 -p 2221:22 shinofara/serf:latest
f9abc288f29b1f32224b6f243c86062613c63f7727933f4891ca1e215ca32f58
$ sh node.sh
node2
docker run -d -t --name node2 -p 7945 -p 2222:22 --link node1:node shinofara/serf:latest
299e5b7b4798cd609a806d23782e4851cfa592bf57870e6a638f7c947656cb11
$ sh node.sh
node3
docker run -d -t --name node3 -p 7945 -p 2223:22 --link node1:node shinofara/serf:latest
07e327177cae0a27ecfaea854ad629111da2ffc24f9c403d7c181503dce03407
$ sh node.sh
node4
docker run -d -t --name node4 -p 7945 -p 2224:22 --link node1:node shinofara/serf:latest
1a0e54ce5c54db404fe51e1cdcea67202ad064fe586a7e43a74bf2ae8aa1f907
$ sh node.sh
node5
docker run -d -t --name node5 -p 7945 -p 2225:22 --link node1:node shinofara/serf:latest
b1477622be43fe3e9e05b05573321b67c66d6542674d5f7111f8242e52d8423f
$ sh node.sh
node6
docker run -d -t --name node6 -p 7945 -p 2226:22 --link node1:node shinofara/serf:latest
f5b709c3b415b70b042c234df8b9c50d6dc679e5c976d4523b3f001cbc05bb04
$ sh node.sh
node7
docker run -d -t --name node7 -p 7945 -p 2227:22 --link node1:node shinofara/serf:latest
6e7622d40e9bc367d4481412afaeb965a5bf42ba4dad4072079e1c33f5554b09

特にnode数に意味はありません、あきるまで実行しただけです


ちゃんとクラスタネットワークが作成されているか確認

確認するためのコンテナを立ち上げます。

$ docker run --rm -it --name node8 -p 7945 -p 2228:22 --link node1:node shinofara/serf:latest /bin/bash

まだsupervisorが立ち上がってないので起動&確認

root@e9305544dfab:/# /usr/bin/supervisord &

root@e9305544dfab:/# supervisorctl status
serfagent RUNNING pid 13, uptime 0:00:06
sshd RUNNING pid 12, uptime 0:00:06

serf members で確認

root@e9305544dfab:/# serf members

1a0e54ce5c54 172.17.0.5:7946 alive
07e327177cae 172.17.0.4:7946 alive
299e5b7b4798 172.17.0.3:7946 alive
e9305544dfab 172.17.0.9:7946 alive
f5b709c3b415 172.17.0.7:7946 alive
f9abc288f29b 172.17.0.2:7946 alive
6e7622d40e9b 172.17.0.8:7946 alive
b1477622be43 172.17.0.6:7946 alive

とりあえずクラスタネットワーク作成までは完了!

作業履歴はこちら

https://github.com/shinofara/serf/tree/b4b92da946d506695cbab3af8b32ee758fc32273