3.4. MongoDB
3.4.1. 概要
OpenShift Online には、MongoDB の実行用のコンテナーイメージがあります。このイメージでは、設定で指定されるユーザー名、パスワード、データベース名を基にデータベースサービスが提供されます。
3.4.2. バージョン
現時点で、OpenShift Online は MongoDB のバージョン 2.6、3.2、および 3.4 を提供しています。
3.4.3. イメージ
RHEL 7 イメージは、Red Hat レジストリーから入手できます。
$ docker pull registry.access.redhat.com/rhscl/mongodb-26-rhel7 $ docker pull registry.access.redhat.com/rhscl/mongodb-32-rhel7 $ docker pull registry.access.redhat.com/rhscl/mongodb-34-rhel7
このイメージは、mongodb
イメージストリームで使用することができます。
3.4.4. 設定および用途
3.4.4.1. データベースの初期化
MongoDB は、一時ボリュームまたは永続ボリュームで設定できます。ボリュームを初めて使用する場合には、データベースとデータベースの管理ユーザーが作成され、次に MongoDB デーモンが起動します。その後、MongoDB デーモンが起動します。別のコンテナーにボリュームを再アタッチする場合には、データベース、データベースユーザー、管理者ユーザーは作成されず、MongoDB デーモンが開始されます。
以下のコマンドは、新しいデータベースの Pod を作成し、さらに一時ボリュームが含まれるコンテナー内で MongoDB を実行します。
$ oc new-app \ -e MONGODB_USER=<username> \ -e MONGODB_PASSWORD=<password> \ -e MONGODB_DATABASE=<database_name> \ -e MONGODB_ADMIN_PASSWORD=<admin_password> \ mongodb:2.6
3.4.4.2. コンテナーでの MongoDB コマンドの実行
OpenShift Online は Software Collections (SCL) を使用して、MongoDB をインストールし、起動します。(デバッグ用に) 実行中のコンテナー内で MongoDB コマンドを実行する場合には bash を使用して呼び出す必要があります。
これを実行するには、まず 実行中の MongoDB Pod の名前を特定します。たとえば、現在のプロジェクトで Pod の一覧を表示できます。
$ oc get pods
次に、任意の Pod に対してリモートシェルセッションを開きます。
$ oc rsh <pod>
コンテナーに入ると、必要な SCL が自動的に有効になります。
Bash シェルから mongo コマンドを実行し、MongoDB の対話セッションを開始して通常の MongoDB 操作が実行できるようになりました。たとえば、sampledb データベースに切り替えてデータベースユーザーとして認証するには、以下を実行します。
bash-4.2$ mongo -u $MONGODB_USER -p $MONGODB_PASSWORD $MONGODB_DATABASE MongoDB shell version: 2.6.9 connecting to: sampledb >
完了したら、CTRL+D を押して、MongoDB セッションを終了します。
3.4.4.3. 環境変数
MongoDB ユーザー名、パスワード、データベース名および admin のパスワードは、以下の環境変数で設定する必要があります。
変数名 | 説明 |
---|---|
| 作成する MongoDB アカウントのユーザー名 |
| ユーザーアカウントのパスワード |
| データベース名 |
| admin ユーザーのパスワード |
ユーザー名、パスワード、データベース名および admin パスワードを指定する必要があります。この 4 つすべてを指定しない場合には、Pod は起動に失敗し、OpenShift Online は Pod の再起動を継続的に試行します。
管理者ユーザーは admin に設定され、そのパスワードは、 MONGODB_ADMIN_PASSWORD
環境変数を設定して指定する必要があります。このプロセスは、データベースの初期化の実行時に行います。
MongoDB 設定は、以下の環境変数で設定できます。
変数名 | 説明 | デフォルト |
---|---|---|
| データファイルの事前割り当てを無効にします。 |
|
| MongoDB がより小さなデータファイルサイズを使用するようにデフォルト設定します。 |
|
| MongoDB を Quiet モードで実行して、出力量を制限しようとします。 |
|
テキスト検索は、MongoDB バージョン 2.6 以降ではデフォルトで有効になっているので、設定可能なパラメーターはありません。
3.4.4.4. ボリュームのマウントポイント
MongoDB イメージはマウントしたボリュームで実行して、データベース用に永続ストレージを有効化できます。
- /var/lib/mongodb/data: これは、MongoDB がデータベースファイルを保存するデータベースのディレクトリーです。
3.4.4.5. パスワードの変更
パスワードはイメージ設定の一部であるため、データベースユーザー (MONGODB_USER
) と admin ユーザーのパスワードを変更するための唯一のサポートされている方法とし、環境変数 MONGODB_PASSWORD
と MONGODB_ADMIN_PASSWORD
をそれぞれ変更することができます。
現在のパスワードは、Pod またはデプロイメント設定を Web コンソールで表示するか、CLI で環境変数を表示して、確認できます。
$ oc set env pod <pod_name> --list
MongoDB で直接データベースのパスワードを変更すると、変数に保存されている値と実際のパスワードが一致しなくなる可能性があります。データベースコンテナーが起動するたびに、パスワードは環境変数に保存されている値にリセットされます。
これらのパスワードを変更するには、oc set env
コマンドを使用して、関連するデプロイメント設定の任意の環境変数 1 つまたは両方を更新します。たとえば、テンプレートからアプリケーションを作成する場合など、複数のデプロイメント設定がこれらの環境変数を使用する場合には、デプロイメント設定ごとに変数を更新し、パスワードがどこでも同期されるようにします。これは、すべて同じコマンドで実行できます。
$ oc set env dc <dc_name> [<dc_name_2> ...] \ MONGODB_PASSWORD=<new_password> \ MONGODB_ADMIN_PASSWORD=<new_admin_password>
アプリケーションによっては、アプリケーションの他の場所にあるパスワードの他の環境変数を更新して一致させる必要があるものもあります。たとえば、フロントエンド Pod のより一般的な DATABASE_USER
変数などは、データベースユーザーのパスワードと一致する必要がある場合があります。必要とされる環境変数すべてにおいて、パスワードがアプリケーションごとに一致しているようにしてください。 一致しない場合には、トリガーされた時点で、Pod の再デプロイメントが失敗する場合があります。
設定変更トリガーが設定されている場合には、環境変数を更新すると、データベースサーバーの再デプロイメントがトリガーされます。設定されていない場合には、新しいデプロイメントを手動で起動して、パスワードの変更を適用する必要があります。
新規パスワードが有効になっていることを確認するには、まず、実行中の MongoDB Pod に対してリモートシェルセッションを開きます。
$ oc rsh <pod>
Bash シェルから、データベースユーザーの新規パスワードを確認します。
bash-4.2$ mongo -u $MONGODB_USER -p <new_password> $MONGODB_DATABASE --eval "db.version()"
パスワードが正しく変更された場合には、以下のような出力が表示されるはずです。
MongoDB shell version: 2.6.9 connecting to: sampledb 2.6.9
admin ユーザーの新規パスワードを確認するには、以下を実行します。
bash-4.2$ mongo -u admin -p <new_admin_password> admin --eval "db.version()"
パスワードが正しく変更された場合には、以下のような出力が表示されるはずです。
MongoDB shell version: 2.6.9 connecting to: admin 2.6.9
3.4.5. テンプレートからのデータベースサービスの作成
OpenShift Online には テンプレートが含まれており、新規データベースサービスの作成を簡素化します。テンプレートには、必須の環境変数をすべて定義するパラメーターフィールドがあり (ユーザー、パスワード、データベース名など)、自動生成されたパスワード値など、事前定義済みのデフォルト値が設定されます。また、テンプレートは デプロイメント設定 および サービス の両方を定義します。
MongoDB テンプレートは、クラスターの初期設定時にクラスター管理者により、デフォルトの openshift プロジェクトに登録しておく必要があります。
以下のテンプレートを使用できます。
-
mongodb-persistent
は、データベースのデータ用に永続ボリュームストアを使用するので、データは Pod が再起動されても残ります。
この説明に従い、テンプレートをインスタンス化できます。
サービスをインスタンス化したら、データベースにアクセスする予定のある別のコンポーネントのデプロイメント設定に、ユーザー名、パスワード、データベース名の環境変数をコピーできます。このコンポーネントは、定義したサービスを使用してこのデータベースにアクセスできます。
3.4.6. MongoDB レプリケーション
Red Hat は、StatefulSet を使用した MongoDB のレプリケーション (クラスタリング) 用に、概念実証 テンプレートを提供します。GitHub からサンプルテンプレート を入手できます。
たとえば、現在のプロジェクトのテンプレートライブラリーにテンプレートのサンプルをアップロードするには、以下を実行します。
$ oc create -f \ https://raw.githubusercontent.com/sclorg/mongodb-container/master/examples/petset/mongodb-petset-persistent.yaml
以下のテンプレートサンプルでは、永続ストレージを使用します。このテンプレートを使用するには、クラスターで永続ボリュームが利用できるようにする必要があります。
OpenShift Online は正常でない Pod (コンテナー) を自動的に再起動するので、レプリカセットのメンバーの 1 つまたは複数で、クラッシュまたは障害が発生すると、レプリカセットメンバーは再起動されます。
レプリカセットのメンバーがダウンまたは再起動している場合に考えられるシナリオは以下のいずれかです。
プライマリーメンバーがダウンしている:
このような場合には、他の 2 つのメンバーが新しいプライマリーを選択します。新しいプライマリーが選択されるまで、読み取りには影響はありませんが、書き込みが失敗してしまいます。正常に選択された後には、書き込みおよび読み取りは通常通りに処理されます。
セカンダリーメンバーの 1 つがダウンしている:
読み取りおよび書き込みには影響はありません。
oplogSize
設定と書き込み速度によって、3 番目のメンバーがレプリカセットへの参加に失敗する可能性があるため、手動の介入によりデータベースのコピーをもう一度同期する必要があります。2 つのメンバーがダウンしている:
3 つのメンバーで構成されるレプリカセットメンバーが他のメンバーに到達できない場合には、プライマリーロールが指定されていれば、そのロールが取り消されます。このような場合には、読み取りはセカンダリーメンバーが行い、書き込みに失敗します。他のメンバーが 1 つでも起動したらすぐに、新しいプライマリーメンバーが選択され、読み取りおよび書き込みが通常通りに処理されます。
全メンバーがダウンしている:
このように極端な場合は、読み取りおよび書き込み両方に失敗します。2 つ以上のメンバーが起動してくると、レプリカセットメンバーにプライマリーとセカンダリーメンバーが含まれるように選択が行われ、その後に読み取りと書き込みが通常通りに処理されます。
これが MongoDB の推奨のレプリケーションストラテジーです。
実稼働環境の場合には、できるだけメンバー間の分離を確保する必要があります。StatefulSet Pod を異なるノードにスケジューリングするノード選択機能を 1 つまたは複数使用し、個別のボリュームでサポートされるストレージを提供することを推奨します。
3.4.6.1. 制限
- MongoDB 3.2 のみがサポートされます。
- スケールダウンする場合には、レプリカセットの設定は手動で更新する必要があります。
ユーザーおよび管理者のパスワードの変更は手動のプロセスで行います。以下を実行する必要があります。
- StatefulSet 設定の環境変数の値を更新する
- データベースのパスワードを変更する
- 順次 Pod をすべて再起動する
3.4.6.2. サンプルテンプレートの使用
事前作成されている永続ボリューム 3 つあり、永続ボリュームのプロビジョニングが設定されていることを前提とします。
MongoDB クラスターを作成する新規プロジェクトを作成します。
$ oc new-project mongodb-cluster-example
サンプルテンプレートを使用して新規アプリケーションを作成します。
$ oc new-app https://raw.githubusercontent.com/sclorg/mongodb-container/master/examples/petset/mongodb-petset-persistent.yaml
このコマンドでは、3 つのレプリカセットメンバーを含む MongoDB クラスターが作成されました。
新規の MongoDB Pod のステータスを確認します。
$ oc get pods NAME READY STATUS RESTARTS AGE mongodb-0 1/1 Running 0 50s mongodb-1 1/1 Running 0 50s mongodb-2 1/1 Running 0 49s
サンプルのテンプレートからクラスターを作成すると、3 つのメンバーを含むレプリカセットが作成されます。Pod が実行されると、以下のようにこれらの Pod でさまざまなアクションを実行できます。
Pod の 1 つのログを確認します。
$ oc logs mongodb-0
Pod にログインします。
$ oc rsh mongodb-0 sh-4.2$
MongoDB インスタンスにログインします。
sh-4.2$ mongo $MONGODB_DATABASE -u $MONGODB_USER -p$MONGODB_PASSWORD MongoDB shell version: 3.2.6 connecting to: sampledb rs0:PRIMARY>
3.4.6.3. スケールアップ
MongoDB は、レプリカセット内に奇数の数のメンバーを指定することを推奨します。永続ボリュームが十分に存在し、動的ストレージプロビジョナーがある場合には、oc scale
を使用してスケールアップを行います。
$ oc scale --replicas=5 statefulsets/mongodb $ oc get pods NAME READY STATUS RESTARTS AGE mongodb-0 1/1 Running 0 9m mongodb-1 1/1 Running 0 8m mongodb-2 1/1 Running 0 8m mongodb-3 1/1 Running 0 1m mongodb-4 1/1 Running 0 57s
これにより、レプリカセットと接続する新規 Pod が作成され、設定が更新されます。
oplogSize
設定よりもデータベースのサイズが大きい場合には、既存のデータベースは手動でスケールアップする必要があります。このような場合には、新規メンバーの初回同期を手動で行う必要があります。詳しい情報は、「Check the Size of the Oplog」および「MongoDB Replication」ドキュメントを参照してください。
3.4.6.4. スケールダウン
レプリカセットをスケールダウンするには、メンバー数を 5 つから 3 つ、または 3 つから 1 つのみに変更することができます。
前提条件 (ストレージの空き容量、既存のデータベースのサイズ、oplogSize
) を満たす場合には、手動での介入なしにスケールアップができますが、スケールダウンは常に手動での介入が必要です。
スケールダウンの方法:
oc scale
コマンドを使用して、新しいレプリカ数を設定します。$ oc scale --replicas=3 statefulsets/mongodb
新しいレプリカ数が以前の数の過半数を占める場合には、削除された Pod の 1 つに、プライマリーメンバーロールを指定されていた時のために、レプリカセットにより新しいプライマリーが選択される場合があります。たとえば、メンバーを 5 から 3 にスケールダウンする場合などです。
また、少ない数にスケールダウンすると一時的に、レプリカセットに含まれるのがセカンダリーメンバーだけで、読み取り専用モードとなることがあります。たとえば、メンバーを 5 から 1 にスケールダウンする場合などです。
存在しなくなったメンバーを削除するように、レプリカセットの設定を更新します。
これは、レプリカ数の検査 (downward API 経由で公開) や StatefulSet から削除された Pod を判断する
PreStop
Pod フックを設定し、それ以外の理由で再起動されないようにする実装など、今後改善される可能性があります。- 無効になった Pod が使用するボリュームを消去します。