如何使用Docker部署MongoDB副本集

我寫了一篇有關(guān)如何使用DevOps時(shí)尚風(fēng)格部署mongodb集群的新文章氮块,在本文中绍载,我正在使用Terraform,Ansible滔蝉,Packer和更酷的技術(shù)击儡,我強(qiáng)烈建議您閱讀它。

以DevOps時(shí)尚風(fēng)格(將基礎(chǔ)架構(gòu)作為代碼)部署MongoDB副本集蝠引。


本文將逐步介紹如何使用docker設(shè)置帶有身份驗(yàn)證的MongoDB副本集阳谍。

我們將在本文中使用的是:

  • MongoDB 3.4.1
  • 適用于Mac 1.12.6的Docker

副本集的體系結(jié)構(gòu)

帶有docker的副本集的架構(gòu)

在上圖中,我們看到了使用docker復(fù)制集的結(jié)果螃概。

#先決條件

  • docker基礎(chǔ)知識(shí)
  • 安裝了dockerdocker-machine
  • mongoDB的基礎(chǔ)知識(shí)
  • bash腳本編寫的基礎(chǔ)知識(shí)

如果您使用的是Mac或Windows矫夯,請(qǐng)考慮使用虛擬機(jī)。我將在MacOS Sierra上使用VirtualBox運(yùn)行我們的mongoDB實(shí)例吊洼。

#步驟1 —?jiǎng)?chuàng)建我們的3個(gè)docker-machines

要?jiǎng)?chuàng)建docker機(jī)器训貌,我們需要在終端中發(fā)出下一個(gè)命令:

$ docker-machine create -d virtualbox manager1

此命令將使用virtualbox作為我們的虛擬化提供程序創(chuàng)建一個(gè)名為manager1的計(jì)算機(jī)。

現(xiàn)在讓我們創(chuàng)建兩個(gè)左 docker-machine

$ docker-machine create -d virtualbox worker1
$ docker-machine create -d virtualbox worker2

要驗(yàn)證是否創(chuàng)建了我們的機(jī)器冒窍,讓我們運(yùn)行以下命令:

$ docker-machine ls
// the result will be
NAME    ACTIVE   DRIVER     STATE     URL    
manager1   -   virtualbox   Running  tcp://192.168.99.100:2376           
worker1    -   virtualbox   Running  tcp://192.168.99.101:2376
worker2    -   virtualbox   Running  tcp://192.168.99.102:2376

#步驟2 — MongoDB主節(jié)點(diǎn)的配置

現(xiàn)在我們有了三臺(tái)機(jī)器递沪,讓我們將其放置在第一臺(tái)機(jī)器上以啟動(dòng)mongodb配置,讓我們運(yùn)行下一個(gè)命令:

$ eval `docker-machine env manager1`

創(chuàng)建我們的MongoDB容器之前超燃,還有一個(gè)已經(jīng)存在了很長(zhǎng)討論了非常重要的課題數(shù)據(jù)庫(kù)持久ocker containers区拳,并為實(shí)現(xiàn)這一挑戰(zhàn)拘领,我們所要做的是創(chuàng)建一個(gè)docker volume意乓。

$ docker volume create --name mongo_storage

現(xiàn)在,讓我們附加創(chuàng)建的卷以啟動(dòng)我們的第一個(gè)mongo容器并設(shè)置配置。

$ docker run --name mongoNode1 \
-v mongo_storage:/data \
-d mongo \
--smallfiles

接下來(lái)届良,我們需要?jiǎng)?chuàng)建密鑰文件笆凌。

密鑰文件的內(nèi)容用作副本集成員的共享密碼。對(duì)于副本集的所有成員士葫,密鑰文件的內(nèi)容必須相同乞而。

$ openssl rand -base64 741 > mongo-keyfile
$ chmod 600 mongo-keyfile

接下來(lái),我們創(chuàng)建一個(gè)文件夾慢显,用于存放mongo_storage卷中的數(shù)據(jù)爪模,密鑰文件和配置:

