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