Docker/Kubernetes 実践コンテナ開発入門 (以下のurl)の 「4. Swarmによる実践的なアプリケーアプリケーション構築」を 写経しようとしましたが、
$ docker container exec -it manager \
docker stack deploy -c ./stack/todo-mysql.yml todo_mysql
の実行でエラー。
コンテナオーケストレーションツールとしては、Docker Swarmよりも Kubernetes が、世の中的には、標準かと思いますので、 このentryの下部に様々記載してますが、Docker Swarmは学びません。
目次
- git clone https://github.com/gihyodocker/tododb
- 全体構成
- ノードの確認 (master x1 , worker x3)
- todoappという名の overlayネットワーク作成
- $ vi tododb/etc/mysql/mysql.conf.d/mysqld.cnf
- $ vi tododb/add-server-id.sh
- $ vi tododb/prepare.sh
- $ vi tododb/Dockerfile
- tododb/Dockerfile の build 、更にタグ付けし、repositoryへpush
- Swarm上の Master/Slaveサービス定義 ($ vi stack/todo-mysql.yml )
git clone https://github.com/gihyodocker/tododb
全体構成
┌stack(frontend) ──────────────────┐
│┌service(frontend_nginx) ────────────┐│
││┌──────────────────────┐││
│││container x3 │││
│└┴──────────┰───────────┴┘│
│ ┃HTTP(Proxy) │
│┌service(frontend_web) ╂────────────┐│
││┌──────────┸───────────┐││
│││container x3 │││
└┴┴──────────┰───────────┴┴┘
┃HTTP
┌stack(app)───────╂─────────────┐
│┌service(app_nginx)──╂────────────┐│
││┌──────────┸───────────┐││
│││container x3 │││
│└┴──────────┰───────────┴┘│
│ ┃HTTP(Proxy) │
│┌service(app_api)───╂────────────┐│
││┌──────────┸───────────┐││
│││container x3 │││
└┴┴────┰───────────┰─────┴┴┘
┃write ┃read
┌stack(mysql)╂───────────╂───────┐
│┌─────╂───┐ ┌──╂──────┐│
││┌────┸───┤replica ├──┸─────┐││
│││container x1 ┝━━━━┥container x3 │││
││└────────┤ ├────────┘││
│ service(mysql_master) service(mysql_slave) │
└──────────────────────────┘
ノードの確認 (master x1 , worker x3)
$ docker container exec -it manager docker node ls
HOSTNAME STATUS MANAGER STATUS ENGINE VERSION
* 98e4c5b93225 Ready Leader 20.10.23
120608a59677 Ready 20.10.23
d4dc2bd958ec Ready 20.10.23
e54446b93f5e Ready 20.10.23
todoappという名の overlayネットワーク作成
$ docker container exec -it manager \
docker network create --driver=overlay --attachable todoapp
$ vi tododb/etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_general_ci pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql #log-error = /var/log/mysql/error.log # By default we only accept connections from localhost #bind-address = 127.0.0.1 # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 relay-log=mysqld-relay-bin relay-log-index=mysqld-relay-bin log-bin=/var/log/mysql/mysql-bin.log
$ vi tododb/add-server-id.sh
先程の mysqld.cnf に server-id を追記する為のものです
#!/bin/bash -e OCTETS=(`hostname -i | tr -s '.' ' '`) MYSQL_SERVER_ID=`expr ${OCTETS[2]} \* 256 + ${OCTETS[3]}` echo "server-id=$MYSQL_SERVER_ID" >> /etc/mysql/mysql.conf.d/mysqld.cnf
$ vi tododb/prepare.sh
Master/Slave間のレプリケーション設定用
#!/bin/bash -e
# (1) MasterとSlaveを環境変数で制御する
if [ ! -z "$MYSQL_MASTER" ]; then
echo "this container is master"
exit 0
fi
echo "prepare as slave"
# (2) SlaveからMasterへの疎通確認をする
if [ -z "$MYSQL_MASTER_HOST" ]; then
echo "mysql_master_host is not specified" 1>&2
exit 1
fi
while :
do
if mysql -h $MYSQL_MASTER_HOST -u root -p$MYSQL_ROOT_PASSWORD -e "quit" > /dev/null 2>&1 ; then
echo "MySQL master is ready!"
break
else
echo "MySQL master is not ready"
fi
sleep 3
done
# (3) Masterにレプリケーション用のユーザーと権限の作成
IP=`hostname -i`
IFS='.'
set -- $IP
SOURCE_IP="$1.$2.%.%"
mysql -h $MYSQL_MASTER_HOST -u root -p$MYSQL_ROOT_PASSWORD \
-e "CREATE USER IF NOT EXISTS '$MYSQL_REPL_USER'@'$SOURCE_IP' IDENTIFIED BY '$MYSQL_REPL_PASSWORD';"
mysql -h $MYSQL_MASTER_HOST -u root -p$MYSQL_ROOT_PASSWORD \
-e "GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_REPL_USER'@'$SOURCE_IP';"
# (4) Masterのbinlogのポジションを取得
MASTER_STATUS_FILE=/tmp/master-status
mysql -h $MYSQL_MASTER_HOST -u root -p$MYSQL_ROOT_PASSWORD \
-e "SHOW MASTER STATUS\G" > $MASTER_STATUS_FILE
BINLOG_FILE=`cat $MASTER_STATUS_FILE | grep File | xargs | cut -d' ' -f2`
BINLOG_POSITION=`cat $MASTER_STATUS_FILE | grep Position | xargs | cut -d' ' -f2`
echo "BINLOG_FILE=$BINLOG_FILE"
echo "BINLOG_POSITION=$BINLOG_POSITION"
# (5) レプリケーションを開始する
mysql -u root -p$MYSQL_ROOT_PASSWORD \
-e "CHANGE MASTER TO MASTER_HOST='$MYSQL_MASTER_HOST', MASTER_USER='$MYSQL_REPL_USER', MASTER_PASSWORD='$MYSQL_REPL_PASSWORD', MASTER_LOG_FILE='$BINLOG_FILE', MASTER_LOG_POS=$BINLOG_POSITION;"
mysql -u root -p$MYSQL_ROOT_PASSWORD -e "START SLAVE;"
echo "slave started"
$ vi tododb/Dockerfile
FROM mysql:5.7
# (1) パッケージアップデートとwgetインストール
RUN apt-get update
RUN apt-get install -y wget
# (2) entrykitのインストール
RUN wget https://github.com/progrium/entrykit/releases/download/v0.4.0/entrykit_0.4.0_linux_x86_64.tgz
RUN tar -xvzf entrykit_0.4.0_linux_x86_64.tgz
RUN rm entrykit_0.4.0_linux_x86_64.tgz
RUN mv entrykit /usr/local/bin/
RUN entrykit --symlink
# (3) スクリプトと各種設定ファイルのコピー
COPY add-server-id.sh /usr/local/bin/
COPY etc/mysql/mysql.conf.d/mysqld.cnf /etc/mysql/mysql.conf.d/
COPY etc/mysql/conf.d/mysql.cnf /etc/mysql/conf.d/
COPY prepare.sh /docker-entrypoint-initdb.d
COPY init-data.sh /usr/local/bin/
COPY sql /sql
# (4) スクリプトとmysqldの実行
ENTRYPOINT [ \
"prehook", \
"add-server-id.sh", \
"--", \
"docker-entrypoint.sh" \
]
CMD ["mysqld"]
tododb/Dockerfile の build 、更にタグ付けし、repositoryへpush
$ docker image build -t ch04/tododb:latest . $ docker image tag ch04/tododb:latest localhost:5000/ch04/tododb:latest $ docker image push localhost:5000/ch04/tododb:latest
Swarm上の Master/Slaveサービス定義 ($ vi stack/todo-mysql.yml )
version: "3" services: master: image: registry:5000/ch04/tododb:latest deploy: replicas: 1 placement: constraints: [node.role != manager] environment: MYSQL_ROOT_PASSWORD: gihyo MYSQL_DATABASE: tododb MYSQL_USER: gihyo MYSQL_PASSWORD: gihyo MYSQL_MASTER: "true" networks: - todoapp slave: image: registry:5000/ch04/tododb:latest deploy: replicas: 2 placement: constraints: [node.role != manager] depends_on: - master environment: MYSQL_MASTER_HOST: master MYSQL_DATABASE: tododb MYSQL_USER: gihyo MYSQL_PASSWORD: gihyo MYSQL_ROOT_PASSWORD: gihyo MYSQL_REPL_USER: repl MYSQL_REPL_PASSWORD: gihyo networks: - todoapp networks: todoapp: external: true
$ docker container run -d --name todo_mysql localhost:5000/ch04/tododb:latest
$ docker container exec -it manager \
docker stack deploy -c ./stack/todo-mysql.yml todo_mysql
ERROR open ./stack/todo-mysql.yml: no such file or directory