$ docker exec mongoNode1 bash -c 'mkdir /data/keyfile /data/admin'

下一步是創(chuàng)建一些管理員用戶,讓我們創(chuàng)建一個(gè)看起來(lái)像這樣的admin.jscopy.js文件:

// admin.js
admin = db.getSiblingDB("admin")
// creation of the admin user
admin.createUser(
  {
    user: "cristian",
    pwd: "cristianPassword2017",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)
// let's authenticate to create the other user
db.getSiblingDB("admin").auth("cristian", "cristianPassword2017" )
// creation of the replica set admin user
db.getSiblingDB("admin").createUser(
  {
    "user" : "replicaAdmin",
    "pwd" : "replicaAdminPassword2017",
    roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
  }
)

//replica.js
rs.initiate({
 _id: 'rs1',
 members: [{
  _id: 0, host: 'manager1:27017'
 }]
})

IMPORTANT

密碼應(yīng)隨機(jī)荚藻,長(zhǎng)且復(fù)雜屋灌,以確保系統(tǒng)安全并防止或延遲惡意訪問(wèn)。有關(guān)內(nèi)置角色的完整列表应狱,請(qǐng)參見數(shù)據(jù)庫(kù)用戶角色共郭,這些角色與數(shù)據(jù)庫(kù)管理操作有關(guān)。

我們所做的直到知道:

  • 創(chuàng)建了mongo_storagedocker volume疾呻。
  • 創(chuàng)建了mongo-keyfile除嘹,openssl密鑰生成。
  • mongoDB創(chuàng)建了admin.js文件 admin用戶岸蜗。
  • 創(chuàng)建了copy.js文件尉咕,以初始化副本集。

好的璃岳,讓我們繼續(xù)將文件傳遞到容器龙考。

$ docker cp admin.js mongoNode1:/data/admin/
$ docker cp replica.js mongoNode1:/data/admin/
$ docker cp mongo-keyfile mongoNode1:/data/keyfile/

// change folder owner to the user container
$ docker exec mongoNode1 bash -c 'chown -R mongodb:mongodb /data'

我們所做的是,我們需要傳遞到容器中的文件矾睦,然后修改 / data文件夾所有者 到容器的用戶晦款,因?yàn)槿萜饔脩羰切枰L問(wèn)這個(gè)文件夾和文件的用戶。

現(xiàn)在枚冗,所有內(nèi)容都已設(shè)置好缓溅,我們準(zhǔn)備使用副本集配置重新啟動(dòng)mongod實(shí)例。

在啟動(dòng)經(jīng)過(guò)身份驗(yàn)證的mongo容器之前赁温,讓我們創(chuàng)建一個(gè)env文件來(lái)設(shè)置我們的用戶和密碼坛怪。

MONGO_USER_ADMIN=cristian
MONGO_PASS_ADMIN=cristianPassword2017
MONGO_REPLICA_ADMIN=replicaAdmin
MONGO_PASS_REPLICA=replicaAdminPassword2017

現(xiàn)在我們需要?jiǎng)h除容器并開始一個(gè)新的容器。為什么股囊?袜匿,因?yàn)槲覀冃枰峁└北炯蜕矸蒡?yàn)證參數(shù),并且為此稚疹,我們需要運(yùn)行以下命令:

// first let's remove our container
$ docker rm -f mongoNode1
// now lets start our container with authentication 
$ docker run --name mongoNode1 --hostname mongoNode1 \
-v mongo_storage:/data \
--env-file env \
--add-host manager1:192.168.99.100 \
--add-host worker1:192.168.99.101 \
--add-host worker2:192.168.99.102 \
-p 27017:27017 \
-d mongo --smallfiles \
--keyFile /data/keyfile/mongo-keyfile \
--replSet 'rs1' \
--storageEngine wiredTiger \
--port 27017

這里發(fā)生了什么………似乎是在濫用旗幟居灯。

讓我分兩部分向您解釋:

