データベースをDockerコンテナとしてデプロイすることは、開発環境やテスト環境では非常に便利ですが、プロダクション環境での運用には慎重な判断が求められます。コンテナ化されたデータベースは、長期的なメンテナンスコストと複雑なトラブルシューティングを伴うため、チームに十分なノウハウとリソースが必要です。
プロダクション環境でDocker上にMySQLを構築する前に、以下のリスクを考慮する必要があります。
- データの永続性とライフサイクル: データベースはシステムの心臓部であり、コンテナオーケストレーションツールが廃れたとしてもデータは残り続けます。インフラの流行にデータ層を過度に依存させるのは危険です。
- 構成の複雑さとリスク: インフラ構成はシンプルであるべきです。Kubernetes、Swarm、NAS、NFSなどを過剰に組み合わせた複雑な構成は、単一障害点を増やし、ストレージI/Oの遅延やネットワーク分断によるデータ破損のリスクを高めます。
- 運用チームのスキルセット: データベースの運用ノウハウを持つエンジニアが、必ずしもDockerやコンテナオーケストレーションに精通しているとは限りません。運用の属人化や引き継ぎの困難さを招く可能性があります。
これらのリスクを許容できる、あるいは十分に緩和できる場合のみ、以下の手順で構築を進めてください。
イメージの取得と管理
公式イメージをプルし、不要になったイメージをクリーンアップする基本的なコマンドです。ここではバージョンを明示的に指定してイミュータブルな環境を維持します。
# 特定のバージョンのイメージを取得
docker image pull mysql:8.0.33
# 不要になったイメージを強制削除
docker image rm --force mysql:8.0.33
コンテナの起動とストレージマッピング
データ、設定、ログをホスト側に永続化するためのボリュームマウントを行い、コンテナを起動します。ポート番号やディレクトリパスは環境に合わせて調整してください。
docker container run --detach \
--name mysql_db_prod \
--publish 3308:3306 \
--restart on-failure:5 \
--volume /opt/mysql/config:/etc/mysql/conf.d \
--volume /opt/mysql/storage:/var/lib/mysql \
--volume /opt/mysql/logs:/var/log/mysql \
--env MYSQL_ROOT_PASSWORD=Initial_Secure_Pass! \
mysql:8.0.33
パラメータの解説:
--restart on-failure:5: 異常終了時に最大5回まで再起動を試みます。無条件のalwaysよりも安全なフェイルセーフ策です。--publish 3308:3306: ホストの3308ポートをコンテナの3306ポートにマッピングし、ポートの競合を避けます。--volume: 設定ファイル(conf.d)、データディレクトリ、ログディレクトリをホストとバインドマウントし、コンテナが削除されてもデータを保護します。
データベースの初期設定とアクセス制御
コンテナ内部にアクセスし、ルートユーザーのセキュリティ設定とリモートアクセスの構成を行います。
# 実行中のコンテナのシェルにアタッチ
docker container exec -it mysql_db_prod bash
# MySQLクライアントで接続
mysql -u root -p'Initial_Secure_Pass!'
接続後、以下のSQLを実行してパスワードの変更とホスト制限の解除を行います。
-- ルートユーザーのホスト制限をローカルホストからすべてのホストに変更
UPDATE mysql.user SET Host = '%' WHERE User = 'root' AND Host = 'localhost';
-- パスワードの変更と有効期限の無効化
ALTER USER 'root'@'%' IDENTIFIED BY 'New_Strong_Password_2024!' PASSWORD EXPIRE NEVER;
-- 権限テーブルをリロードして変更を反映
FLUSH PRIVILEGES;
プロダクション環境における既知の課題
レプリケーション(主従構成)の脆弱性
Docker環境、特にオーケストレーションツール上でMySQLのレプリケーションを構成する場合、ネットワークとリソースの安定性が極めて重要になります。
- ネットワークジッターとデータ不整合: 高トラフィック時にネットワークの微小な遅延やパケットロスが発生すると、レプリケーション遅延やスレーブの停止を引き起こす可能性があります。
- ツールによるロックの干渉: DBeaverなどのGUIツールを使用して手動でトランザクションをコミットする際、意図しないテーブルロックが発生し、マスターとスレーブのデータ不整合を招くケースがあります。
- リソース変動とマイグレーション: Kubernetes環境において、ノードのCPU使用率スパイクやメモリ圧迫によってPodが自動マイグレーション(Eviction)されると、ストレージI/Oが一時中断し、レプリケーション構成が破綻するリスクがあります。
自動再起動ポリシーの罠
コンテナの再起動ポリシー(例: restart: always)は、一見すると可用性を高めるように見えますが、データベースのようなステートフルなアプリケーションでは逆効果になることがあります。
- サイレントなデータ破損: クラスタ環境で自動再起動が頻繁に発生すると、アプリケーション層は接続エラーを一時的なものとしてリトライし、ユーザーにエラーを通知しません。しかし、裏側ではトランザクションの途中でコンテナが強制終了・再起動されており、データの不整合や破損が進行している可能性があります。
- フェイルオーバーとの競合: データベース自体のクラスタリング機能(例: InnoDB Cluster)や外部のヘルスチェックと、Dockerの自動再起動ポリシーが競合し、スプリットブレイン(多重マスター状態)を引き起こす危険性があります。