Docker容器實戰(zhàn)(八) - 漫談 Kubernetes 的本質(zhì)

在前面以Docker項目為例,一步步剖析了Linux容器的具體實現(xiàn)方式偶垮。
通過這些應該明白:一個“容器”铡俐,實際上是一個由Linux Namespace、Linux Cgroups和rootfs三種技術構建出來的進程的隔離環(huán)境脯倚。

一個正在運行的Linux容器,其實可以被看做

  • 一組聯(lián)合掛載在 /var/lib/docker/aufs/mnt 上的rootfs嵌屎,這部分稱為“容器鏡像”(Container Image)推正,是容器的靜態(tài)視圖
  • 一個由Namespace+Cgroups構成的隔離環(huán)境,這部分稱為“容器運行時”(Container Runtime)宝惰,是容器的動態(tài)視圖植榕。

作為一名開發(fā)者,我并不關心容器運行時的差異尼夺。
因為尊残,在整個“開發(fā)-測試-發(fā)布”的流程中,真正承載著容器信息進行傳遞的淤堵,是容器鏡像寝衫,而不是容器運行時。

這個重要假設拐邪,正是容器技術圈在Docker項目成功后不久慰毅,就迅速走向了“容器編排”這個“上層建筑”的主要原因:
作為云基礎設施提供商,只要能夠將用戶提交的Docker鏡像以容器的方式運行扎阶,就能成為容器生態(tài)圖上的一個承載點汹胃,從而將整個容器技術棧上的價值婶芭,沉淀在這個節(jié)點上。

更重要的是统台,只要從我這個承載點向Docker鏡像制作者和使用者方向回溯,整條路徑上的各個服務節(jié)點
比如CI/CD啡邑、監(jiān)控贱勃、安全、網(wǎng)絡谤逼、存儲等贵扰,都有我可以發(fā)揮和盈利的余地。
這個邏輯流部,正是所有云計算提供商如此熱衷于容器技術的重要原因:通過容器鏡像戚绕,它們可以和開發(fā)者關聯(lián)起來。

從一個開發(fā)者和單一的容器鏡像枝冀,到無數(shù)開發(fā)者和龐大容器集群舞丛,容器技術實現(xiàn)了從“容器”到“容器云”的飛躍,標志著它真正得到了市場和生態(tài)的認可果漾。
容器從一個開發(fā)者手里的小工具球切,一躍成為了云計算領域的絕對主角 而能夠定義容器組織和管理規(guī)范的“容器編排”技術,坐上了容器技術領域的“頭把交椅”

最具代表性的容器編排工具绒障,當屬

  • Docker公司的Compose+Swarm組合
  • Google與RedHat公司共同主導的Kubernetes項目

在前面介紹容器技術發(fā)展歷史中吨凑,已經(jīng)對這兩個開源項目做了詳細地剖析和評述。所以户辱,在今天專注于主角Kubernetes項目鸵钝,談一談它的設計與架構。

跟很多基礎設施領域先有工程實踐庐镐、后有方法論的發(fā)展路線不同恩商,Kubernetes項目的理論基礎則要比工程實踐走得靠前得多,這當然要歸功于Google公司在2015年4月發(fā)布的Borg論文了必逆。

Borg系統(tǒng)痕届,一直以來都被譽為Google公司內(nèi)部最強大的“秘密武器”。
相比于Spanner末患、BigTable等相對上層的項目研叫,Borg要承擔的責任,是承載Google整個基礎設施的核心依賴璧针。
在Google已經(jīng)公開發(fā)表的基礎設施體系論文中嚷炉,Borg項目當仁不讓地位居整個基礎設施技術棧的最底層。


這幅圖探橱,來自于Google Omega論文的第一作者的博士畢業(yè)論文申屹。它描繪了當時Google已經(jīng)公開發(fā)表的整個基礎設施棧绘证。在這個圖里,你既可以找到MapReduce哗讥、BigTable等知名項目嚷那,也能看到Borg和它的繼任者Omega位于整個技術棧的最底層。

正是由于這樣的定位杆煞,Borg可以說是Google最不可能開源的一個項目魏宽。
得益于Docker項目和容器技術的風靡,它卻終于得以以另一種方式與開源社區(qū)見面决乎,就是Kubernetes項目队询。