Docker標(biāo)志:

  1. --env-file讀取ENV文件,并設(shè)置environment在容器內(nèi)的變量。
  2. --add-host標(biāo)志將條目添加到Docker容器的/etc/hosts文件中怪嫌,因此我們可以使用主機(jī)名代替IP地址义锥。在這里,我們映射了我們之前創(chuàng)建的3個(gè)docker-machines岩灭。

要更深入地了解docker run命令拌倍,請(qǐng)閱讀Docker文檔

Docker Flags

為了設(shè)置mongo副本集噪径,我們需要各種mongo標(biāo)志

  1. --keyFile 這個(gè)標(biāo)志是用來(lái)告訴mongo在哪里 mongo-keyfile.
  2. --replSet 該標(biāo)志用于設(shè)置副本集的名稱柱恤。
  3. --storageEngine由于mongoDB 3.4.1的默認(rèn)引擎為wiredTiger,因此不需要此標(biāo)志用于設(shè)置mongoDB的引擎找爱。

為了對(duì)mongo副本集有更深入的了解膨更,請(qǐng)閱讀MongoDB文檔,我也建議使用MongoUniversity課程以了解有關(guān)此主題的更多信息缴允。

mongoNode1容器的最后一步是啟動(dòng)副本集荚守,我們將通過(guò)運(yùn)行以下命令來(lái)做到這一點(diǎn):

$ docker exec mongoNode1 bash -c 'mongo < /data/admin/replica.js'

您應(yīng)該會(huì)看到以下內(nèi)容:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{ "ok" : 1 }
bye

現(xiàn)在,讓我們使用以下命令創(chuàng)建管理員用戶:

$ docker exec mongoNode1 bash -c 'mongo < /data/admin/admin.js'

您應(yīng)該會(huì)看到以下內(nèi)容:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
admin
Successfully added user: {
 "user" : "cristian",
 ...
Successfully added user: {
 "user" : "replicaAdmin",
...
bye

現(xiàn)在练般,要進(jìn)入副本矗漾,請(qǐng)運(yùn)行以下命令:

$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_REPLICA_ADMIN -p $MONGO_PASS_REPLICA --eval "rs.status()" --authenticationDatabase "admin"'

您應(yīng)該已經(jīng)準(zhǔn)備好,看到類似以下內(nèi)容:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{
 "set" : "rs1",
 ...
 "members" : [
  {
   "_id" : 0,
   "name" : "manager1:27017",
   ...
 "ok" : 1
}

#步驟3 —再添加2個(gè)mongo節(jié)點(diǎn)容器

現(xiàn)在一切就緒薄料,讓我們?cè)賳?dòng)2個(gè)節(jié)點(diǎn)并將它們加入副本集敞贡。

要添加第一個(gè)節(jié)點(diǎn),我們將其更改為worker1 docker計(jì)算機(jī)摄职,如果您使用的是本地計(jì)算機(jī)誊役,請(qǐng)運(yùn)行以下命令:

eval `docker-machine env worker1`

如果您不在本地運(yùn)行,只需將終端指向下一個(gè)服務(wù)器即可谷市。

現(xiàn)在蛔垢,由于我們將重復(fù)幾乎為mongoNode1所做的所有步驟,因此讓我們創(chuàng)建一個(gè)腳本來(lái)為我們運(yùn)行所有命令迫悠。

讓我們創(chuàng)建一個(gè)名為create-replica-set.sh的文件鹏漆,然后看看如何組成main函數(shù):

function main {
  init_mongo_primary
  init_mongo_secondaries
  add_replicas manager1 mongoNode1
  check_status manager1 mongoNode1
}
main

現(xiàn)在,讓我向您展示此功能的組成:

INIT MONGO主要功能

function init_mongo_primary {
# [@params](http://twitter.com/params) name-of-keyfile
createKeyFile mongo-keyfile

# [@params](http://twitter.com/params) server container volume
createMongoDBNode manager1 mongoNode1 mongo_storage

# [@params](http://twitter.com/params) container
init_replica_set mongoNode1
}

該函數(shù)內(nèi)部也有對(duì)函數(shù)的調(diào)用创泄,沒有添加任何新內(nèi)容艺玲,我們之前已經(jīng)看過(guò)所有功能,讓我為您描述它的作用:

  1. 副本集身份驗(yàn)證創(chuàng)建密鑰文件鞠抑。
  2. 創(chuàng)建一個(gè)mongodb容器饭聚,并接收2個(gè)參數(shù):a)待定位的服務(wù)器,b)容器的名稱搁拙,c)docker卷的名稱秒梳,所有我們之前看到的功能法绵。
  3. 最后,它將使用與我們之前完全相同的步驟來(lái)啟動(dòng)副本端幼。

