はじめに
MongoDB3.4 を CentOS7 にインストールしようとしたところ、特に WARNING を消す部分でいろいろと四苦八苦したのでメモ
CentOS のバージョンは以下の通り。さくらのVPSです。
# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
1. MongoDB のインストールと起動
公式の記事に従って yum を使って MongoDB のインストールを行います。
Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux — MongoDB Manual 3.4
1.1. MongoDB を yum でインストール
まずは、 /etc/yum.repos.d のディレクトリの下にファイルを追加して、yum のレポジトリを追加します。
# vi /etc/yum.repos.d/mongodb-org-3.4.repo
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
yum でインストール
# yum install -y mongodb-org
この後、公式のリファレンスでは SELinux の設定について書かれていますが、おそらくサーバの初期設定をしたときに SELinux を無効化している方が多いと思いますので、ここは飛ばします(自分もやっていない)。
1.2. MongoDB の起動と自動起動の設定
MongoDB の起動
# systemctl start mongod
MongoDB の自動起動
# systemctl enable mongod
MongoDB のバージョンの確認
# mongo --version
MongoDB shell version v3.4.1
MongoDB のシェルの起動
# mongo
MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
Server has startup warnings:
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten]
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten]
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten]
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten]
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten]
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2017-01-11T18:01:33.949+0900 I CONTROL [initandlisten]
>
起動できました。無事に MongoDB のインストールができたようです。
2. WARNING: We suggest setting it to 'never' を消す
シェルを起動したときに WARING が出てしまっています。今度はこれを解消します。これも公式が解消方法を出していますが、公式のやり方だと一部うまくいかない部分がありました。そのため、別の記事も参考にしています。
Disable Transparent Huge Pages (THP) — MongoDB Manual 3.4
MongoDB 3.0 をインストール - Carpe Diem
Transparent Huge Pages (THP) is a Linux memory management system that reduces the overhead of Translation Lookaside Buffer (TLB) lookups on machines with large amounts of memory by using larger memory pages.
However, database workloads often perform poorly with THP, because they tend to have sparse rather than contiguous memory access patterns. You should disable THP on Linux machines to ensure best performance with MongoDB.
CentOS(redhat系)の Linux では、THP(Transparent Huge Pages) というページ管理システムを採用しているのですが、どうやらこれが MongoDB と相性が悪いようです。
2.1. 初期化するスクリプトの作成
/etc/init.d ディレクトリにスクリプトを作成します。
公式のものをコピペしてやってみましたが、WARNING の一部が消えなかったので他の記事を参考に以下のようにしました。
# vi /etc/init.d/disable-transparent-hugepages
#!/bin/bash
### BEGIN INIT INFO
# Provides: disable-transparent-hugepages
# Required-Start: $local_fs
# Required-Stop:
# X-Start-Before: mongod mongodb-mms-automation-agent
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Disable Linux transparent huge pages
# Description: Disable Linux transparent huge pages, to improve
# database performance.
### END INIT INFO
case $1 in
start)
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
re='^[0-1]+$'
if [[ $(cat ${thp_path}/khugepaged/defrag) =~ $re ]]
then
# RHEL 7
echo 0 > ${thp_path}/khugepaged/defrag
else
# RHEL 6
echo 'no' > ${thp_path}/khugepaged/defrag
fi
unset re
unset thp_path
;;
esac
パーミッションの変更
# chmod 755 /etc/init.d/disable-transparent-hugepages
サービス設定の追加
(chkconfig についてはこちらの記事がわかりやすかったです)
# chkconfig --add disable-transparent-hugepages
# chkconfig --list
disable-transparent-hugepages 0:off 1:off 2:on 3:on 4:on 5:on 6:off
# /sbin/service disable-transparent-hugepages start
をしたかどうかは忘れました...すいません
2.2. tuned と ktune の設定
If using tuned or ktune, you must perform this step in addition to installing the init script.
tuned または ktune を使用している場合には、2.1 に加えて以下の設定もする必要があります。
(tuned または ktune に関してはこちら)
tuned and ktune are dynamic kernel tuning tools available on Red Hat and CentOS that can disable transparent huge pages.
To disable transparent huge pages in tuned or ktune, you need to edit or create a new profile that sets THP to never.
新しいプロファイルの作成が必要なようです。
# mkdir /etc/tuned/no-thp
# vi /etc/tuned/no-thp/tuned.conf
[main]
include=virtual-guest
[vm]
transparent_hugepages=never
tuned-adm コマンドを使って、プロファイルの切り替えを行います。
# tuned-adm profile no-thp
変更されたかテストしています。never に [] がついていればうまくいっています。
# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
# cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]
2.3. MongoDB の再起動とシェルの確認
MongoDB を再起動
# systemctl restart mongod
シェルを起動して、WARNING が消えたか確認
# mongo
MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017/
MongoDB server version: 3.4.1
Server has startup warnings:
2017-01-11T18:24:52.860+0900 I CONTROL [initandlisten]
2017-01-11T18:24:52.860+0900 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-01-11T18:24:52.860+0900 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2017-01-11T18:24:52.860+0900 I CONTROL [initandlisten]
>
WARNING: We suggest setting it to 'never' の2つは消えたようです。
もし、WARNING が消えない場合はログからエラーを確認してください
# tail /var/log/mongodb/mongod.log
3. WARNING: Access control is not enabled for the database. を消す
MongoDB 3系から出た WARNING だと思います。どうやら、MongoDB のセキュリティ面の問題らしいです。openssl コマンドを使って内部認証を行えるようにします。こちらも見つけにくかったですが、公式の記事がありました。
Enable Internal Authentication — MongoDB Manual 3.0
keyfile の場所はこちらの記事を参考にしています。
mongodb3.0.x 設定ファイルテンプレ - Qiita
3.1. keyfile の作成
keyfileの作成
# mkdir -p /usr/local/mongodb/conf
# openssl rand -base64 741 > /usr/local/mongodb/conf/mongodb-keyfile
公式には chown がないのですが、私の場合はこれがないと permission denied というエラーが出ました。
# chmod 600 /usr/local/mongodb/conf/mongodb-keyfile
# chown -R mongod.mongod /usr/local/mongodb/conf/mongodb-keyfile
3.2. 設定ファイルに追加し、再起動
設定ファイルに追加します。 security のコメントアウトを外すことを忘れないでください。
# vi /etc/mongod.conf
security:
keyFile: /usr/local/mongodb/conf/mongodb-keyfile
MongoDB を再起動
# systemctl restart mongod
シェルの起動
# mongo
MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
>
WARNING が消えた!(もしかしたら、ユーザ認証を追加しないといけないかも)
4. ユーザ認証の追加
今のままだと誰でも Mongo のデータに触ることができるため、とても危険です。私も1度 Mongo を標的としたマルウェアに感染したため、全てのデータが消えました。ユーザ認証ははじめに追加しましょう。こちらも公式に方法が書いてあります。
Enable Auth — MongoDB Manual 3.4
4.1. 管理ユーザの作成
管理ユーザを作成します。admin データベースにユーザを管理する権限( userAdminAnyDatabase )を持ったユーザを追加します。 password の部分はご自分で用意したものを設定してください。
# mongo
> use admin
switched to db admin
> db.createUser({user:"myUserAdmin",pwd:"password",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
Successfully added user: {
"user" : "myUserAdmin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
MongoDB の設定ファイルを更新します。
# vi /etc/mongod.conf
security:
keyFile: /usr/local/mongodb/conf/mongodb-keyfile
authorization: enabled
MongoDB を再起動します。
# systemctl restart mongod
次からはログインが必要になります。mongo のシェルを起動してから db.auth()
を使ってログインする方法と、mongo のシェルを起動するときにログインする方法の2種類があります。
mongo のシェルを起動してから db.auth()
を使ってログインする方法
db.auth()
のあとに 1
と出れば成功
# mongo
> use admin
switched to db admin
> db.auth("myUserAdmin","password")
1
mongo のシェルを起動するときにログインする方法
シェルがちゃんと起動すれば成功
# mongo -u "myUserAdmin" -p "password" --authenticationDatabase "admin"
4.2 一般ユーザの作成
Mongo はデータベースごとにユーザを作成するようです。テストユーザを作成して、権限の確認をしましょう。
readWrite
はデータベースの読み書きができます。'read' だと読み込みだけです。
# mongo -u "myUserAdmin" -p "password" --authenticationDatabase "admin"
> use test
> db.createUser({user:"myTester",pwd:"xyz123",roles:[{role:"readWrite",db:"test"}]})
Successfully added user: {
"user" : "myTester",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}
一度シェルを閉じてから再度ログインしてみましょう。
# mongo -u "myTester" -p "xyz123" --authenticationDatabase "test"
> db.foo.insert( { x: 1, y: 1 } )
WriteResult({ "nInserted" : 1 })
> show collections
foo
> db.foo.find()
{ "_id" : ObjectId("58762b81a5a33029aaf665ee"), "x" : 1, "y" : 1 }
ちゃんとデータが見れました。次は、一度シェルを閉じてから再度ログインしてみましょう。
# mogno
> use test
switched to db test
> show collections
2017-01-11T21:58:19.707+0900 E QUERY [main] Error: listCollections failed: {
"ok" : 0,
"errmsg" : "not authorized on test to execute command { listCollections: 1.0, filter: {} }",
"code" : 13,
"codeName" : "Unauthorized"
} :
> db.foo.find()
Error: error: {
"ok" : 0,
"errmsg" : "not authorized on test to execute command { find: \"foo\", filter: {} }",
"code" : 13,
"codeName" : "Unauthorized"
}
今度はテストユーザで認証していないため、コレクションを見ることができませんでした。
最後にテストユーザを削除することを忘れずに。
# mongo -u "myUserAdmin" -p "password" --authenticationDatabase "admin"
> db.dropUser("myuser")
参考元
Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux — MongoDB Manual 3.4
Disable Transparent Huge Pages (THP) — MongoDB Manual 3.4
MongoDB 3.0 をインストール - Carpe Diem
Enable Internal Authentication — MongoDB Manual 3.0
mongodb3.0.x 設定ファイルテンプレ - Qiita
Enable Auth — MongoDB Manual 3.4