0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MySQLの公式Dockerイメージを使ったコンテナ起動時のヘルスチェックはTCP/IP経由で行ったほうが良い

Posted at

TL;DR

MySQLの公式Dockerイメージのヘルスチェックには-h 127.0.0.1オプションを追加してTCP/IP経由で行う。これにより、初期化用の一時サーバではなく本番サーバの起動を確実に検出できる。

healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]

問題の背景

MySQLの公式イメージでは、起動時に以下のプロセスを実行する:

  1. 一時サーバを立ち上げて初期化プロセスを実行
  2. 一時サーバを停止
  3. 本番サーバを起動

docker-entrypoint.shの該当部分:

# Do a temporary startup of the MySQL server, for init purposes
docker_temp_server_start() {
    # For 5.7+ the server is ready for use as soon as startup command unblocks
    if ! "$@" --daemonize --skip-networking --default-time-zone=SYSTEM --socket="${SOCKET}"; then
        mysql_error "Unable to start server."
    fi
}

発生する問題

ドメインソケット経由でのヘルスチェックでは、以下の問題が発生する可能性がある:

  1. ヘルスチェックのタイミングが一時サーバの稼働中と重なると、一時サーバに接続してしまう
  2. 一時サーバへの接続によりヘルスチェックが成功したように見える
  3. その後、一時サーバが停止すると接続が切断される
  4. この現象は起動タイミングに依存するため、断続的に発生する

解決方法

一時サーバには--skip-networkingオプションが設定されているため、TCP/IP接続ができない。したがって、TCP/IP経由でヘルスチェックを行えば、本番サーバが確実に起動していることを確認できる。

docker-composeの設定例

version: "3.8"

services:
  mysql:
    image: mysql:8.0
    healthcheck:
-     test: ["CMD", "mysqladmin", "ping"]
+     test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
      interval: 30s
      timeout: 5s
      retries: 3
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  mysql-data: {}

-h 127.0.0.1を追加することで、TCP/IP経由での接続確認となり、本番サーバの起動を確実に検出できる。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?