相比于“小打小鬧”的Docker公司、“舊瓶裝新酒”的Mesos社區(qū)构诚,Kubernetes項目從一開始就比較幸運地站上了一個他人難以企及的高度:
在它的成長階段蚌斩,這個項目每一個核心特性的提出,幾乎都脫胎于Borg/Omega系統(tǒng)的設計與經(jīng)驗范嘱。
更重要的是送膳,這些特性在開源社區(qū)落地的過程中,又在整個社區(qū)的合力之下得到了極大的改進丑蛤,修復了很多當年遺留在Borg體系中的缺陷和問題肠缨。

盡管在發(fā)布之初被批“曲高和寡”,但在逐漸覺察到Docker技術棧的“稚嫩”和Mesos社區(qū)的“老邁”盏阶,社區(qū)很快就明白了:Kubernetes項目在Borg體系的指導下晒奕,體現(xiàn)出了一種獨有的先進與完備性,這些才是一個基礎設施領域開源項目的核心價值名斟。

從Kubernetes的頂層設計說起脑慧。

Kubernetes要解決什么?

編排砰盐?調(diào)度闷袒?容器云?還是集群管理岩梳?

至今其實都沒有標準答案囊骤。在不同的發(fā)展階段,Kubernetes需要著力的問題是不同的冀值。

但對于大多數(shù)用戶也物,他們希望Kubernetes項目帶來的體驗是確定的:
現(xiàn)在我有應用的容器鏡像,請幫我在一個給定的集群上把應用運行起來
更進一步說列疗,還希望Kubernetes能給我提供路由網(wǎng)關滑蚯、水平擴展、監(jiān)控、備份告材、災難恢復等一系列運維能力坤次。

這不就是經(jīng)典PaaS(eg. Cloud Foundry)項目的能力嗎!
而且,有了Docker后斥赋,根本不需要什么Kubernetes缰猴、PaaS,只要使用Docker公司的Compose+Swarm項目疤剑,就完全可以很方便DIY出這些功能滑绒!
所以說,如果Kubernetes項目只是停留在拉取用戶鏡像骚露、運行容器蹬挤,以及提供常見的運維功能的話缚窿,那別說跟嫡系的Swarm競爭棘幸,哪怕跟經(jīng)典的PaaS項目相比也難有優(yōu)勢

而實際上,在定義核心功能過程中倦零,Kubernetes項目正是依托著Borg項目的理論優(yōu)勢
才在短短幾個月內(nèi)迅速站穩(wěn)了腳跟

  • 進而確定了一個如下所示的全局架構

可以看到误续,Kubernetes項目的架構,跟它的原型項目Borg類似扫茅,都由Master和Node兩種節(jié)點組成蹋嵌,分別對應著控制節(jié)點和計算節(jié)點。

其中葫隙,控制節(jié)點 --- 即Master節(jié)點栽烂,由三個緊密協(xié)作的獨立組件組合而成,它們分別是

  • 負責API服務的kube-apiserver
  • 負責調(diào)度的kube-scheduler
  • 負責容器編排的kube-controller-manager

整個集群的持久化數(shù)據(jù)恋脚,由kube-apiserver處理后保存在Ectd

而計算節(jié)點上最核心的是

kubelet組件


在Kubernetes中腺办,kubelet主要負責同容器運行時(比如Docker項目)打交道。
而這個交互所依賴的糟描,是一個稱作CRI(Container Runtime Interface) 的遠程調(diào)用接口怀喉,這個接口定義了容器運行時的各項核心操作,比如:啟動一個容器需要的所有參數(shù)船响。
這也是為何躬拢,Kubernetes項目并不關心你部署的是什么容器運行時、使用的什么技術實現(xiàn)见间,只要你的這個容器運行時能夠運行標準的容器鏡像聊闯,它就可以通過實現(xiàn)CRI接入到Kubernetes項目當中。

而具體的容器運行時米诉,比如Docker項目馅袁,則一般通過OCI這個容器運行時規(guī)范同底層的Linux操作系統(tǒng)進行交互,即:把CRI請求翻譯成對Linux操作系統(tǒng)的調(diào)用(操作Linux Namespace和Cgroups等)荒辕。

