第一章 kubernetes入門

1.1 Kubernetes是什么

  1. 首先,它是一個全新的基于容器技術(shù)的分布式架構(gòu)領(lǐng)先方案;
  2. 其次,Kubernetes是一個開放的開發(fā)平臺;
  3. 最后,Kubernetes是一個完備的分布式系統(tǒng)支撐平臺。

1.2 為什么要用Kubernetes

使用Kubernetes的理由很多,最根本的一個理由就是:IT從來都是一個由新技術(shù)驅(qū)動的行業(yè)。
使用Kubernetes所帶來的好處:

  1. 首先,最直接的感受就是我們可以“輕裝上陣”地開發(fā)復(fù)雜系統(tǒng)了;
  2. 其次,使用Kubernetes就是在全面擁抱微服務(wù)架構(gòu);
  3. 然后,我們的系統(tǒng)可以隨時隨地整體“搬遷”到公有云上;
  4. 最后,Kubernetes系統(tǒng)架構(gòu)具備了超強(qiáng)的橫向擴(kuò)容能力。

1.3 Kubernetes基本概念和術(shù)語

在Kubernetes中,Node、Pod、Replication Controller、Service等概念都可以看作一種資源對象,通過Kubernetes提供的Kubectl工具或者API調(diào)用進(jìn)行操作,并保存在etcd中。

1.3.1 Node(節(jié)點(diǎn))

Node(節(jié)點(diǎn))是Kubernetes集群中相對于Master而言的工作主機(jī),在較早的版本中也被稱為Minion。Node可以是一臺物理主機(jī),也可以是一臺虛擬機(jī)(VM)。在每個Node上運(yùn)行用于啟動和管理Pid的服務(wù)Kubelet,并能夠被Master管理。在Node上運(yùn)行的服務(wù)進(jìn)行包括Kubelet、kube-proxy和docker daemon。

Node信息如下:

  1. Node地址:主機(jī)的IP地址,或者Node ID。
  2. Node運(yùn)行狀態(tài):包括Pending、Running、Terminated三種狀態(tài)。
  3. Node Condition(條件):描述Running狀態(tài)Node的運(yùn)行條件,目前只有一種條件----Ready。Ready表示Node處于健康狀態(tài),可以接收從Master發(fā)來的創(chuàng)建Pod的指令。
  4. Node系統(tǒng)容量:描述Node可用的系統(tǒng)資源,包括CPU、內(nèi)存數(shù)量、最大可調(diào)度Pod數(shù)量等。
  5. 其他:Node的其他信息,包括實(shí)例的內(nèi)核版本號、Kubernetes版本號、Docker版本號、操作系統(tǒng)名稱等。

1. Node的管理

Node通常是物理機(jī)、虛擬機(jī)或者云服務(wù)商提供的資源,并不是由Kubernetes創(chuàng)建的。我們說Kubernetes創(chuàng)建一個Node,僅僅表示Kubernetes在系統(tǒng)內(nèi)部創(chuàng)建了一個Node對象,創(chuàng)建后即會對其進(jìn)行一系列健康檢查,包括是否可以連通、服務(wù)是否正確啟動、是否可以創(chuàng)建Pod等。如果檢查未能通過,則該Node將會在集群中被標(biāo)記為不可用(Not Ready)。

2. 使用Node Controller對Node進(jìn)行管理

Node Controller是Kubernetes Master中的一個組件,用于管理Node對象。它的兩個主要功能包括:集群范圍內(nèi)的Node信息同步,以及單個Node的生命周期管理。
Node信息同步可以通過kube-controller-manager的啟動參數(shù)--node-sync-period設(shè)置同步的時間周期。

3. Node的自注冊

當(dāng)Kubelet的--register-node參數(shù)被設(shè)置為true(默認(rèn)值即為true)時,Kubelet會向apiserver注冊自己。這也是Kubernetes推薦的Node管理方式。

