Docker はクラスター MongoDB 実装手順を構築します

Docker はクラスター MongoDB 実装手順を構築します

序文

会社の業務上のニーズにより、独自の MongoDB サービスを構築する予定です。MongoDB のクラウド データベースは非常に高価なため、レプリカ セット方式を使用して、プライマリ 1 台、セカンダリ 1 台、調停 1 台の 3 台のサーバーでクラスターを構築します。

基本概念

レプリカ セット: レプリカ セットは、プライマリ サーバーと複数のセカンダリ サーバーで構成される MongoDB インスタンスのクラスターです。

  • マスター: マスター ノードはすべての書き込み操作を受け取ります。プライマリ ノードは、データセットに加えられたすべての変更を oplog に記録します。
  • セカンダリ: プライマリ ノードの oplog をコピーし、そのデータ セットに操作を適用します。プライマリ ノードが使用できない場合は、適格なセカンダリ ノードが新しいプライマリ ノードとして選出されます。
  • アービター: 選択をロードします。プライマリ ノードが使用できない場合は、セカンダリ ノードの 1 つをプライマリ ノードとして選択します。

シャーディング:

マスタースレーブ

  • MongoDB 4.0 以降を実行すると、次のメッセージが表示されます: [main] マスター/スレーブ レプリケーションはサポートされなくなりました。これは、MongoDB 4.0 以降ではマスター/スレーブ レプリケーションがサポートされなくなったことを意味します。

1. 環境整備

CentOS 7.6 64ビットシステムを使用してDocker、Docker-compose、Docker-Swarmをインストールします。

2. キーファイルの生成

  • MongoDB は KeyFile 認証を使用します。レプリカ セット内の各 MongoDB インスタンスは、KeyFile コンテンツを共有パスワードとして使用し、他のメンバーを認証します。 MongoDB インスタンスは、正しい KeyFile を持っている場合にのみレプリカ セットに参加できます。
  • keyFile の内容の長さは 6 ~ 1024 文字で、KeyFile の内容はレプリカ セットのすべてのメンバーで同じである必要があります。
  • 注意すべき点の 1 つは、UNIX システムでは、KeyFile にグループ権限または完全な権限を設定できないことです (つまり、権限は X00 に設定する必要があります)。 Windows では、keyFile の権限はチェックされません。
  • 任意の方法を使用して keyFile を生成できます。たとえば、次の操作では openssl を使用して、複雑なランダムな 1024 文字の文字列を生成します。次に、chmod を使用してファイル権限を変更し、ファイル所有者にのみ読み取り権限を付与します。
  • これは、keyFile を生成するための MongoDB が公式に推奨する方法です。
# セキュリティを確保するには 400 権限が必要です。そうでない場合、mongod は openssl rand -base64 756 > mongodb.key の起動時にエラーを報告します。
chmod 400 mongodb.key

2. ホスト間ネットワークを作成する

クラスターを構築するには、ホスト間で通信する必要があります。オーバーレイ ネットワークを構築するには、Docker Swarm ツールを使用する必要があります。 Docker Swarm は Docker の組み込みクラスター ツールであり、Docker デーモンのクラスターにサービスをより簡単にデプロイするのに役立ちます。

クラスターに Docker を追加するには、まずクラスターが必要です。任意の Docker インスタンスで docker swarm init を使用してクラスターを初期化できます。

$ sudo docker swarm 初期化

Swarm が初期化されました: 現在のノード (t4ydh2o5mwp5io2netepcauyl) がマネージャーになりました。

この Swarm にワーカーを追加するには、次のコマンドを実行します。

  docker swarm に参加 --token SWMTKN-1-4dvxvx4n7magy5zh0g0de0xoues9azekw308jlv6hlvqwpriwy-cb43z26n5jbadk024tx0cqz5r 192.168.1.5:2377

クラスターが初期化されると、この Docker インスタンスは自動的にクラスター管理ノードになり、他の Docker インスタンスは、ここに示されている docker swarm join コマンドを実行してクラスターに参加できるようになります。

クラスターに追加されるノードは、デフォルトでは通常のノードです。管理ノードとしてクラスターに参加する場合は、docker swarm join-token コマンドを使用して、管理ノードの join コマンドを取得できます。

$ sudo docker swarm join-token manager
この Swarm にマネージャーを追加するには、次のコマンドを実行します。

  docker swarm に参加 --token SWMTKN-1-60am9y6axwot0angn1e5inxrpzrj5d6aa91gx72f8et94wztm1-7lz0​​dth35wywekjd1qn30jtes 192.168.1.5:2377