此外汗销,kubelet還通過gRPC協(xié)議同一個叫作Device Plugin的插件進行交互犹褒。



這個插件,是Kubernetes項目用來管理GPU等宿主機物理設備的主要組件弛针,也是基于Kubernetes項目進行機器學習訓練叠骑、高性能作業(yè)支持等工作必須關注的功能。

而kubelet的另一個重要功能削茁,則是調(diào)用網(wǎng)絡插件和存儲插件為容器配置網(wǎng)絡和持久化存儲宙枷。
這兩個插件與kubelet進行交互的接口,分別是

  • CNI(Container Networking Interface)
  • CSI(Container Storage Interface)茧跋。

實際上慰丛,kubelet這個奇怪的名字,來自于Borg項目里的同源組件Borglet瘾杭。
不過诅病,如果你瀏覽過Borg論文的話,就會發(fā)現(xiàn)粥烁,這個命名方式可能是kubelet組件與Borglet組件的唯一相似之處贤笆。因為Borg項目,并不支持我們這里所講的容器技術讨阻,而只是簡單地使用了Linux Cgroups對進程進行限制芥永。
這就意味著,像Docker這樣的“容器鏡像”在Borg中是不存在的钝吮,Borglet組件也自然不需要像kubelet這樣考慮如何同Docker進行交互埋涧、如何對容器鏡像進行管理的問題,也不需要支持CRI奇瘦、CNI棘催、CSI等諸多容器技術接口。

kubelet完全就是為了實現(xiàn)Kubernetes項目對容器的管理能力而重新實現(xiàn)的一個組件链患,與Borg之間并沒有直接的傳承關系巧鸭。

雖然不使用Docker,但Google內(nèi)部確實在使用一個包管理工具麻捻,名叫Midas Package Manager (MPM)纲仍,其實它可以部分取代Docker鏡像的角色。

Borg對于Kubernetes項目的指導作用又體現(xiàn)在哪里呢贸毕?

Master節(jié)點!

雖然在Master節(jié)點的實現(xiàn)細節(jié)上Borg與Kubernetes不盡相同郑叠,但出發(fā)點高度一致
即:如何編排、管理明棍、調(diào)度用戶提交的作業(yè)

所以乡革,Borg項目完全可以把Docker鏡像看做是一種新的應用打包方式。
這樣,Borg團隊過去在大規(guī)模作業(yè)管理與編排上的經(jīng)驗就可以直接“套”在Kubernetes項目沸版。

這些經(jīng)驗最主要的表現(xiàn)就是嘁傀,從一開始,Kubernetes就沒有像同期的各種“容器云”項目视粮,把Docker作為整個架構的核心细办,而是另辟蹊徑, 僅僅把它作為最底層的一個容器運行時實現(xiàn)

而Kubernetes著重解決的問題,則來自于Borg的研究人員在論文中提到的一個非常重要的觀點:

運行在大規(guī)模集群中的各種任務之間蕾殴,實際上存在著各種各樣的關系笑撞。這些關系的處理,才是作業(yè)編排和管理系統(tǒng)最困難的地方钓觉。

這種任務 <=>任務之間的關系隨處可見
比如

  • 一個Web應用與數(shù)據(jù)庫之間的訪問關系
  • 一個負載均衡器和它的后端服務之間的代理關系
  • 一個門戶應用與授權組件之間的調(diào)用關系

而且同屬于一個服務單位的不同功能之間茴肥,也完全可能存在這樣的關系
比如

  • 一個Web應用與日志搜集組件之間的文件交換關系。

而在容器技術普及之前荡灾,傳統(tǒng)虛擬機對這種關系的處理方法都比較“粗粒度”

  • 很多功能并不相關應用被一鍋部署在同臺虛擬機瓤狐,只是因為偶爾會互相發(fā)幾個HTTP請求!
  • 更常見的情況則是,一個應用被部署在虛擬機里之后卧晓,你還得手動維護很多跟它協(xié)作的守護進程(Daemon)芬首,用來處理它的日志搜集赴捞、災難恢復逼裆、數(shù)據(jù)備份等輔助工作。

在“功能單位”劃分上赦政,容器卻有著獨到的“細粒度”優(yōu)勢:
畢竟容器的本質(zhì)胜宇,只是一個進程而已