Kubelet進(jìn)行自注冊的啟動參數(shù)如下:

  1. --apiservers=: apiserver地址;
  2. --kubeconfig=: 登錄apiserver所需憑據(jù)/證書的目錄;
  3. --cloud_provider=: 云服務(wù)商地址,用于獲取自身的metadata;
  4. --register-node=: 設(shè)置為true表示自動注冊到apiserver。

4. 手動管理Node

Kubernetes集群管理員也可以手工創(chuàng)建和修改Node對象。當(dāng)需要這樣操作時,先要將Kubelet啟動參數(shù)中的--register-node參數(shù)的值設(shè)置為false。這樣,在Node上的Kubelet就不會把自己注冊到apiserver中去了。

另外,Kubernetes提供了一種運(yùn)行時加入或者隔離某些Node的方法。具體操作請參考第四章。

1.3.2 Pod

Pod是Kubernetes的最基本操作單元,包含一個活多個緊密相關(guān)的容器,類似于豌豆莢的概念。一個Pod可以被一個容器化的環(huán)境看作應(yīng)用層的“邏輯宿主機(jī)”(Logical Host)。一個Pod中的多個容器應(yīng)用通常是緊耦合的。Pod在Node上被創(chuàng)建、啟動或者銷毀。

為什么Kubernetes使用Pod在容器之上再封裝一層呢?一個很重要的原因是,Docker容器之間的通信受到Docker網(wǎng)絡(luò)機(jī)制的限制。在Docker的世界中,一個容器需要link方式才能訪問另一個容器提供的服務(wù)(端口)。大量容器之間的link將是一個非常繁重的工作。通過Pod的概念將多個容器組合在一個虛擬的“主機(jī)”內(nèi),可以實(shí)現(xiàn)容器之間僅需要通過Localhost就能相互通信了。

一個Pod中的應(yīng)用容器共享同一組資源,如下所述:

  1. PID命名空間:Pod中的不同應(yīng)用程序可以看到其他應(yīng)用程序的進(jìn)程ID;
  2. 網(wǎng)絡(luò)命名空間:Pod中的多個容器能夠訪問同一個IP和端口范圍;
  3. IPC命名空間:Pod中的多個容器能夠使用SystemV IPC或者POSIX消息隊(duì)列進(jìn)行通信;
  4. UTS命名空間:Pod中的多個容器共享一個主機(jī)名;
  5. Volumes(共享存儲卷):Pod中的各個容器可以訪問在Pod級別定義的Volumes。

1. 對Pod的定義

對Pod的定義通過Yaml或Json格式的配置文件來完成。下面的配置文件將定義一個名為redis-slave的Pod,其中kind為Pod。在spec中主要包含了Containers(容器)的定義,可以定義多個容器。

apiVersion: v1
kind: Pod
metadata:
name: redis-slave
labels:
name: redis-slave
spec:
containers:
- name: slave
image: kubeguide/guestbook-redis-slave
env:
- name: GET_HOSTS_FROM
value: env
ports:
- containerPort: 6379

Pod的生命周期是通過Replication Controller來管理的。Pod的生命周期過程包括:通過模板進(jìn)行定義,然后分配到一個Node上運(yùn)行,在Pod所含容器運(yùn)行結(jié)束后Pod也結(jié)束。在整個過程中,Pod處于一下4種狀態(tài)之一:

  1. Pending:Pod定義正確,提交到Master,但其所包含的容器鏡像還未完成創(chuàng)建。通常Master對Pod進(jìn)行調(diào)度需要一些時間,之后Node對鏡像進(jìn)行下載也需要一些時間;
  2. Running:Pod已被分配到某個Node上,且其包含的所有容器鏡像都已經(jīng)創(chuàng)建完成,并成功運(yùn)行起來;
  3. Succeeded:Pod中所有容器都成功結(jié)束,并且不會被重啟,這是Pod的一種最終狀態(tài);
  4. Failed:Pod中所有容器都結(jié)束了,但至少一個容器是以失敗狀態(tài)結(jié)束的,這也是Pod的一種最終狀態(tài)。

