生き返れMariaDB
問題文
A社の社内システム用に作成したdocker上のmariaDBコンテナが非常に不安定で、すぐに落ちてしまい、社内システムの可用性に影響が出ている。 このシステムはとある社員が一人で作成したが、完成した日に退職してしまって連絡が取れず、このシステムの仕様書なども存在しない。
現在コンテナに安定したアクセスができない原因を報告し、 コンテナをレコード情報を保持したまま動作が可能となるように復旧せよ。
初期状態
- VM上で
docker ps -a
をするとmariaDB
コンテナが1つ存在している - VM上で
docker start mariaDB
→docker exec -it mariaDB bash
をしても落ちて開けない
終了状態
- コンテナが継続して起動している状態である
docker exec -it mariaDB bash
でコンテナに入ることができ、入った際にMariaDBのDBictsc_inc
のusers
テーブルを見たときに
+----+------------+-----------+------+-------+
| ID | First_Name | Last_Name | Age | Sex |
+----+------------+-----------+------+-------+
| 1 | Tarou | Yamada | 23 | MAN |
| 2 | Emi | Uchiyama | 23 | WOMAN |
| 3 | Ryo | Sato | 25 | MAN |
| 4 | Yuki | Tayama | 22 | WOMAN |
| 5 | Yuto | Takahashi | 21 | MAN |
+----+------------+-----------+------+-------+
が存在している。
- 社内システムがDBを参照出来るよう、3306番ポートが開いている。
配点
- このコンテナが不安定になっている原因を明確な証拠をもとに正しく特定できている(60%)
- コンテナが継続動作するように復旧できている(25%)
- 当該コンテナ上で問題文通りのレコードを参照できる(15%)
解説
こちらの問題では、社内システムのデータベースとして使用している DockerのMariaDB
コンテナの動作が何らかの原因で不安定になっているがその原因を報告し解決する、 というものでした。
まずこの問題でのシステム構成図を説明したいと思います。 このMariaDB
コンテナと社内システムは3306番ポートを用いて接続されており、社内システムは日々このコンテナのMariaDBに対しデータの読み書きを行っています。 また、このコンテナはコンテナ内部にデータを保持している訳ではなく、mariaVOL
というDocker内部のボリュームにコンテナ内部のデータディレクトリ/var/lib/mysql
をマウントしています。よって、このコンテナが破損したとしてもデータベース内部のデータは保持され続ける仕組みとなっております。
トラブルの原因
この問題でMariaDBコンテナが不安定であった原因はこのシステムを退職した社員が「サーバーのメモリが足りないので、メモリを食わないようにしたい」ということでこのMariaDBコンテナが使用できるメモリの量を4MB
にしたことが原因でした。 以下が当該コマンドです。
docker run -m "4M" -v mariaVOL:/var/lib/mysql -d --name mariaDB -e MYSQL_ROOT_PASSWORD=MariaPass -p 3306:3306 -d mariadb:latest
-m
オプションでこのコンテナが利用できるメモリを4MBまでに制限していることが分かります。 ここでは当時打たれたコマンドを出してメモリ制限がされていることが分かりましたが、今回はDockerの設定やログ等でしかトラブルの原因を知ることが出来ません。
この原因を知る例として、細かいものは他にもあるかとは思いますが、大きく2つ紹介します。
1.docker inspect
コマンドを使用する
docker inspect
コマンドは、dockerコンテナの設定情報を参照することが出来るコマンドです。これを見ると、コンテナがどのような設定で動作しているのかが分かります。しかし、この設定データの量は膨大で、全てを見るには時間がかかってしまいます。 例えばですが、この問題の原因のメモリについて調べたい際、docker inspect mariaDB | grep Memory
など、grepコマンドなどを使い検索すると、
"Memory": 4194304,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": -1,
"MemorySwappiness": null,
といった値が出てきます。ここに出た"Memory": 4194304
という値はバイト表記でして、MBに換算すると約4MB
ということが分かります。設定されていた値と同じですね。
2.docker stats
コマンドを使用する
docker stats
コマンドは、コンテナのリソース使用状況を表示するコマンドです。Linuxのtop
コマンドに似たような機能を持っています。 ここで、コンテナのリソース使用状況を知ることが出来ます。
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
eb99786557f7 mariaDB 8.44% 3.664MiB / 4MiB 91.60% 656B / 0B 1.89GB / 0B 3
こちらでもMEM USAGE / LIMIT
の欄で3.664MiB / 4MiB
と見えており、メモリが4MB制限であること、そして使用中のメモリが逼迫している状態であることから不安定になる原因であることが推定出来ます。
解決策
前項の方法でメモリ制限が原因であることを突き止めた場合、現在のトラブルをどのように解決するかについて例を載せます。
1.docker update
コマンドを使用しリソース設定を更新する
docker update
コマンドはコンテナの設定を更新するためのコマンドです。 コンテナの設定をコンテナを作り直すことなく変更することが可能です。 例として、問題のコンテナのメモリ制限を4MBから1GBへと緩和します。例えば、 docker update --memory 1G mariaDB
このコマンドを実行する事により、メモリ上限を4MBから1GBに変更することが出来ます。 docker inspect mariaDB | grep Memory
で見てみると
"Memory": 1073741824,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": -1,
"MemorySwappiness": null,
となり、Memory": 1073741824
(byte)は約1GBですので、1GBへと緩和されたことが分かります。
2.同じ設定のコンテナを作り直す
解法の一つとして、同じ設定のMariaDBコンテナを再作成する方法があります。 docker run -v mariaVOL:/var/lib/mysql -d --name mariaDB -e MYSQL_ROOT_PASSWORD=MariaPass -p 3306:3306 -d mariadb:latest
などで、メモリ制限を緩和、およびメモリ制限を無くしたコンテナを作成します。 ただし、MariaDBのデータベースはボリュームmariaVOL
にマウントされているという点に注意しなければなりません。mariaVOL
へコンテナをマウントしないと、コンテナに入ってもデータベースを参照することが出来なくなってしまいます。
上記の2つの設定のどちらかを適用し、
docker exec -it mariaDB bash
mysql -u root -p ${MYSQL_ROOT_PASSWORD}
use ictsc_inc;
select * from users;
をするとこちらのテーブル
+----+------------+-----------+------+-------+
| ID | First_Name | Last_Name | Age | Sex |
+----+------------+-----------+------+-------+
| 1 | Tarou | Yamada | 23 | MAN |
| 2 | Emi | Uchiyama | 23 | WOMAN |
| 3 | Ryo | Sato | 25 | MAN |
| 4 | Yuki | Tayama | 22 | WOMAN |
| 5 | Yuto | Takahashi | 21 | MAN |
+----+------------+-----------+------+-------+
を見ることが可能で、復旧したことが分かります。