INIT MONGO SECONDARY FUNCTION

function init_mongo_secondaries {
# [@Params](http://twitter.com/Params) server container volume
createMongoDBNode worker1 mongoNode1 mongo_storage
createMongoDBNode worker2 mongoNode2 mongo_storage
}

此功能的作用是為副本集創(chuàng)建其他2個(gè)mongo容器礼烈,并執(zhí)行與mongoNode1相同的步驟弧满,但是這里我們不包括副本集實(shí)例化和admin用戶創(chuàng)建婆跑,因?yàn)檫@些不是必需的,因?yàn)楦北炯瘜⑴c副本的所有節(jié)點(diǎn)共享數(shù)據(jù)庫(kù)配置庭呜,以后再將它們添加到主數(shù)據(jù)庫(kù)中滑进。

添加復(fù)制功能

<pre class="gl gm gn go gp lk ll dl" style="box-sizing: inherit; margin: 56px 0px 0px; overflow-x: auto; padding: 20px; background: rgba(0, 0, 0, 0.05); color: rgba(0, 0, 0, 0.8); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># [@params](http://twitter.com/params) server container
function add_replicas {
  echo '·· adding replicas >>>> '$1' ··' switchToServer $1

  for server in worker1 worker2
   do
    rs="rs.add('$server:27017')"
    add='mongo --eval "'$rs'" -u $MONGO_REPLICA_ADMIN 
         -p $MONGO_PASS_REPLICA --authenticationDatabase="admin"'
    sleep 2
    wait_for_databases $server
    docker exec -i $2 bash -c "$add"
  done
}</pre>

在這里,我們要做的是最后將另外兩個(gè)mongo容器添加到副本集配置上的主數(shù)據(jù)庫(kù)中募谎,首先我們遍歷剩下的機(jī)器以添加容器扶关,在循環(huán)中我們準(zhǔn)備配置,然后檢查容器是否準(zhǔn)備好了数冬,我們通過(guò)調(diào)用函數(shù)來(lái)做到這一點(diǎn)wait_for_databases节槐,然后將機(jī)器作為參數(shù)傳遞給我們,然后在主數(shù)據(jù)庫(kù)中執(zhí)行配置拐纱,然后我們應(yīng)該收集如下消息:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{ "ok" : 1 }

這意味著mongo容器已成功添加到副本铜异。

最后,我們使用main中的最后一個(gè)功能檢查副本集的狀態(tài):

# [@params](http://twitter.com/params) server container
function check_status {
switchToServer $1
cmd='mongo -u $MONGO_REPLICA_ADMIN -p $MONGO_PASS_REPLICA
--eval "rs.status()" --authenticationDatabase "admin"'
docker exec -i $2 bash -c "$cmd"
}

既然我們已經(jīng)了解了自動(dòng)化腳本的功能并且知道將要執(zhí)行的操作秸架,那么現(xiàn)在該執(zhí)行自動(dòng)化bash腳本了揍庄,如下所示:

請(qǐng)注意,如果已完成上述所有步驟东抹,則需要重置我們已實(shí)現(xiàn)的所有內(nèi)容蚂子,以避免任何沖突名稱問(wèn)題,要重置配置缭黔,請(qǐng)?jiān)趃ithub存儲(chǔ)庫(kù)中找到一個(gè)reset.sh文件