Kubernetes為Pod設(shè)計(jì)了一套獨(dú)特的網(wǎng)絡(luò)配置,包括:為每個Pod分配一個IP地址,使用Pod名作為容器間通信的主機(jī)名等。關(guān)于Kubernetes網(wǎng)絡(luò)的設(shè)計(jì)原理將在第2章進(jìn)行詳細(xì)說明。

另外,不建議在Kubernetes的一個Pod內(nèi)運(yùn)行相同應(yīng)用的多個實(shí)例。

1.3.3 Label(標(biāo)簽)

Label是Kubernetes系統(tǒng)中的一個核心概念。Label以key/value鍵值對的形式附加到各種對象上,如Pod、Service、RC、Node等。Label定義了這些對象的可識別屬性,用來對它們進(jìn)行管理和選擇。Label可以在創(chuàng)建時附加到對象上,也可以在對象創(chuàng)建后通過API進(jìn)行管理。

在為對象定義好Label后,其他對象就可以使用Label Selector(選擇器)來定義其作用的對象了。

Label Selector的定義由多個逗號分隔的條件組成。

"labels": {
"key1": "value1",
"key2": "value2"
}

當(dāng)前有兩種Label Selector:基于等式的(Equality-based)和基于集合的(Set-based),在使用時可以將多個Label進(jìn)行組合來選擇。

基于等式的Label Selector使用等式類的表達(dá)式來進(jìn)行選擇:

  1. name = redis-slave: 選擇所有包含Label中key="name"且value="redis-slave"的對象;
  2. env != production: 選擇所有包括Label中的key="env"且value不等于"production"的對象。

基于集合的Label Selector使用集合操作的表達(dá)式來進(jìn)行選擇:

  1. name in (redis-master, redis-slave): 選擇所有包含Label中的key="name"且value="redis-master"或"redis-slave"的對象;
  2. name not in (php-frontend): 選擇所有包含Label中的key="name"且value不等于"php-frontend"的對象。

在某些對象需要對另一些對象進(jìn)行選擇時,可以將多個Label Selector進(jìn)行組合,使用逗號","進(jìn)行分隔即可。基于等式的LabelSelector和基于集合的Label Selector可以任意組合。例如:

name=redis-slave,env!=production
name not in (php-frontend),env!=production

1.3.4 Replication Controller(RC)

Replication Controller是Kubernetes系統(tǒng)中的核心概念,用于定義Pod副本的數(shù)量。在Master內(nèi),Controller Manager進(jìn)程通過RC的定義來完成Pod的創(chuàng)建、監(jiān)控、啟停等操作。

根據(jù)Replication Controller的定義,Kubernetes能夠確保在任意時刻都能運(yùn)行用于指定的Pod“副本”(Replica)數(shù)量。如果有過多的Pod副本在運(yùn)行,系統(tǒng)就會停掉一些Pod;如果運(yùn)行的Pod副本數(shù)量太少,系統(tǒng)就會再啟動一些Pod,總之,通過RC的定義,Kubernetes總是保證集群中運(yùn)行著用戶期望的副本數(shù)量。

同時,Kubernetes會對全部運(yùn)行的Pod進(jìn)行監(jiān)控和管理,如果有需要(例如某個Pod停止運(yùn)行),就會將Pod重啟命令提交給Node上的某個程序來完成(如Kubelet或Docker)。

可以說,通過對Replication Controller的使用,Kubernetes實(shí)現(xiàn)了應(yīng)用集群的高可用性,并大大減少了系統(tǒng)管理員在傳統(tǒng)IT環(huán)境中需要完成的許多手工運(yùn)維工作(如主機(jī)監(jiān)控腳本、應(yīng)用監(jiān)控腳本、故障恢復(fù)腳本等)。

