生き返れMariaDB

問題文 

A社の社内システム用に作成したdocker上のmariaDBコンテナが非常に不安定で、すぐに落ちてしまい、社内システムの可用性に影響が出ている。 このシステムはとある社員が一人で作成したが、完成した日に退職してしまって連絡が取れず、このシステムの仕様書なども存在しない。

現在コンテナに安定したアクセスができない原因を報告し、 コンテナをレコード情報を保持したまま動作が可能となるように復旧せよ。

初期状態  

  • VM上でdocker ps -aをするとmariaDBコンテナが1つ存在している
  • VM上でdocker start mariaDBdocker exec -it mariaDB bashをしても落ちて開けない

終了状態  

  • コンテナが継続して起動している状態である
  • docker exec -it mariaDB bashでコンテナに入ることができ、入った際にMariaDBのDBictsc_incusersテーブルを見たときに
+----+------------+-----------+------+-------+
| 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   |
+----+------------+-----------+------+-------+

を見ることが可能で、復旧したことが分かります。