# and this how we can execute the script that will configure 
# everything for us.
$ bash < create-replica-set.sh

如果一切設(shè)置正確食茎,我們應(yīng)該看到來(lái)自mongodb的消息,如下所示:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{
 "set" : "rs1",
 ...
 },
 "members" : [
  {
   "_id" : 0,
   "name" : "manager1:27017",
   "health" : 1,
   "state" : 1,
   "stateStr" : "PRIMARY",
   ...
  },
  {
   "_id" : 1,
   "name" : "worker1:27017",
   "health" : 1,
   "state" : 2,
   "stateStr" : "SECONDARY",
   ...
  },
  {
   "_id" : 2,
   "name" : "worker2:27017",
   "health" : 1,
   "state" : 0,
   "stateStr" : "STARTUP",
   ...
  }
 ],
 "ok" : 1
}

正如您所看到的馏谨,每個(gè)容器現(xiàn)在都已正確配置董瞻,需要注意的是,我們--add-host像以前一樣使用了來(lái)自docker 的標(biāo)志田巴,并將這些條目添加到Docker容器的/ etc / hosts文件中钠糊,因此我們可以使用主機(jī)名代替IP地址。

兩個(gè)節(jié)點(diǎn)都可能需要一分鐘才能完成從mongoNode1的同步壹哺。

您可以通過(guò)查看日志來(lái)查看每個(gè)mongo Docker容器中發(fā)生的情況抄伍。您可以通過(guò)在任何docker-machine服務(wù)器上運(yùn)行此命令來(lái)執(zhí)行此操作。

$ docker logs -ft mongoContainerName

現(xiàn)在我們已經(jīng)啟動(dòng)并運(yùn)行了一個(gè)MongoDB副本設(shè)置服務(wù)管宵,讓我們修改用戶截珍,或者您可以創(chuàng)建另一個(gè)用戶并授予一些權(quán)限來(lái)對(duì)數(shù)據(jù)庫(kù)執(zhí)行Crud操作攀甚,因此,僅出于說(shuō)明目的岗喉,這是一個(gè)不好的做法秋度,讓我添加一個(gè)的管理員用戶的超級(jí)角色。

# we are going to assign the root role to our admin user
# we enter to the container
$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'
# Then we execute the following in the mongo shell
# Mongo 3.4.1 shell
> use admin
> db.grantRolesToUser( "cristian", [ "root" , { role: "root", db: "admin" } ] )
>

現(xiàn)在钱床,他擁有一個(gè)可以做任何事情的超級(jí)用戶荚斯,因此讓我們創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)并插入一些數(shù)據(jù)。

$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'
# Mongo 3.4.1 shell
> use movies
> db.movies.insertMany([{
  id: '1',
  title: 'Assasins Creed',
  runtime: 115,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 6
}, {
  id: '2',
  title: 'Aliados',
  runtime: 124,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 13
}, {
  id: '3',
  title: 'xXx: Reactivado',
  runtime: 107,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 20
}, {
  id: '4',
  title: 'Resident Evil: Capitulo Final',
  runtime: 107,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 27
}, {
  id: '5',
  title: 'Moana: Un Mar de Aventuras',
  runtime: 114,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2016,
  releaseMonth: 12,
  releaseDay: 2
}])
# inserted 5 documents
> 

現(xiàn)在查牌,我們有了一個(gè)電影數(shù)據(jù)庫(kù)事期,其中包含包含5部電影:D的電影集合。

V窖眨回顧的時(shí)間

我們所做的…

我們使用自動(dòng)腳本使用Docker配置并啟動(dòng)帶有身份驗(yàn)證MongoDB副本集兽泣。

在安全方面,我們創(chuàng)建:

  • 兩種用戶類型胁孙,即管理數(shù)據(jù)庫(kù)集群管理數(shù)據(jù)庫(kù)唠倦。
  • 我們創(chuàng)建一個(gè)密鑰文件,并在啟用身份驗(yàn)證的情況下啟動(dòng)副本涮较。