對Replication Controller的定義使用Yaml或Json格式的配置文件來完成。以redis-slave為例,在配置文件中通過spec.template定義Pod的屬性(這部分定義與Pod的定義是一致的),設(shè)置spec.replicas=2來定義Pod副本的數(shù)量。

apiVersion: v1
kind: ReplicationController
metadata:
name: redis-slave
labels: redis-slave
name: redis-slave
spec:
replicas: 2
selector:
name: redis-slave
template:
metadata:
labels:
name: redis-slave
spec:
container:
- name: slave
image: kubeguide/guestbook-redis-slave
env:
- name: GET_HOSTS_FROM
value: env
ports:
- containerPort: 6379

通常,Kubernetes集群中不止一個Node,假設(shè)一個集群有3個Node,根據(jù)RC的定義,系統(tǒng)將可能在其中的兩個Node上創(chuàng)建Pod。

1.3.5 Service(服務(wù))

在Kubernetes的世界里,雖然每個Pod都會被分配一個單獨(dú)的IP地址,這個IP地址會隨時Pod的銷毀而消失。這就引出一個問題:如果有一組Pod組成一個集群來提供服務(wù),那么如何來訪問它們呢?

Kubernetes的Service(服務(wù))就是用來解決這個問題的核心概念。

一個Service可以看作一組提供相同服務(wù)的Pod的對外訪問接口。Service作用于哪些Pod是通過Label Selector來定義的。

1. 對Service的定義

對Service的定義同樣使用Yaml或Json格式的配置文件來完成。以redis-slave服務(wù)的定義為例:

apiVersion: v1
kind: Service
metadata:
name: redis-slave
labels:
name: redis-slave
spec:
ports:
- port: 6379
selector:
name: redis-slave

通過該定義,Kubernetes將會創(chuàng)建一個名為“redis-slave”的服務(wù),并在6379端口上監(jiān)聽。spec.selector的定義表示該Service將包含所有具有"name=redis-slave"的Label的Pod。

在Pod正常啟動后,系統(tǒng)將會根據(jù)Service的定義創(chuàng)建出與Pod對應(yīng)的Endpoint(端點(diǎn))對象,以建立起Service與后端Pod的對應(yīng)關(guān)系。隨著Pod的創(chuàng)建、銷毀,Endpoint對象也將被更新。Endpoint對象主要有Pod的IP地址和容器所需監(jiān)聽的端口號組成。

2. Pod的IP地址和Service的Cluster IP地址

Pod的IP地址是Docker Daemon根據(jù)docker0網(wǎng)橋的IP地址段進(jìn)行分配的,但Service的Cluster IP地址是Kubernetes系統(tǒng)中的虛擬IP地址,由系統(tǒng)動態(tài)分配。Service的Cluster IP地址相對于Pod的IP地址來說相對穩(wěn)定,Service被創(chuàng)建時即被分配一個IP地址,在銷毀該Service之前,這個IP地址都不會再變化了。而Pod在Kubernetes集群中生命周期較短,可能被ReplicationContrller銷毀、再次創(chuàng)建,新創(chuàng)建的Pod將會分配一個新的IP地址。

3. 外部訪問Service

由于Service對象在Cluster IP Range池中分配到的IP只能在內(nèi)部訪問,所以其他Pod都可以無障礙地訪問到它。到如果這個Service作為前端服務(wù),準(zhǔn)備為集群外的客戶端提供服務(wù),我們就需要給這個服務(wù)提供公共IP了。

Kubernetes支持兩種對外提供服務(wù)的Service的type定義:NodePort和LoadBalancer。

1. NodePort

在定義Service時指定spec.type=NodePort,并指定spec.ports.nodePort的值,系統(tǒng)就會在Kubernetes集群中的每個Node上打開一個主機(jī)上的真實(shí)端口號。這樣,能夠訪問Node的客戶端都就能通過這個端口號訪問到內(nèi)部的Service了。