就是說,只要你愿意恢着,那些原擠在同一VM里的各個應用桐愉、組件、守護進程掰派,都可被分別做成鏡像!
然后運行在一個一個專屬的容器中从诲。
它們之間互不干涉,擁有各自的資源配額靡羡,可以被調(diào)度在整個集群里的任何一臺機器上系洛。
而這,正是一個PaaS系統(tǒng)最理想的工作狀態(tài)略步,也是所謂微服務思想得以落地的先決條件描扯。

如果只做到 封裝微服務、調(diào)度單容器 這層次趟薄,Docker Swarm 就已經(jīng)綽綽有余了绽诚。
如果再加上Compose項目,甚至還具備了處理一些簡單依賴關系的能力
比如

  • 一個“Web容器”和它要訪問的數(shù)據(jù)庫“DB容器”

Compose項目中,你可以為這樣的兩個容器定義一個“l(fā)ink”恩够,而Docker項目則會負責維護這個“l(fā)ink”關系
其具體做法是:Docker會在Web容器中卒落,將DB容器的IP地址、端口等信息以環(huán)境變量的方式注入進去蜂桶,供應用進程使用导绷,比如:

DB_NAME=/web/db
DB_PORT=tcp://172.17.0.5:5432
DB_PORT_5432_TCP=tcp://172.17.0.5:5432
DB_PORT_5432_TCP_PROTO=tcp
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_ADDR=172.17.0.5
  • 平臺項目自動地處理容器間關系的典型例子
    當DB容器發(fā)生變化時(比如鏡像更新,被遷移至其他宿主機)屎飘,這些環(huán)境變量的值會由Docker項目自動更新

可是妥曲,如果需求是,要求這個項目能夠處理前面提到的所有類型的關系钦购,甚至能

支持未來可能的更多關系

這時檐盟,“l(fā)ink”這針對一種案例設計的解決方案就太過簡單了

一旦要追求項目的普適性,那就一定要從頂層開始做好設計

Kubernetes最主要的設計思想是押桃,從更宏觀的角度葵萎,以統(tǒng)一的方式來定義任務之間的各種關系,并且為將來支持更多種類的關系留有余地唱凯。

比如羡忘,Kubernetes對容器間的“訪問”進行了分類,首先總結出了一類常見的“緊密交互”的關系磕昼,即:

  • 應用之間需要非常頻繁的交互和訪問
  • 會直接通過本地文件進行信息交換

常規(guī)環(huán)境下的應用往往會被直接部在同一臺機器卷雕,通過Localhost通信,通過本地磁盤目錄交換文件
而在Kubernetes票从,這些容器會被劃分為一個“Pod”
Pod里的容器共享同一個Network Namespace漫雕、同一組數(shù)據(jù)卷,從而達到高效率交換信息的目的峰鄙。

Pod是Kubernetes中最基礎的一個對象浸间,源自于Google Borg論文中一個名叫Alloc的設計


Borg分配(分配的縮寫)是一臺機器上可以運行一個或多個任務的資源的保留集。無論是否使用資源吟榴,資源都會保持分配狀態(tài)魁蒜。 Alloc可用于為將來的任務留出資源,在停止任務和重新啟動任務之間保留資源吩翻,以及將來自不同作業(yè)的任務收集到同一臺計算機上–例如兜看,一個Web服務器實例和一個關聯(lián)的logaver任務,用于復制服務器的URL日志從本地磁盤記錄到分布式文件系統(tǒng)仿野。分配資源與機器資源的處理方式相似铣减。在一個內(nèi)部運行的多個任務共享其資源。如果必須將分配重定位到另一臺計算機脚作,則其任務將隨之重新安排葫哗。
分配集就像一項工作:它是一組在多臺機器上保留資源的分配缔刹。創(chuàng)建分配集后,可以提交一個或多個作業(yè)以在其中運行劣针。為簡便起見校镐,我們通常使用“任務”來指代分配或頂級任務(在分配外的一個),使用“作業(yè)”來指代作業(yè)或分配集捺典。

而對于另外一種更為常見的需求鸟廓,比如

Web應用與數(shù)據(jù)庫之間的訪問關系

