Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その23 )( Docker Network メモ書き+Prometheus の HTTP API でデータを削除する )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
- Docker Compose で Redis と RabbitMQ の Clustering 構成を構築してみましたが、Docker の network 機能が全然分かってないな。。。と思ったので、その辺を調べてみます。
- 試している途中で Grafana 上に不要なデータが表示されるようになったので、Prometheus の HTTP API を有効にして削除しています。
参照したサイト・書籍
Networking Overview
https://docs.docker.com/network/Networking with standalone containers
https://docs.docker.com/network/network-tutorial-standalone/Networking in Compose
https://docs.docker.com/compose/networking/Prometheus: Delete Time Series Metrics
https://www.shellhacks.com/prometheus-delete-time-series-metrics/Prometheus - HTTP API
https://prometheus.io/docs/prometheus/latest/querying/api/High Availability Prometheus and Alertmanager
https://mkezz.wordpress.com/tag/docker/ https://github.com/mkez00/prom-alertmanager-ha- 記事とは無関係ですが、Vagrant で自分が知らないことをやっているサンプルを見かけたので、メモとして残しておきます。
Docker Compose - docker-compose.yml リファレンス
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaaredis/5.0/alpine/Dockerfile
https://github.com/docker-library/redis/blob/f1a8498333ae3ab340b5b39fbac1d7e1dc0d628c/5.0/alpine/DockerfileAlpine Linux package management
https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_managementAlpine Linux で軽量な Docker イメージを作る
https://qiita.com/pottava/items/970d7b5cda565b995fe7
目次
Networking with standalone containers
を試してみたメモ書き- docker-compose で network を指定せずにコンテナを作成した時にコンテナ名でも通信できる理由とは?
- コンテナ名で通信ができるなら hostname の指定は不要なのでは?
- Grafana に追加された
rabbit@791f27a3e17b
を削除するには? - rabbitmq_exporter → haproxy へはコンテナ名でアクセスさせる
- redis-cluster-make コンテナ用の Dockerfile の FROM に指定するイメージを
-alpine
に変更する
手順
Networking with standalone containers
を試してみたメモ書き
Docker のドキュメントに Networking with standalone containers というページがあったので試してみた時のメモ書きです。
docker network ls
コマンドで作成されている docker network を表示できる。デフォルトで作成されているのは bridge, host, none の3つ。- network を指定せずに
docker run
コマンドを実行した場合、bridge が使用される。 - デフォルトの bridge ではコンテナ名で通信できない。ping コマンドを実行すると
bad address
と表示される。IP アドレスでは通信できる。 docker network create --driver bridge <network名>
コマンドでユーザ定義の bridge ネットワークが作成できる。docker run
コマンド実行時に--net
オプションでユーザ定義の network を指定すれば、指定された network が使用される。docker run
コマンド実行後にdocker network connect
コマンドで別の network に接続することも可能(複数接続可能らしい)。
ということは、bridge-a-net, bridge-b-net という2つの bridge のユーザ定義 network を作成した後、
alpine1, alpine2, alpine3 の3つのコンテナを作成し、alpine1 は bridge-a-net へ、alpine3 は bridge-b-net へ、そして alpine2 は bridge-a-net, bridge-b-net の両方へ接続します。
alpine1 から alpine2 に ping は通るが、alpine3 には ping は通らず、
alpine3 から alpine2 に ping は通るが、alpine1 には ping は通らず、
alpine2 から alpine1, alpine2 の両方に ping が通ります。
ifconfig
コマンド、route
コマンドで各コンテナのネットワークインターフェースやルーティングテーブルを確認すると以下の通り。alpine1, alpine3 には eth0 しかありませんが、alpine2 には eth0, eth1 の2つのネットワークインターフェースがあります。
なるほど。。。
docker-compose で network を指定せずにコンテナを作成した時にコンテナ名でも通信できる理由とは?
Networking in Compose によると、デフォルトで作成されている bridge network が使われるのではなく、[projectname]_default
(projectname は docker-compose.yml のあるディレクトリ名)という名前の network が作成されてそれが使われるとのことでした。
確かに docker-compose up -d
コマンドを実行すると、最初に Creating network "ksbysample-webapp-lending_default" with the default driver
というメッセージが出力されていました。
docker network inspect ksbysample-webapp-lending_default
コマンドを実行すると以下の出力でした。
コンテナ名で通信ができるなら hostname の指定は不要なのでは?
docker-compose.yml では rabbitmq1 ~ rabbitmq3 のコンテナの定義に hostname: rabbitmq1
のように hostname を設定していますが、コンテナ名と hostname が同じ文字列でコンテナ名で通信できるのであれば書かなくても良い気がします。
rabbitmq1: image: rabbitmq:${RABBITMQ_VERSION}-alpine container_name: rabbitmq1 hostname: rabbitmq1 environment: - RABBITMQ_ERLANG_COOKIE - RABBITMQ_DEFAULT_USER - RABBITMQ_DEFAULT_PASS - RABBITMQ_DEFAULT_VHOST
rabbitmq1 ~ rabbitmq3 の定義から hostname を削除してみます。
rabbitmq1: image: rabbitmq:${RABBITMQ_VERSION}-alpine container_name: rabbitmq1 environment: - RABBITMQ_ERLANG_COOKIE - RABBITMQ_DEFAULT_USER - RABBITMQ_DEFAULT_PASS - RABBITMQ_DEFAULT_VHOST rabbitmq2: image: rabbitmq:${RABBITMQ_VERSION}-alpine container_name: rabbitmq2 depends_on: - rabbitmq1 environment: - RABBITMQ_ERLANG_COOKIE volumes: - ./docker/rabbitmq/cluster-entrypoint.sh:/usr/local/bin/cluster-entrypoint.sh entrypoint: /bin/sh -c /usr/local/bin/cluster-entrypoint.sh rabbitmq3: image: rabbitmq:${RABBITMQ_VERSION}-alpine container_name: rabbitmq3 depends_on: - rabbitmq1 environment: - RABBITMQ_ERLANG_COOKIE volumes: - ./docker/rabbitmq/cluster-entrypoint.sh:/usr/local/bin/cluster-entrypoint.sh entrypoint: /usr/local/bin/cluster-entrypoint.sh
docker-compose up -d
コマンドを実行するとエラーは出ずに起動し、
HAProxy のログを見ると rabbitmq1 の UP が認識されて(ただし後から rabbitmq2, rabbitmq3 のコンテナが停止していることに気づきました。。。)、
順調かな。。。と思いましたが、管理コンソールを見ると Nodes には1台しか表示されておらず、Name も rabbit@rabbitmq1
ではなく rabbit@791f27a3e17b
になっていました。
Grafana でも RabbitMQ が1台追加されて表示されており、
rabbitmq1 コンテナで hostname
コマンドを実行すると、rabbitmq1 ではなく 791f27a3e17b という文字列が表示されました。hostname を設定しないとこうなるようです。
RabbitMQ には hostname の設定が必要だったので元に戻します。単に通信するだけならば hostname の設定は不要ですが、サーバによっては hostname が指定の文字列で設定されている必要があるようです。
Grafana に追加された rabbit@791f27a3e17b
を削除するには?
hostname の設定を戻してからコンテナを再起動したのですが、rabbit@791f27a3e17b
が残ったままでした。。。
削除する方法を調べたところ、Prometheus: Delete Time Series Metrics のページを見つけたので、この方法を試してみます。
最初に Prometheus 起動時に --web.enable-admin-api
オプションを追加します。prometheus/Dockerfile から ENTRYPOINT の定義をコピーして --web.enable-admin-api
を追加したものを docker-compose.yml に記述します。
prometheus: image: prom/prometheus:latest container_name: prometheus ports: - "9090:9090" volumes: - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - ./docker/prometheus/storage:/prometheus entrypoint: - "/bin/prometheus" - "--storage.tsdb.path=/prometheus" - "--web.console.libraries=/etc/prometheus/console_libraries" - "--web.console.templates=/etc/prometheus/consoles" - "--config.file=/etc/prometheus/prometheus.yml" - "--web.enable-admin-api"
docker-compose up -d
コマンドを実行します。これで Prometheus の HTTP API が呼び出せるようになりました。ブラウザから http://localhost:9090/api/v1/status/flags にアクセスすると、JSON で結果が返ってきます。
削除するデータを特定するための文字列を取得します。Grafana 上で削除対象の「Edit」を選択した後、
rabbitmq_running{node="$node"}
の部分をコピーして $node
の部分を rabbit@791f27a3e17b
に置き換えた文字列 rabbitmq_running{node="rabbit@791f27a3e17b"}
を作成します。
コマンドラインから curl -v -X POST -g 'http://localhost:9090/api/v1/admin/tsdb/delete_series?match[]=rabbitmq_running{node="rabbit@791f27a3e17b"}'
を実行します。
Grafana 上ですぐに削除されませんが、Dashboard を表示し直すと rabbit@791f27a3e17b
が消えました。
--web.enable-admin-api
オプションはデフォルトでは無効化されている機能なので、docker-compose.yml を元に戻しておきます。
rabbitmq_exporter → haproxy へはコンテナ名でアクセスさせる
rabbitmq_exporter が haproxy 経由で rabbitmq にアクセスする時にはホストを経由する必要はないので、コンテナ名でアクセスすることにします。docker-compose.yml の以下の点を変更します。
rabbitmq_exporter: image: kbudde/rabbitmq-exporter:latest container_name: rabbitmq_exporter ports: - "9419:9419" environment: - RABBIT_URL=http://haproxy:15672 - RABBIT_USER=${RABBITMQ_DEFAULT_USER} - RABBIT_PASSWORD=${RABBITMQ_DEFAULT_PASS} - RABBIT_CAPABILITIES=bert,no_sort - PUBLISH_PORT=9419
RABBIT_URL=http://${HOST_IP_ADDRESS}:15672
→RABBIT_URL=http://haproxy:15672
に変更します。
redis_exporter → redis も REDIS_ADDR=redis://${HOST_IP_ADDRESS}:${REDIS_CLUSTER_1_PORT},.....
→ REDIS_ADDR=redis://redis-cluster-1:6379,.....
にしてみたのですが、こちらは正常に動作しなかったので元に戻しました。
redis-cluster-make コンテナ用の Dockerfile の FROM に指定するイメージを -alpine
に変更する
docker/redis/Dockerfile の FROM の記述が FROM redis:${REDIS_VERSION}
となっており -alpine
を付けていなかったので付けることにします。
redis/5.0/alpine/Dockerfile を参考に docker/redis/Dockerfile を以下のように変更します。
ARG REDIS_VERSION FROM redis:${REDIS_VERSION} RUN apk add --no-cache expect
FROM redis:${REDIS_VERSION}
→FROM redis:${REDIS_VERSION}-alpine
に変更します。RUN apt-get update -qq && apt-get install -y expect
→RUN apk add --no-cache expect
に変更します。Alpine Linux だと、パッケージ管理ツールが apk になる、インストール前に update 不要、--no-cache
を付けてキャッシュに残らないようにする、-y
オプションは不要、になるようです。
IntelliJ IDEA の Docker Plugin から redis:5.0.2-custom のイメージを削除した後、docker-compose up -d
コマンドを実行します。
redis-cluster-make コンテナのログを見ると yes が自動入力されており、redis-cli --cluster create
コマンドも正常終了しています。
redis-cluster-6379 コンテナで redis-cli コマンドを起動して cluster nodes
コマンドを実行すると、Resis Cluster 構成が構築できていることが確認できます。
履歴
2018/12/08
初版発行。