以php-frontend service的定義為例,nodePort=80,這樣,在每一個啟動了該php-frontend Pod的Node節(jié)點(diǎn)上,都會打開80端口。

apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
name: frontend
spec:
type: NodePort
ports:
- port: 80
nodePort: 30001
selector:
name: frontend

2. LoadBalancer

如果云服務(wù)商支持外接負(fù)載均衡器,則可以通過spec.type=LoadBalaner定義Service,同時需要制定負(fù)載均衡器的IP地址。使用這種類型需要指定Service的nodePort和clusterIP。例如:

apiVersion: v1
kind: Service
metadata: {
"kind" "Service",
"apiVersion": "v1",
"metadata": {
"name": "my-service"
},
"spec": {
"type": "LoadBalaner",
"clusterIP": "10.0.171.239",
"selector": {
"app": "MyApp"
},
"ports": [
{
"protocol": "TCP",
"port": 80,
"targetPort": 9376,
"nodePort": 30061
}
],
},
"status": {
"loadBalancer": {
"ingress": [
{
"ip": "146.148.47.155"
}
]
}
}
}

在這個例子中,status.loadBalancer.ingress.ip設(shè)置的146.146.47.155為云服務(wù)商提供的負(fù)載均衡器的IP地址。

之后,對該Service的訪問請求將會通過LoadBalancer轉(zhuǎn)發(fā)到后端Pod上去,負(fù)載分發(fā)的實(shí)現(xiàn)方式則依賴于云服務(wù)上提供的LoadBalancer的實(shí)現(xiàn)機(jī)制。

1.3.6 Volume(存儲卷)

Volume是Pod中能夠被多個容器訪問的共享目錄。Kubernetes的Volume概念與Docker的Volume比較類似,但不完全相同。Kubernetes中的Volume與Pod生命周期相同,但與容器的生命周期不相關(guān)。當(dāng)容器終止或者重啟時,Volume中的數(shù)據(jù)也不會丟失。另外,Kubernetes支持多種類型的Volume,并且一個Pod可以同時使用任意多個Volume。
Kubernetes提供了非常豐富的Volume類型,下面逐一進(jìn)行說明。

  1. EmptyDir:一個EmptyDir Volume是在Pod分配到Node時創(chuàng)建的。從它的名稱就可以看出,它的初始內(nèi)容為空。在同一個Pod中所有容器可以讀和寫EmptyDir中的相同文件。當(dāng)Pod從Node上移除時,EmptyDir中的數(shù)據(jù)也會永久刪除。
  2. hostPath:在Pod上掛載宿主機(jī)上的文件或目錄。
  3. gcePersistentDisk:使用這種類型的Volume表示使用谷歌計(jì)算引擎(Google Compute Engine,GCE)上永久磁盤(Persistent Disk,PD)上的文件。與EmptyDir不同,PD上的內(nèi)容會永久保存,當(dāng)Pod被刪除時,PD只是被卸載(Unmount),但不會被刪除。需要注意的是,你需要先創(chuàng)建一個永久磁盤(PD)才能使用gcePersistentDisk。
  4. awsElasticBlockStore:與GCE類似,該類型的Volume使用Amazon提供的Amazon Web Service(AWS)的EBS Volume,并可以掛在到Pod中去。需要注意到是,需要首先創(chuàng)建一個EBS Volume才能使用awsElasticBlockStore。
  5. nfs:使用NFS(網(wǎng)絡(luò)文件系統(tǒng))提供的共享目錄掛載到Pod中。在系統(tǒng)中需要一個運(yùn)行中的NFS系統(tǒng)。
  6. iscsi:使用iSCSI存儲設(shè)備上的目錄掛載到Pod中。
  7. glusterfs:使用開源GlusterFS網(wǎng)絡(luò)文件系統(tǒng)的目錄掛載到Pod中。
  8. rbd:使用Linux塊設(shè)備共享存儲(Rados Block Device)掛載到Pod中。
  9. gitRepo:通過掛載一個空目錄,并從GIT庫clone一個git respository以供Pod使用。
  10. secret:一個secret volume用于為Pod提供加密的信息,你可以將定義在Kubernetes中的secret直接掛載為文件讓Pod訪問。secret volume是通過tmfs(內(nèi)存文件系統(tǒng))實(shí)現(xiàn)的,所以這種類型的volume總是不會持久化的。
  11. persistentVolumeClaim:從PV(PersistentVolume)中申請所需的空間,PV通常是一種網(wǎng)絡(luò)存儲,例如GCEPersistentDisk、AWSElasticBlockStore、NFS、iSCSI等。

