Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その11 )( Docker コンテナの image をバージョンアップする、rabbitmq・haproxy・rabbitmq_exporter 編 )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
- 今回は以下の Docker コンテナの image をバージョンアップします。
- rabbitmq
- haproxy
- kbudde/rabbitmq-exporter
- 今回は以下の Docker コンテナの image をバージョンアップします。
参照したサイト・書籍
chmod not working correctly in Docker
https://serverfault.com/questions/772227/chmod-not-working-correctly-in-dockerClustering Guide
https://www.rabbitmq.com/clustering.htmldocker-library / rabbitmq
https://github.com/docker-library/rabbitmqCentOS7 RabbitMQ 3.7.4 cluster installation and use
https://www.programmersought.com/article/13654537027/Authentication, Authorisation, Access Control
https://www.rabbitmq.com/access-control.htmlConfiguration
https://www.rabbitmq.com/configure.htmlrabbitmqctl(8)
https://www.rabbitmq.com/rabbitmqctl.8.html#forget_cluster_nodeRabbitMQ cluster maintenance
https://docs.openstack.org/openstack-ansible/pike/admin/maintenance-tasks/rabbitmq-maintain.html
目次
- .env を変更する
- docker-compose.yml を変更する
docker-compose up -d
コマンドを実行する- rabbitmq が起動しない。。。
- 環境変数 RABBITMQ_ERLANG_COOKIE をやめて .erlang.cookie file に変更する
HTTP access denied: user 'rabbitmq' - invalid credentials
が出力されないようにする+管理画面からログインできるようにする- clean タスク実行 → Rebuild Project 実行 → build タスクを実行する
- 変更前の docker image を削除する
手順
.env を変更する
.......... RABBITMQ_VERSION=3.8.9-management RABBITMQ_ERLANG_COOKIE=Uzkm93w5e1Lz8AcP RABBITMQ_DEFAULT_USER=rabbitmq RABBITMQ_DEFAULT_PASS=12345678 RABBITMQ_DEFAULT_VHOST=/ ..........
RABBITMQ_VERSION=3.8.2-management
→RABBITMQ_VERSION=3.8.9-management
に変更します。
docker-compose.yml を変更する
.......... # http://localhost:1936/haproxy?stats haproxy: image: haproxy:2.3.2-alpine container_name: haproxy ports: - "1936:1936" - "5672:5672" - "15672:15672" environment: - TZ=Asia/Tokyo volumes: - ./docker/rabbitmq/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro depends_on: - rabbitmq1 - rabbitmq2 - rabbitmq3 ..........
image: haproxy:2.1.2-alpine
→image: haproxy:2.3.2-alpine
に変更します。
docker-compose up -d
コマンドを実行する
以下のコマンドを実行して docker image を更新・ダウンロードします(画面キャプチャはなし)。
docker-compose build --no-cache
コマンドを実行し、Dockerfile で作成している image を更新します。- kbudde/rabbitmq-exporter は latest の docker image をダウンロードしているので、ローカルの docker image を削除します。
docker-compose up -d
コマンドを実行してコンテナ一式(メールサーバ・rainloop を除く)を起動します。
rabbitmq が起動しない。。。
docker-compose up -d
コマンドを実行した後、haproxy の画面で rabbitmq が起動するのを待っても rabbitmq2、rabbitmq3 がいつまでたっても起動しません。
IntelliJ IDEA でコンテナの状況を確認すると rabbitmq2、rabbitmq3 は停止しており、
RABBITMQ_ERLANG_COOKIE env variable support is deprecated and will be REMOVED in a future version. Use the $HOME/.erlang.cookie file or the --erlang-cookie switch instead.
というログが出力されていました。ただし、あくまでも deprecated なので起動しない原因ではないようです。- 起動しない理由は以下3つのいずれかのようです。
Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues)
CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server)
Target node is not running
環境変数 RABBITMQ_ERLANG_COOKIE をやめて .erlang.cookie file に変更する
deprecated のメッセージが出ているので、先に環境変数 RABBITMQ_ERLANG_COOKIE をやめて .erlang.cookie file に変更します。
docker/rabbitmq の下に .erlang.cookie を新規作成し、以下の内容を記述します。
Uzkm93w5e1Lz8AcP
.env から RABBITMQ_ERLANG_COOKIE=Uzkm93w5e1Lz8AcP
を削除します。
RABBITMQ_VERSION=3.8.9-management RABBITMQ_DEFAULT_USER=rabbitmq RABBITMQ_DEFAULT_PASS=12345678 RABBITMQ_DEFAULT_VHOST=/
docker-compose.yml の rabbitmq1、rabbitmq2、rabbitmq3 の environment から - RABBITMQ_ERLANG_COOKIE
を削除します。
# RabbitMQ Clustering rabbitmq1: build: context: ./docker/rabbitmq args: - RABBITMQ_VERSION=${RABBITMQ_VERSION} image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq1 hostname: rabbitmq1 environment: - TZ=Asia/Tokyo - RABBITMQ_DEFAULT_USER - RABBITMQ_DEFAULT_PASS - RABBITMQ_DEFAULT_VHOST rabbitmq2: image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq2 hostname: rabbitmq2 environment: - TZ=Asia/Tokyo volumes: - ./docker/rabbitmq/cluster-entrypoint.sh:/usr/local/bin/cluster-entrypoint.sh entrypoint: /bin/sh -c /usr/local/bin/cluster-entrypoint.sh depends_on: - rabbitmq1 rabbitmq3: image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq3 hostname: rabbitmq3 environment: - TZ=Asia/Tokyo volumes: - ./docker/rabbitmq/cluster-entrypoint.sh:/usr/local/bin/cluster-entrypoint.sh entrypoint: /usr/local/bin/cluster-entrypoint.sh depends_on: - rabbitmq1
https://www.rabbitmq.com/clustering.html#cookie-file-locations を見ると .erlang.cookie は /var/lib/rabbitmq/.erlang.cookie に配置すると記述されているので、docker/rabbitmq/Dockerfile を以下のように変更します。
ARG RABBITMQ_VERSION FROM rabbitmq:${RABBITMQ_VERSION}-alpine RUN apk add --no-cache tzdata COPY .erlang.cookie /var/lib/rabbitmq/
COPY .erlang.cookie /var/lib/rabbitmq/
を追加します。
docker-compose build --no-cache
コマンドを実行してから docker-compose up -d
コマンドを実行します。。。が、Cookie file /var/lib/rabbitmq/.erlang.cookie must be accessible by owner only
というメッセージが表示されて rabbitmq が起動しません。
docker/rabbitmq/Dockerfile の最後に RUN ls -al /var/lib/rabbitmq/
を追加して .erlang.cookie の owner、permission を確認すると -rwxr-xr-x 1 root root
でした。
owner/group は https://github.com/docker-library/rabbitmq/blob/master/3.8/alpine/Dockerfile を見ると addgroup、adduser コマンドで rabbitmq
が指定されており、permission は -rw-------
にすれば良いはずなので、docker/rabbitmq/Dockerfile を以下のように変更してみます。
ARG RABBITMQ_VERSION FROM rabbitmq:${RABBITMQ_VERSION}-alpine RUN apk add --no-cache tzdata COPY --chown=rabbitmq:rabbitmq .erlang.cookie /var/lib/rabbitmq/ RUN chmod 600 /var/lib/rabbitmq/.erlang.cookie RUN ls -al /var/lib/rabbitmq/
- COPY コマンドに
--chown=rabbitmq:rabbitmq
オプションを追加します。 RUN chmod 600 /var/lib/rabbitmq/.erlang.cookie
を追加します。
docker-compose build --no-cache
コマンドを実行すると owner、group は rabbitmq
に変更されましたが、permission は -rwxr-xr-x
のままでした。。。
この permission を変更する方法が最初全然分からなかったのですが、いろいろ検索してみた結果、以下の方法で解消できました。
- chmod not working correctly in Docker を読むと
VOLUME /var/lib/rabbitmq
が指定されているから RUN コマンドで chmod できないらしい。VOLUME コマンドで指定していないディレクトリで chmod してからコピーすればよいとのこと。VOLUME /var/lib/rabbitmq
が指定されているのは https://github.com/docker-library/rabbitmq/blob/master/3.8/alpine/Dockerfile 参照。
ただし Dockerfile 内で
COPY --chown=rabbitmq:rabbitmq .erlang.cookie /tmp/
、RUN chmod 600 /tmp/.erlang.cookie
の後にRUN cp -p /tmp/.erlang.cookie /var/lib/rabbitmq/
を実行してもコピーされませんでした。これは Dockerfile ではなくコンテナ起動時に command あるいは entrypoint で実行するシェルスクリプトでやればコピーできます。
最終的に以下のようになりました。
■docker/rabbitmq/Dockerfile
ARG RABBITMQ_VERSION FROM rabbitmq:${RABBITMQ_VERSION}-alpine RUN apk add --no-cache tzdata COPY --chown=rabbitmq:rabbitmq .erlang.cookie /tmp/ RUN chmod 600 /tmp/.erlang.cookie
- 以下の2行を追加しました。.erlang.cookie を /tmp にコピー後、owner を rabbitmq:rabbitmq へ、permission を
-rw-------
へ変更します。COPY --chown=rabbitmq:rabbitmq .erlang.cookie /tmp/
RUN chmod 600 /tmp/.erlang.cookie
■docker-compose.yml
# RabbitMQ Clustering rabbitmq1: build: context: ./docker/rabbitmq args: - RABBITMQ_VERSION=${RABBITMQ_VERSION} image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq1 hostname: rabbitmq1 environment: - TZ=Asia/Tokyo - RABBITMQ_DEFAULT_USER - RABBITMQ_DEFAULT_PASS - RABBITMQ_DEFAULT_VHOST command: - /bin/sh - -c - | cp -p /tmp/.erlang.cookie /var/lib/rabbitmq/ ls -al /var/lib/rabbitmq/ rabbitmq-server rabbitmq2: image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq2 hostname: rabbitmq2 environment: - TZ=Asia/Tokyo volumes: - ./docker/rabbitmq/cluster-entrypoint.sh:/usr/local/bin/cluster-entrypoint.sh entrypoint: /usr/local/bin/cluster-entrypoint.sh depends_on: - rabbitmq1 rabbitmq3: image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq3 hostname: rabbitmq3 environment: - TZ=Asia/Tokyo volumes: - ./docker/rabbitmq/cluster-entrypoint.sh:/usr/local/bin/cluster-entrypoint.sh entrypoint: /usr/local/bin/cluster-entrypoint.sh depends_on: - rabbitmq1
- rabbitmq1 に command を追加しました。ここで /tmp/.erlang.cookie を /var/lib/rabbitmq/ の下へコピーした後、rabbitmq-server を起動します。
- rabbitmq2 の entrypoint を
/bin/sh -c /usr/local/bin/cluster-entrypoint.sh
→/usr/local/bin/cluster-entrypoint.sh
に修正しました(rabbitmq3 と違っていたのと /bin/sh -c があるとなぜかうまく動作しなかったためです)。
■docker/rabbitmq/cluster-entrypoint.sh
#!/bin/bash set -e cp -p /tmp/.erlang.cookie /var/lib/rabbitmq/ ls -al /var/lib/rabbitmq/ rabbitmq-diagnostics erlang_cookie_sources # Start RMQ from entry point. # This will ensure that environment variables passed # will be honored rabbitmq-server -detached # Wait a while for rabbitmq1 to start sleep 15s # Do the cluster dance rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl join_cluster rabbit@rabbitmq1 # Stop the entire RMQ server. This is done so that we # can attach to it again, but without the -detached flag # making it run in the forground rabbitmqctl stop # Wait a while for the app to really stop sleep 3s # Start it rabbitmq-server
- 以下の3行を追加しました。/tmp/.erlang.cookie を /var/lib/rabbitmq/ の下へコピーします。また https://www.rabbitmq.com/clustering.html#cookie-file-troubleshooting に .erlang.cookie をチェックするコマンドが記載されていたのでそれも追加します。
cp -p /tmp/.erlang.cookie /var/lib/rabbitmq/
ls -al /var/lib/rabbitmq/
rabbitmq-diagnostics erlang_cookie_sources
/usr/local/bin/docker-entrypoint.sh rabbitmq-server -detached
→rabbitmq-server -detached
に変更します(/usr/local/bin/docker-entrypoint.sh
がなくても動いたので削除しました)。また rabbitmq1 の起動が完了するまで時間がかかるためsleep 15s
を追加しました。- https://www.rabbitmq.com/clustering.html#creating に記載があったので
rabbitmqctl reset
を追加しました。 rabbitmqctl stop
の後の待機時間をsleep 2s
→sleep 3s
に変更しました。
docker-compose build --no-cache
コマンドを実行してから docker-compose up -d
コマンドを実行すると無事 rabbitmq1、rabbitmq2、rabbitmq3 の全てが起動しました。
rabbitmq2 のログを見ると RABBITMQ_ERLANG_COOKIE env variable support is deprecated ...
のメッセージは出力されておらずサーバが問題なく起動していますが、今度は HTTP access denied: user 'rabbitmq' - invalid credentials
という warning が延々と出力されていました(この warning は rabbitmq1、rabbitmq3 にも出力されています)。
rabbitmq の管理画面から rabbitmq / 12345678 でログインしようしてもログインできませんでした。
HTTP access denied: user 'rabbitmq' - invalid credentials
が出力されないようにする+管理画面からログインできるようにする
使っている RabbitMQ のバージョンは違いますが、CentOS7 RabbitMQ 3.7.4 cluster installation and use の記事を見つけました。「Report an error」のところに記述があり、rabbitmqctl add_user
コマンドで rabbitmq ユーザを作成すればよいみたいです。
docker-compose.yml の rabbitmq1 コンテナの command で rabbitmqctl add_user
コマンドを実行してもエラーが出て登録できなかったので、rabbitmqctl add_user
コマンド実行用のコンテナを作成して対応することにします。
docker/rabbitmq の下に create-user-entrypoint.sh を新規作成し、以下の内容を記述します。sleep の時間は 15s だと rabbitmq1 が起動完了する前に rabbitmqctl add_user
コマンドを実行する時があったのでここでは 30s にしました。
#!/bin/bash set -e cp -p /tmp/.erlang.cookie /var/lib/rabbitmq/ ls -al /var/lib/rabbitmq/ rabbitmq-diagnostics erlang_cookie_sources # Wait a while for rabbitmq1 to start sleep 30s rabbitmqctl -n rabbit@rabbitmq1 add_user ${RABBITMQ_DEFAULT_USER} ${RABBITMQ_DEFAULT_PASS} rabbitmqctl -n rabbit@rabbitmq1 set_user_tags ${RABBITMQ_DEFAULT_USER} administrator rabbitmqctl -n rabbit@rabbitmq1 set_permissions -p / ${RABBITMQ_DEFAULT_USER} ".*" ".*" ".*"
docker-compose.yml に rabbitmq-create-user コンテナの記述を追加します。
# RabbitMQ Clustering rabbitmq1: build: context: ./docker/rabbitmq args: - RABBITMQ_VERSION=${RABBITMQ_VERSION} image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq1 hostname: rabbitmq1 environment: - TZ=Asia/Tokyo - RABBITMQ_DEFAULT_USER - RABBITMQ_DEFAULT_PASS - RABBITMQ_DEFAULT_VHOST command: - /bin/sh - -c - | cp -p /tmp/.erlang.cookie /var/lib/rabbitmq/ ls -al /var/lib/rabbitmq/ rabbitmq-server rabbitmq-create-user: image: rabbitmq:${RABBITMQ_VERSION}-alpine-custom container_name: rabbitmq-create-user hostname: rabbitmq-create-user environment: - TZ=Asia/Tokyo - RABBITMQ_DEFAULT_USER - RABBITMQ_DEFAULT_PASS volumes: - ./docker/rabbitmq/create-user-entrypoint.sh:/usr/local/bin/create-user-entrypoint.sh entrypoint: /usr/local/bin/create-user-entrypoint.sh depends_on: - rabbitmq1 rabbitmq2: ..........
- 作成するユーザ名、パスワードは環境変数 RABBITMQ_DEFAULT_USER、RABBITMQ_DEFAULT_PASS の設定をそのまま使っています。
- rabbitmq1 コンテナの environment の RABBITMQ_DEFAULT_USER、RABBITMQ_DEFAULT_PASS は不要なのでは?と思って削除したらエラーが出たので残しています。
動作確認します。docker-compose up -d
コマンドを実行して起動した後、
rabbitmq-create-user コンテナのログを確認すると rabbitmqctl add_user
コマンド等は全て正常に実行できており、
rabbitmq1、rabbitmq2 コンテナのログを見ると HTTP access denied: user 'rabbitmq' - invalid credentials
は出力されていません。
http://localhost:15672/ にアクセスして rabbitmq / 12345678 でログインすると無事ログインできました。
rabbitmq_exporter の方は、Grafana で RabbitMQ の情報を表示させてみると問題なさそうです。
clean タスク実行 → Rebuild Project 実行 → build タスクを実行する
clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると無事 "BUILD SUCCESSFUL" のメッセージが出力されました。
変更前の docker image を削除する
以下の docker image を削除します。
- rabbitmq:3.8.2-management-alpine
- rabbitmq:3.8.2-management-alpine-custom
履歴
2020/12/18
初版発行。
2020/12/19
ユーザを作成できない場合があったため、docker/rabbitmq/create-user-entrypoint.sh 内の rabbitmq1 の起動待機時間を sleep 20s
→ sleep 30s
に変更しました。