Docker: run linkオプションによるmysqlコンテナ間のリンク

例えば、Webアプリケーションを作成する際のDocker構成の一例としてデータベース(DB)機能のみのコンテナを起動し、WebアプリコンテナからDBコンテナにアクセスする際の方法として、ホストネットワークIPへバインディングせずに、docker runサブコマンドのlinkオプションを活用する方法がある。本記事は公式mysqlサーバコンテナを作成しlinkオプションで起動したコンテナからサーバへ接続する手法を紹介する。尚、参考にした公式ドキュメントリンクは記事末尾を参照すること。また、使用docker engine versionは1.9.1。

linkオプションの機能

仮にリンクされる側のコンテナ(DBサーバ等)をsource、リンクする側のコンテナ(Webアプリ、クライアント等)をrecipientと置いた時、linkオプションがrecipientコンテナに提供する機能は下記の通り。

  1. sourceコンテナのIPアドレス、EXPOSEしているポート、プロトコルをrecipientコンテナの環境変数に登録
  2. sourceコンテナの環境変数をrecipientコンテナの環境変数に登録
  3. sourceコンテナのIPアドレスをrecipientコンテナの/etc/hostsへ登録

DockerコンテナのIPアドレスはdocker run時にランダムに割り振られ、他のコンテナから仮想ブリッジ経由で当該IPにアクセスする際は、上記の様なlink機能が必要となる。
以下にmysqlコンテナを用いて、上記機能の確認結果を示す。
docker_link_mysql
尚、公式mysqlコンテナのリンクは下記の通り。
https://hub.docker.com/_/mysql/
DockerfileのEXPOSE指定は3306ポートとなる。

mysqlサーバコンテナの作成

-eオプションで指定している環境変数MYSQL_ROOT_PASSWORDはmysqlのrootパスワードとなる。ちなみに、toorはBlack hat(現kali)でデフォルトで設定されているパスワード。私はテスト用だと良く使用する。
続いて、mysql01コンテナ上のbashからコンテナのステータスを確認する。

psコマンドにてコンテナ上でmysqldが稼働していること、envコマンドにてコンテナ上にMYSQL_ROOT_PASSWORDが登録されていること、mysqlコマンドにてmysqldへログインしsqlを打鍵できることを確認できる。

mysqlクライアントコンテナの作成

mysqlクライアントとしてのコンテナが必要である為、手っ取り早くmysqlコマンドが使える公式mysqlコンテナを活用。エイリアス名はdb。–rmオプションを付けることでコンテナ終了時、すなわち/bin/bash終了時にコンテナを削除する設定とする。

上記環境変数から分かるとおり、source側のコンテナ情報はDB_PORT_3306〜で登録され、source側の環境変数もDB_ENV_〜で登録されている。
参考) 公式ガイド: Legacy container links

hostsファイルにもコンテナ名(mysql01)、エイリアス名(db)、コンテナID(afceca423dc9)でホストエントリが登録されている。

mysqlサーバコンテナへの接続

linkを用いたコンテナ構成で本番デプロイを行う際、環境変数に渡す情報と、コンテナの起動順序に考慮が必要となる。大量のコンテナを管理する場合にDocker ComposeやKubernetesが必要なる理由が良くわかる。

recipientコンテナ上の/etc/hostsファイルの動的更新

仮にmysql01:dbコンテナのみをrestartした場合、再割り当てされたIPアドレス情報はrecipientコンテナの/etc/hostsファイルに即時反映される。但し、環境変数<エイリアス名>_PORT_3306_TCP_ADDRは当該プロセスが終了するまでは変更されない。

再度、berserk_wright上でhostsを確認すると、mysql01のIPが172.17.0.4から172.17.0.3に変更されているが、DB_PORT_3306_TCP_ADDRは変更されていない。

そう考えると、コード中で使用するsourceのIPアドレス指定は環境変数よりもhostsに記載のコンテナ名、エイリアス名の方が、コンテナの動的なIP変更にも耐えられる設計となり良いかと思う。

参考サイト