1.3.7 Namespace(命名空間)

Namespace(命名空間)是Kubernetes系統(tǒng)中的另一個非常重要的概念,通過將系統(tǒng)內(nèi)部的對象“分配”到不同的Namespace中,形成邏輯上分組的不同項(xiàng)目、小組或用戶組,便于不同的分組在共享使用整個集群的資源的同時還能被分別管理。
Kubernetes集群在啟動后,會創(chuàng)建一個名為“default”的Namespace,通過Kubectl可以查看到。
使用Namespace來組織Kubernetes的各種對象,可以實(shí)現(xiàn)對用戶的分組,即“多租戶”管理。對不同的租戶還可以進(jìn)行單獨(dú)的資源配額設(shè)置和管理,使得整個集群的資源配置非常靈活、方便。

1.3.8 Annotation(注解)

Annotation與Label類似,也使用key/value鍵值對的形式進(jìn)行定義。Label具有嚴(yán)格的命名規(guī)則,它定義的是Kubernetes對象的元數(shù)據(jù)(Metadata),并且用于Label Selector。Annotation則是用戶任意定義的“附加”信息,以便于外部工具進(jìn)行查找。
用Annotation來記錄的信息包括:

  1. build信息、release信息、Docker鏡像信息等,例如時間戳、release id號、PR號、鏡像hash值、docker registry地址等;
  2. 日志庫、監(jiān)控庫、分析庫等資源庫的地址信息;
  3. 程序調(diào)試工具信息,例如工具名稱、版本號等;
  4. 團(tuán)隊(duì)的聯(lián)系信息,例如電話號碼、負(fù)責(zé)人名稱、網(wǎng)址等。?

1.3.9 小結(jié)

上述這些組件是Kubernetes系統(tǒng)的核心組件,它們共同構(gòu)成了Kubernetes系統(tǒng)的框架和計(jì)算模型。通過對它們進(jìn)行靈活組合,用戶就可以快速、方便地對容器集群進(jìn)行配置、創(chuàng)建和管理。
除了以上核心組件,在Kubernetes系統(tǒng)中還有許多可供配置的資源對象,例如LimitRange、ResourceQuota。另外,一些系統(tǒng)內(nèi)部使用的對象Binding、Event等請參考Kubernetes的API文檔。

1.4 Kubernetes總體架構(gòu)

Kubernetes集群由兩類節(jié)點(diǎn)組成:Master和Node。在Master上運(yùn)行etcd、API Server、Controller Manager和Scheduler四個組件,其中后三個組件構(gòu)成了Kubernetes的總控中心,負(fù)責(zé)對集群中所有資源進(jìn)行管理和調(diào)度。在每個Node上運(yùn)行Kubelet、Proxy和Docker Daemon三個組件,負(fù)責(zé)對本節(jié)點(diǎn)上的Pod的生命周期進(jìn)行管理,以及實(shí)現(xiàn)服務(wù)代理的功能。另外在所有節(jié)點(diǎn)上都可以運(yùn)行Kubectl命令行工具,它提供了Kubernetes的集群管理工具集。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,958評論 2 373

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