これらのコマンドを使用して、サービス開発用の Docker クラスターを確立し、関連する開発仲間の Docker をこのクラスターに追加して、ホスト間ネットワークを構築する最初のステップを完了します。

ホスト間ネットワークの構築

次に、 docker network createコマンドを使用してオーバーレイ ネットワークを作成します。

$ sudo docker network create --driver overlay --attachable mongodbs

Overlay ネットワークを作成するときは、異なるマシン上の Docker コンテナが正常に使用できるように、--attachable オプションを追加する必要があります。

このネットワークを作成した後、クラスターに参加している任意の Docker インスタンスで docker network ls を使用して、その下のネットワーク リストを表示できます。このネットワーク定義がクラスター内のすべてのノードに同期されていることがわかります。

$ sudo docker ネットワーク ls
ネットワーク ID 名前 ドライバー スコープ
## ......
y89bt74ld9l8 mongodbs オーバーレイ スウォーム
## ......

次に、新しいネットワークを作成するのではなく、すでに定義したネットワークを使用するように Docker Compose 定義を変更する必要があります。

Docker Compose 構成ファイルのネットワーク定義セクションでネットワークの external プロパティを true に設定するだけで、Docker Compose は、作成するすべてのコンテナーを Docker Compose に属さないこのプロジェクトに接続します。

ネットワーク:
 メッシュ:
  外部: 真

この実装により、開発中にエイリアス マッピングを使用できるネットワークにサービス全体を配置し、さまざまな機能をデバッグするときにサービス IP を切り替える面倒なプロセスを回避できます。この構造では、開発した Docker を終了して別のクラスターに参加させるだけで、さまざまな共同デバッグ プロジェクト間を即座に切り替えることができます。

2. docker-composeファイルを書く

マスターノード

バージョン: "3"
サービス: 
 マスター:
  画像: mongo:4.1
  コンテナ名: マスター
  環境:
   MONGO_INITDB_ROOT_USERNAME: ルート
   MONGO_INITDB_ROOT_パスワード: 123456
   TZ: 「アジア/上海」
  ボリューム:
   # MongoDB データ ディレクトリをマウントします - "/data/docker/mongodb/data/mongo:/data/db:rw"
   # キーファイルをマウント
   - 「/data/docker/mongodb/data/mongodb.key:/data/mongodb.key」
  ポート:
   - 「27018:27017」
  ネットワーク:
   - モンゴッド
  指示:
   # パスワード --auth
   #レプリカセット名 --replSet testSet 
   --oplogサイズ 128
   --keyFile /data/mongodb.key
# Swarm クロスホストネットワーク ネットワーク:
 モンゴッドブズ:
  外部: 真

セカンダリノード

バージョン: "3"
サービス: 
二次:
 画像: mongo:4.1
 コンテナ名: セカンダリ
 環境:
  MONGO_INITDB_ROOT_USERNAME: ルート
  MONGO_INITDB_ROOT_パスワード: 123456
  TZ: 「アジア/上海」
 ボリューム:
  - 「/data/docker/mongodb/data/mongo:/data/db:rw」
  - 「/data/docker/mongodb/data/mongodb.key:/data/mongodb.key」
 ポート:
  - 「27018:27017」
 ネットワーク:
  - モンゴッド
 指示:
  --認証
  --replSet テストセット 
  --oplogサイズ 128
  --keyFile /data/mongodb.key
ネットワーク:
モンゴッドブズ:
 外部: 真

調停ノードはデータを保存する必要はありません。マスターノードに障害が発生したときに新しいマスターノードを選択するためにのみ使用されます。したがって、パスワードやポートマッピング操作は必要ありません。

バージョン: "3"
サービス:
アービタ:
 画像: mongo:4.1
 コンテナ名: アービター
 再起動: 常に
 ボリューム:
  - 「/data/docker/mongodb/data/mongo:/data/db:rw」
  - 「/data/docker/mongodb/data/mongo_key:/mongo:rw」
 ネットワーク:
  - モンゴッド
 指示:
  mongod --replSet テストセット --smallfiles --oplogSize 128
ネットワーク:
モンゴッドブズ:
 外部: 真

3. コンテナを起動する

次に、コンテナ オーケストレーションを使用して、3 つのサーバーでそれぞれコンテナを起動します。