如果為數(shù)據(jù)庫(kù)正確配置了訪問(wèn)控制稠鼻,則攻擊者應(yīng)該無(wú)法訪問(wèn)您的數(shù)據(jù)。查看我們的安全檢查表法希,以幫助發(fā)現(xiàn)潛在的漏洞枷餐。— @MongoDB文件

如果我們想為我們的架構(gòu)增加更多的安全性苫亦,我們可以使用docker-machines 創(chuàng)建一個(gè)Swarm集群毛肋,并且docker swarm可以很好地處理網(wǎng)絡(luò)通信,還可以在容器中創(chuàng)建非root用戶屋剑,并且可以啟用加密數(shù)據(jù)在mongoDB中润匙,但是此主題不在本文的范圍之內(nèi)。


#結(jié)論

現(xiàn)在唉匾,我們有了一個(gè)可用的MongoDB復(fù)制集孕讳。您可以隨時(shí)將節(jié)點(diǎn)添加到此副本集。您甚至可以停止mongo容器或主要mongoNode1中的一個(gè)厂财,然后看著另一個(gè)mongoNode接管新的主要容器。由于數(shù)據(jù)寫在docker卷上峡懈,因此重啟這些節(jié)點(diǎn)中的任何一個(gè)都不是問(wèn)題璃饱。數(shù)據(jù)將保留并重新加入副本集。

給我們帶來(lái)的好處是肪康,我們看到了如何使用bash文件使整個(gè)過(guò)程自動(dòng)化荚恶。

您面臨的一個(gè)挑戰(zhàn)是修改bash腳本并使其更加動(dòng)態(tài)撩穿,因?yàn)樵撃_本非常適合本文的規(guī)范,而另一個(gè)挑戰(zhàn)是向體系結(jié)構(gòu)中添加一個(gè)任意Mongo節(jié)點(diǎn)谒撼。


Github倉(cāng)庫(kù)

要獲取本文的完整腳本文件食寡,可以在以下倉(cāng)庫(kù)中進(jìn)行檢查。

github-Crizstian / mongo-replica-with-docker:如何使用Docker部署MongoDB副本集github.com

進(jìn)一步閱讀


翻譯自:https://towardsdatascience.com/how-to-deploy-a-mongodb-replica-set-using-docker-6d0b9ac00e49

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市茉帅,隨后出現(xiàn)的幾起案子叨叙,更是在濱河造成了極大的恐慌锭弊,老刑警劉巖堪澎,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異味滞,居然都是意外死亡樱蛤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門剑鞍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)昨凡,“玉大人,你說(shuō)我怎么就攤上這事蚁署”慵梗” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵光戈,是天一觀的道長(zhǎng)哪痰。 經(jīng)常有香客問(wèn)我,道長(zhǎng)久妆,這世上最難降的妖魔是什么晌杰? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮筷弦,結(jié)果婚禮上肋演,老公的妹妹穿的比我還像新娘。我一直安慰自己烂琴,他們只是感情好爹殊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奸绷,像睡著了一般梗夸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上健盒,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天绒瘦,我揣著相機(jī)與錄音称簿,去河邊找鬼。 笑死惰帽,一個(gè)胖子當(dāng)著我的面吹牛憨降,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播该酗,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼授药,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了呜魄?” 一聲冷哼從身側(cè)響起悔叽,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎爵嗅,沒想到半個(gè)月后娇澎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡睹晒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年趟庄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伪很。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戚啥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锉试,到底是詐尸還是另有隱情猫十,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布呆盖,位于F島的核電站拖云,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏絮短。R本人自食惡果不足惜江兢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丁频。 院中可真熱鬧杉允,春花似錦、人聲如沸席里。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)奖磁。三九已至改基,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咖为,已是汗流浹背秕狰。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工稠腊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸣哀。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓架忌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親我衬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子叹放,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容