Kubernetes則提供了一種叫作“Service”的服務。像這樣的兩個應用襟己,往往故意不部署在同一機器引谜,即使Web應用所在的機器宕機了,數(shù)據(jù)庫也不受影響擎浴。
可對于一個容器來說员咽,它的IP地址等信息是不固定的,Web應用又怎么找到數(shù)據(jù)庫容器的Pod呢贮预?

所以贝室,Kubernetes的做法是給Pod綁定一個Service服務
Service服務聲明的IP地址等信息是“終生不變”的。Service主要就是作為Pod的代理入口(Portal)仿吞,從而代替Pod對外暴露一個固定的網(wǎng)絡地址滑频。
這樣,對于Web應用的Pod來說唤冈,它需要關心的就是數(shù)據(jù)庫Pod的Service信息峡迷。不難想象,Service后端真正代理的Pod的IP地址务傲、端口等信息的自動更新凉当、維護枣申,則是Kubernetes的職責售葡。

圍繞著容器和Pod不斷向真實的技術場景擴展,我們就能夠摸索出一幅如下所示

  • Kubernetes核心功能“全景圖”


  • 從容器這個最基礎的概念出發(fā)忠藤,首先遇到了容器間“緊密協(xié)作”關系的難題挟伙,于是就擴展到了Pod

  • 有了Pod之后,我們希望能一次啟動多個應用的實例模孩,這樣就需要Deployment這個Pod的多實例管理器

  • 而有了這樣一組相同的Pod后尖阔,我們又需要通過一個固定的IP地址和端口以負載均衡的方式訪問它,于是就有了Service

如果現(xiàn)在

兩個不同Pod之間不僅有“訪問關系”榨咐,還要求在發(fā)起時加上授權信息

最典型的例子就是Web應用對數(shù)據(jù)庫訪問時需要Credential(數(shù)據(jù)庫的用戶名和密碼)信息介却。
那么,在Kubernetes中這樣的關系又如何處理呢块茁?

Kubernetes項目提供了一種叫作Secret的對象齿坷,是一個保存在Etcd里的鍵值對桂肌。
這樣,你把Credential信息以Secret的方式存在Etcd里永淌,Kubernetes就會在你指定的Pod(比如崎场,Web應用Pod)啟動時,自動把Secret里的數(shù)據(jù)以Volume的方式掛載到容器里遂蛀。這樣谭跨,這個Web應用就可以訪問數(shù)據(jù)庫了。

除了應用與應用之間的關系外李滴,應用運行的形態(tài)是影響“如何容器化這個應用”的第二個重要因素螃宙。
為此,Kubernetes定義了基于Pod改進后的對象所坯。比如

  • Job
    描述一次性運行的Pod(比如污呼,大數(shù)據(jù)任務)
  • DaemonSet
    描述每個宿主機上必須且只能運行一個副本的守護進程服務
  • CronJob
    描述定時任務

如此種種,正是Kubernetes定義容器間關系和形態(tài)的主要方法包竹。
Kubernetes并沒有像其他項目那樣燕酷,為每一個管理功能創(chuàng)建一個指令,然后在項目中實現(xiàn)其中的邏輯
這種做法周瞎,的確可以解決當前的問題苗缩,但是在更多的問題來臨之后,往往會力不從心

相比之下声诸,在Kubernetes中酱讶,我們推崇

  • 首先,通過一個“編排對象”彼乌,比如Pod/Job/CronJob等描述你試圖管理的應用
  • 然后泻肯,再為它定義一些“服務對象”,比如Service/Secret/Horizontal Pod Autoscaler(自動水平擴展器)等慰照。這些對象灶挟,會負責具體的平臺級功能。

這種使用方法毒租,就是所謂的“聲明式API”稚铣。這種API對應的“編排對象”和“服務對象”,都是Kubernetes中的API對象(API Object)墅垮。

這就是Kubernetes最核心的設計理念惕医,也是接下來我會重點剖析的關鍵技術點。

Kubernetes如何啟動一個容器化任務

現(xiàn)在已經(jīng)制作好了一個Nginx容器鏡像算色,希望讓平臺幫我啟動這個鏡像抬伺。并且,我要求平臺幫我運行兩個完全相同的Nginx副本灾梦,以負載均衡的方式共同對外提供服務峡钓。