docker-compose を起動 -d

4.レプリカセットを構成する

マスターノードコンテナに入る

docker exec -it マスター mongo

mongo シェルで実行します:

> rs.initiate()
{
   "info2" : "設定が指定されていません。セットのデフォルト設定を使用します",
   「私」:「7abd89794aa7:27017」、
   「OK」: 1
}

実行を続行:

テストセット:SECONDARY> rs.add('secondary:27017')
{
   「OK」: 1,
   "$clusterTime" : {
       "clusterTime" : タイムスタンプ(1599562800, 1)、
       "サイン" : {
           「ハッシュ」: BinData(0,"wrxMUIX/0bEyLgCVoQqdLvH59T0="),
           "キーID" : NumberLong("6870069879538450434")
       }
   },
   "操作時間" : タイムスタンプ(1599562800, 1)
}

実行を続行します。true は、このノードが調停ノードであることを意味します。

テストセット:PRIMARY> rs.add('arbiter:27017',true)
{
   「OK」: 1,
   "$clusterTime" : {
       "clusterTime" : タイムスタンプ(1599562838, 1)、
       "サイン" : {
           「ハッシュ」: BinData(0,"p9ub49lLD8ij8nkxpfu2l/AvRRY="),
           "キーID" : NumberLong("6870069879538450434")
       }
   },
   "operationTime" : タイムスタンプ(1599562838, 1)
}

構成を表示

テストセット:PRIMARY> rs.conf()
{
   "_id" : "テストセット",
   「バージョン」: 3,
   "プロトコルバージョン" : NumberLong(1),
   "writeConcernMajorityJournalDefault" : true、
   「メンバー」: [
       {
           "_id" : 0,
           "ホスト" : "7abd89794aa7:27017",
           "arbiterOnly" : false、
           "buildIndexes" : true、
           「非表示」: false、
           「優先度」: 1,
           「タグ」: {

           },
           "スレーブ遅延" : NumberLong(0),
           「投票」: 1
       },
       {
           "_id" : 1,
           "ホスト" : "セカンダリ:27017",
           "arbiterOnly" : false、
           "buildIndexes" : true、
           「非表示」: false、
           「優先度」: 1,
           「タグ」: {

           },
           "スレーブ遅延" : NumberLong(0),
           「投票」: 1
       },
       {
           "_id" : 2,
           "ホスト" : "アービター:27017",
           "arbiterOnly" : true、
           "buildIndexes" : true、
           「非表示」: false、
           「優先度」: 0,
           「タグ」: {

           },
           "スレーブ遅延" : NumberLong(0),
           「投票」: 1
       }
   ]、
   "設定" : {
       「連鎖許可」: true、
       「ハートビート間隔ミリ秒」: 2000,
       "ハートビートタイムアウト秒数" : 10,
       「選挙タイムアウトミリ秒」: 10000,
       "キャッチアップタイムアウトミリ秒" : -1,
       「キャッチアップテイクオーバー遅延ミリ秒」: 30000,
       "getLastErrorModes" : {

       },
       "getLastErrorDefaults" : {
           "w" : 1,
           "タイムアウト" : 0
       },
       "レプリカセットID" : オブジェクトID("5f576426fe90ef2dd8cd2700")
   }
}

ステータスを表示

テストセット:PRIMARY> rs.status()
{
   「設定」:「テストセット」、
   「日付」: ISODate("2020-09-08T11:45:12.096Z"),
   "私の状態" : 1,
   "用語" : NumberLong(1),
   "同期先" : "",
   "syncSourceHost" : "",
   "同期ソースID" : -1,
   "ハートビート間隔ミリ秒" : NumberLong(2000)、
   「最適時間」: {
       "最終コミット操作時間" : {
           "ts" : タイムスタンプ(1599565502, 1)、
           "t" : 数値(1)
       },
       "lastCommittedWallTime" : ISODate("2020-09-08T11:45:02.775Z"),
       「readConcernMajorityOpTime」: {
           "ts" : タイムスタンプ(1599565502, 1)、
           "t" : 数値(1)
       },
       "readConcernMajorityWallTime" : ISODate("2020-09-08T11:45:02.775Z")、
       「適用された操作時間」: {
           "ts" : タイムスタンプ(1599565502, 1)、
           "t" : 数値(1)
       },
       "持続オペレーション時間" : {
           "ts" : タイムスタンプ(1599565502, 1)、
           "t" : 数値(1)
       },
       "最後に適用された壁の時刻" : ISODate("2020-09-08T11:45:02.775Z"),
       "lastDurableWallTime" : ISODate("2020-09-08T11:45:02.775Z")
   },
   "lastStableRecoveryTimestamp" : タイムスタンプ(1599565492, 1)、
   "lastStableCheckpointTimestamp" : タイムスタンプ(1599565492, 1)、
   「メンバー」: [
       {
           "_id" : 0,
           "名前" : "7abd89794aa7:27017",
           "ip" : "10.0.1.41",
           「健康」: 1,
           「状態」: 1,
           "stateStr" : "プライマリ",
           「稼働時間」: 2784,
           「最適時間」:{
               "ts" : タイムスタンプ(1599565502, 1)、
               "t" : 数値(1)
           },
           "optimeDate" : ISODate("2020-09-08T11:45:02Z")、
           "同期先" : "",
           "syncSourceHost" : "",
           "同期ソースID" : -1,
           "情報メッセージ" : "",
           「選挙時刻」: タイムスタンプ(1599562790, 2)、
           「選挙日」: ISODate("2020-09-08T10:59:50Z"),
           "configVersion" : 3,
           「自己」: 真、
           「最後のハートビートメッセージ」:「」
       },
       {
           "_id" : 1,
           "名前" : "セカンダリ:27017",
           「ip」:「10.0.1.233」、
           「健康」: 1,
           「状態」: 2,
           "stateStr" : "セカンダリ",
           「稼働時間」: 2711,
           「最適時間」:{
               "ts" : タイムスタンプ(1599565502, 1)、
               "t" : 数値(1)
           },
           「optimeDurable」: {
               "ts" : タイムスタンプ(1599565502, 1)、
               "t" : 数値(1)
           },
           "optimeDate" : ISODate("2020-09-08T11:45:02Z")、
           "optimeDurableDate" : ISODate("2020-09-08T11:45:02Z")、
           "最後のハートビート" : ISODate("2020-09-08T11:45:11.494Z"),
           "lastHeartbeatRecv" : ISODate("2020-09-08T11:45:11.475Z"),
           "pingMs" : NumberLong(0),
           "最後のハートビートメッセージ" : "",
           "同期先" : "7abd89794aa7:27017",
           "同期ソースホスト": "7abd89794aa7:27017",
           "同期ソースID" : 0,
           "情報メッセージ" : "",
           "configバージョン" : 3
       },
       {
           "_id" : 2,
           「名前」:「アービター:27017」、
           "ip" : null、
           「健康」: 0,
           「状態」: 8,
           "stateStr" : "(到達不能/正常)",
           「稼働時間」: 0,
           "最後のハートビート" : ISODate("2020-09-08T11:45:10.463Z"),
           "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
           "pingMs" : NumberLong(0),
           "lastHeartbeatMessage" : "アービターへの接続エラー:27017 :: 原因:: アービターのアドレスが見つかりませんでした SocketException: ホストが見つかりません (権限あり)",
           "同期先" : "",
           "syncSourceHost" : "",
           "同期ソースID" : -1,
           "情報メッセージ" : "",
           "configバージョン" : -1
       }
   ]、
   「OK」: 1,
   "$clusterTime" : {
       "clusterTime" : タイムスタンプ(1599565502, 1)、
       "サイン" : {
           「ハッシュ」: BinData(0,"7/ei+8UrhlpIny9zKeWuAFpn46c="),
           "キーID" : NumberLong("6870069879538450434")
       }
   },
   "operationTime" : タイムスタンプ(1599565502, 1)
}

5. MongoDBの可用性を確認する

まずマスターノードサーバーに入り、データを追加します

docker exec -it マスター mongo
管理者を使用する
db.auth('ルート', '123456')
使用テスト
db.test.insert({名前:"ムヤン",年齢:20})

セカンダリノードサーバーでデータが同期されているかどうかを確認します。