如果DIY齐鲤,可能需要啟動兩臺虛擬機,分別安裝兩個Nginx椒楣,然后使用keepalived為這兩個虛擬機做一個虛擬IP给郊。

而如果使用Kubernetes呢?要做的則是編寫如下這樣一個YAML文件(比如名叫nginx-deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

在上面這個YAML文件中捧灰,定義了一個Deployment對象淆九,它的主體部分(spec.template部分)是一個使用Nginx鏡像的Pod,而這個Pod的副本數(shù)是2(replicas=2)毛俏。

然后執(zhí)行:

$ kubectl create -f nginx-deployment.yaml

這樣炭庙,兩個完全相同的Nginx容器副本就被啟動了。
不過煌寇,這么看來焕蹄,做同樣一件事情,Kubernetes用戶要做的工作也不少啊
別急阀溶,在后續(xù)會陸續(xù)介紹Kubernetes這種“聲明式API”的好處腻脏,以及基于它實現(xiàn)的強大的編排能力。

總結

首先银锻,一起回顧了容器的核心知識永品,說明了容器其實可以分為兩個部分

  • 容器運行時
  • 容器鏡像

然后,重點介紹了Kubernetes的架構击纬,詳細講解了它如何使用“聲明式API”來描述容器化業(yè)務和容器間關系的設計思想鼎姐。

調(diào)度

過去很多的集群管理項目(比如Yarn、Mesos更振,以及Swarm)所擅長的炕桨,都是把一個容器,按照某種規(guī)則肯腕,放置在某個最佳節(jié)點上運行起來献宫。這種功能,稱為“調(diào)度”乎芳。

編排

而Kubernetes所擅長的遵蚜,是按照用戶的意愿和整個系統(tǒng)的規(guī)則,完全自動化地處理好容器之間的各種關系奈惑。
這種功能,就是我們經(jīng)常聽到的一個概念:編排睡汹。

所以說肴甸,Kubernetes的本質(zhì),是為用戶提供一個具有普遍意義的容器編排工具囚巴。
Kubernetes為用戶提供的不僅限于一個工具原在。它真正的價值友扰,還是在于提供了一套基于容器構建分布式系統(tǒng)的基礎依賴

參考

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市庶柿,隨后出現(xiàn)的幾起案子村怪,更是在濱河造成了極大的恐慌,老刑警劉巖浮庐,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甚负,死亡現(xiàn)場離奇詭異,居然都是意外死亡审残,警方通過查閱死者的電腦和手機梭域,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搅轿,“玉大人病涨,你說我怎么就攤上這事¤捣兀” “怎么了既穆?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雀鹃。 經(jīng)常有香客問我循衰,道長,這世上最難降的妖魔是什么褐澎? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任会钝,我火速辦了婚禮,結果婚禮上工三,老公的妹妹穿的比我還像新娘迁酸。我一直安慰自己,他們只是感情好俭正,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布奸鬓。 她就那樣靜靜地躺著,像睡著了一般掸读。 火紅的嫁衣襯著肌膚如雪串远。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天儿惫,我揣著相機與錄音澡罚,去河邊找鬼。 笑死肾请,一個胖子當著我的面吹牛留搔,可吹牛的內(nèi)容都是我干的螟蝙。 我是一名探鬼主播蛔垢,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了青责?” 一聲冷哼從身側響起穆端,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤绘盟,失蹤者是張志新(化名)和其女友劉穎概而,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掷豺,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡捞烟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了萌业。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坷襟。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖生年,靈堂內(nèi)的尸體忽然破棺而出婴程,到底是詐尸還是另有隱情,我是刑警寧澤抱婉,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布档叔,位于F島的核電站,受9級特大地震影響蒸绩,放射性物質(zhì)發(fā)生泄漏衙四。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一患亿、第九天 我趴在偏房一處隱蔽的房頂上張望传蹈。 院中可真熱鬧,春花似錦步藕、人聲如沸惦界。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沾歪。三九已至,卻和暖如春雾消,著一層夾襖步出監(jiān)牢的瞬間灾搏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工立润, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狂窑,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓范删,卻偏偏與公主長得像蕾域,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子到旦,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

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