[root@linux セカンダリ] docker exec -it セカンダリ mongo
testSet:SECONDARY> 管理者を使用する
テストセット:SECONDARY> db.auth('root', '123456')
testSet:SECONDARY> テストを使用する
テストセット:セカンダリ> db.test.find()
2020-09-08T19:03:02.295+0800 E クエリ [js] キャッチされない例外: エラー: listCollections が失敗しました: {
   "操作時間" : タイムスタンプ(1599562972, 1)、
   「OK」: 0,
   "errmsg" : "マスターではなく、slaveOk=false",
   「コード」: 13435、
   "コード名" : "マスターなしスレーブ不可",
   "$clusterTime" : {
       "clusterTime" : タイムスタンプ(1599562972, 1)、
       "サイン" : {
           「ハッシュ」: BinData(0,"mhsrpGHRl7qZg2QOjyS3RbBb/Yc="),
           "キーID" : NumberLong("6870069879538450434")
       }
   }
} :
テストセット:セカンダリ> rs.slaveOk()
テストセット:SECONDARY> db.users.find()
{ "_id" : ObjectId("5f5764b1f909544b783696c2"), "名前" : "ムヤン", "年齢" : 20 }

セカンダリ クエリ中に次のエラーが報告されます。

マスターとスレーブではないok=false

これは、セカンダリが読み取りまたは書き込みを許可されていないため、正常です。これを解決する必要がある場合は、方法は次のとおりです。

テストセット:セカンダリ> rs.slaveOk()

これで、Docker で MongoDB クラスターを構築するための実装手順に関するこの記事は終了です。Docker で MongoDB クラスターを構築するための関連コンテンツの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Dockerを使用して最新バージョンのMongoDBをインストールする方法
  • Docker コンテナのデプロイの試み - マルチコンテナ通信 (node+mongoDB+nginx)
  • docker で mongodb データベースを使用する方法の詳細説明 (LAN でのアクセス)
  • Docker ベースで MongoDB への許可アクセスを実装する方法
  • DockerでMongoDBコンテナをデプロイする方法

<<:  Vueは、商品の数を制御するためのコンポーネントのパッケージ化と使用を実装します。

>>:  MySQL インデックスの長所と短所、およびインデックス作成のガイドライン

推薦する

Centos7.4 システムに yum ソースから mysql 5.6 をインストールする

システム環境: centos7.4 1. データベースがインストールされているかどうかを確認します。...

子コンポーネントで vue activated を使用する詳細

ページ: ベース: <テンプレート> <div class="タブコンテ...

Node.jsはexpress-fileuploadミドルウェアを使用してファイルをアップロードします

目次プロジェクトを初期化するサーバーの作成クライアントを初期化するコンポーネントの記述ファイルアップ...

Linux でのファイル コンテンツの重複排除と交差と差異の実装

1. データ重複排除日常業務では、Hive や Impala を使用してクエリとエクスポートを行う際...

Virtualbox に Centos7 仮想マシンをインストールする詳細なグラフィック チュートリアル

1. Centos7をダウンロードするダウンロードアドレス: https://mirrors.tun...

HTML の順序なしリストタグと順序付きリストタグの使用例

1. 上部と下部のリストタグ: <dl>..</dl>:上dt下層dd: カ...

Vue 構成リクエストの複数サーバーソリューションの詳細な説明

1. 解決策1.1 インターフェースコンテキストパスの説明2 つのバックエンド インターフェイス サ...

Dockerデーモンのセキュリティ設定項目の詳細な説明

目次1. テスト環境1.1 CentOS 7をインストールする1.2 Docker CE 19.03...

MySQLのジョイントクエリについて詳しく説明します

目次ユニオンクエリ1. 中国の各省のIDと名前を照会する2. 湖南省のすべての地級市のIDと名称3....

ポップアップ効果を実現するにはjsを使用します

この記事の例では、ポップアップ効果を実現するためのjsの具体的なコードを参考までに共有しています。具...

CentOS8 システムをベースにした Gitlab を構築するために Docker を使用する詳細なチュートリアル

目次1. Dockerをインストールする2. GitLabをインストールする3. GitLabを初期...

Linuxオペレーティングシステムは、タスクマネージャーの視覚化機能を実装するためにPythonを使用しています。

1. Pythonのインストール1. フォルダーを作成します。 mkdir python フォルダ...

Dockerの匿名マウントと名前付きマウントの具体的な使用法

目次データ量匿名マウントと名前付きマウントデータボリュームの場所データ量匿名マウントと名前付きマウン...

CSSの複数条件の書き方の詳細説明:

:not疑似クラスセレクターは、式に一致しない要素をフィルタリングできます。例 テーブル tbod...

Linux コマンドラインのクイックヒント: ファイルの検索方法

私たちのコンピューターには、ディレクトリ、写真、ソース コードなどのファイルが保存されています。たく...