K8s容器日志实时收集FileBeat+ES+Kibana

ELK

K8s容器日志实时收集FileBeat+ES+Kibana

一、FileBeat

1.1 FileBeat工作原理

harvester

prospector

Filebeat 保持文件状态

二、环境配置

2.1 Tomcat镜像制作

2.2 Filebeat 制作镜像

2.3 Elasticsearch安装

2.4 kibana安装

2.5 测试镜像

2.6 服务检查

k8s日志收集第一种方式

k8s日志收集第二种方式

环境说明

IP地址服务主机名

10.4.82.119docker、k8s_master|node、master

10.4.82.120docker、 k8s_node、kibananode

10.4.82.115es、Harbor镜像仓库、docker (主要作用就是打一个filebeat镜像)i4t

提示:filebeat跑在k8s容器内部,所以没有单独创建服务

一、FileBeat

作为 Beats 家族的一员,Filebeat 是一个轻量级的日志传输工具,它的存在正弥补了 Logstash 的缺点:Filebeat 作为一个轻量级的日志传输工具可以将日志推送到中心 Logstash。

在版本 5.x 中,Elasticsearch 具有解析的能力(像 Logstash 过滤器)— Ingest。这也就意味着可以将数据直接用 Filebeat 推送到 Elasticsearch,并让 Elasticsearch 既做解析的事情,又做存储的事情。也不需要使用缓冲,因为 Filebeat 也会和 Logstash 一样记住上次读取的偏移:

如果需要缓冲(例如,不希望将日志服务器的文件系统填满),可以使用 Redis/Kafka,因为 Filebeat 可以与它们进行通信:

Filebeat 优点

Filebeat 只是一个二进制文件没有任何依赖。它占用资源极少,尽管它还十分年轻,正式因为它简单,所以几乎没有什么可以出错的地方,所以它的可靠性还是很高的。它也为我们提供了很多可以调节的点,例如:它以何种方式搜索新的文件,以及当文件有一段时间没有发生变化时,何时选择关闭文件句柄。

Filebeat 缺点

Filebeat 的应用范围十分有限,所以在某些场景下我们会碰到问题。例如,如果使用 Logstash 作为下游管道,我们同样会遇到性能问题。正因为如此,Filebeat 的范围在扩大。开始时,它只能将日志发送到 Logstash 和 Elasticsearch,而现在它可以将日志发送给 Kafka 和 Redis,在 5.x 版本中,它还具备过滤的能力。

典型应用场景

Filebeat 在解决某些特定的问题时:日志存于文件,我们希望

① 将日志直接传输存储到 Elasticsearch。这仅在我们只是抓去(grep)它们或者日志是存于 JSON 格式(Filebeat 可以解析 JSON)。或者如果打算使用 Elasticsearch 的 Ingest 功能对日志进行解析和丰富。

② 将日志发送到 Kafka/Redis。所以另外一个传输工具(例如,Logstash 或自定义的 Kafka 消费者)可以进一步丰富和转发。这里假设选择的下游传输工具能够满足我们对功能和性能的要求。

1.1 FileBeat工作原理

Filebeat是本地文件的日志数据采集器。作为服务器上的代理安装,Filebeat监视日志目录或特定的日志文件tail -f file并将它们转发给ES、Logstash、Kafka

Filebeat由二个主要组件组成:prospectorhavvester这些组件一起工作读取文件并将时间数据发送到指定的输出

启动Filebeat时,它会启动一个或多个查找器,查看您的日志文件指定的本地路径。对**prospector**所在的每个日志文件,prospector启动harvester。每个harvester都会为新内容读取单个日志文件,并将新日志数据发送到libbeat,后者将聚合事件合并聚合数据发送到Filebeat配置的输出

harvester

负载读取单个文化的内容。读取每个文件,并将内容发送到the output。每个文件启动一个harvester,负责打开和关闭文件,这意味着在运行时文件描述符保持打开状态

如果文件在读取时被删除或重命名,Filebeat将继续读取文件。在harvester关闭之前,磁盘上的空间被保留。默认情况下,Filebeat将文件保持打开状态,直到达到close_inactive状态

关闭harvester会产生以下结果

1.如果在harvester仍在读取文件时文件被删除,则关闭文件句柄,释放底层资源。

2.文件的采集只会在scan_frequency过后重新开始

3.如果在harvester关闭的情况下移动文件,则不会继续处理文件

prospector

负责管理harvester并找到所有要读取的文件来源。

如果输入类型为日志,则查找器将查找路径匹配的所有文件,并为每个文件启动一个harvester。每个prospector都在自己的Go斜程中运行

以下示例将Filebeat配置为从与指定的匹配的所有日志文件中收集行:

filebeat.prospectors:

- type: log

  paths:

    - /data/log/*.log

    - /data/log4j/*.log

Filebeat目前支持两种prospector类型:log和stdin

每个prospector类型可以定义多次

日志prospector检查每个文件以查看harvester是否需要启动,是否已经运行

只有在harvest关闭后文件大小发生了变化,才会读到新行

注:Filebeat prospector只能读取本地文件,没有功能可以连接到远程主机来读取存储的日志或文件

Filebeat 保持文件状态

Filebeat 保存每个文件的状态并经常讲状态刷新到磁盘上的注册中心中。该状态用于记录harvest正在读取的最后偏移量,并确保发送所有日志行。

如果输出(例如ES或Logstash)无法访问,Filebeat会跟踪最后发送的行,并在输出再次可用时继续读取文件。

在Filebeat运行时,每个prospector内存中也会保存文件状态信息。由于文件可以被重命名活移动,因为文件名和路径不足易识别文件。对每个文件,Filebeat存储唯一标示符以检测文件是否先前已经采集过

Filebeat如何确保至少一次交付

Filebeat保证事件至少会被传送到配置的输出一次,并且不会丢失数据。Filebeat能够实现此行为,因为它将每个事件的传递状态存储在注册文件中。在输出阻塞或未确认所有事件的情况下,Filebeat将继续尝试发送事件,直到接收端确认已收到。

如果Filebeat在发送事件的过程中关闭,它不会等待输出确认所有收到事件。发送到输出但在Filebeat关闭前未确认的任何事在重新启动Filebeat时会再次发送。这可以确保每个事件至少发送一次,但最终会重复事件发送到输出。也可以通过设置shutdown_timeout选项来配置Filebeat以在关闭之前等待特定事件

注:

Filebeat的至少一次交付保证包括日志轮换和删除旧文件的限制。如果将日志文件写入磁盘并且写入速度超过Filebeat可以处理的速度,或者在输出不可用时删除了文件,则可能会丢数据。在Linux,Filebeat也可能因为inode重用而跳过行

本段参考://www.greatytc.com/p/6282b04fe06a

二、环境配置

Docker安装

wget http://down.abcdocker.com/docker/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm

wget http://down.abcdocker.com/docker/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm

yum 安装

yum install docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm -y

yum install docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm -y

systemctl enable docker

systemctl start docker

sed -i '/ExecStart=\/usr\/bin\/dockerd/i\ExecStartPost=\/sbin/iptables -I FORWARD -s 0.0.0.0\/0 -d 0.0.0.0\/0 -j ACCEPT' /usr/lib/systemd/system/docker.service

sed -i '/dockerd/s/$/ \-\-storage\-driver\=overlay2/g' /usr/lib/systemd/system/docker.service

systemctl daemon-reload

systemctl restart docker

#设置存储引擎和防火墙

2.1 Tomcat镜像制作

我们这里以Tomcat项目为基础进行测试

Docker文件内容如下

#这里需要把apache和jdk下载到本地,需要和Dockerfile在同一目录

wget http://down.abcdocker.com/docker/jdk1.8.0_66.tar.gz

wget http://down.abcdocker.com/docker/apache-tomcat-8.5.39.tar.gz

[root@i4t tomcat_test]# cat Dockerfile

# docker pull centos

###############################################################################

#                                INSTALLATION

###############################################################################

#                              www.i4t.com

##############################################################################

#            .o.        .o8                      .o8                      oooo

#          .888.      "888                      "888                      `888

#          .8"888.      888oooo.  .ooooo.  .oooo888  .ooooo.  .ooooo.  888  oooo  .ooooo.  oooo d8b

#        .8' `888.    d88' `88b d88' `"Y8 d88' `888  d88' `88b d88' `"Y8  888 .8P'  d88' `88b `888""8P

#        .88ooo8888.    888  888 888      888  888  888  888 888        888888.    888ooo888  888

#      .8'    `888.  888  888 888  .o8 888  888  888  888 888  .o8  888 `88b.  888    .o  888

#      o88o    o8888o  `Y8bod8P' `Y8bod8P' `Y8bod88P" `Y8bod8P' `Y8bod8P' o888o o888o `Y8bod8P' d888b

#

#

#                        ****        ****

#                      ***  ***      **  ***

#                      *      *    **    *

#

#                            **    **

#                            ***  **

#                              ****

#####################################################################################

FROM centos

MAINTAINER www.i4t.com "cyh@i4t.com"

WORKDIR /tmp

## Please see https://i4t.com/3552.html  install JDK

COPY jdk1.8.0_66.tar.gz /tmp

    RUN tar zxf /tmp/jdk1.8.0_66.tar.gz -C /usr/local/ && rm -rf /tmp/jdk1.8.0_66.tar.gz

    RUN ln -s /usr/local/jdk1.8.0_66 /usr/local/jdk

#/etc/profile

    ENV JAVA_HOME /usr/local/jdk

    ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

    ENV PATH $PATH:$JAVA_HOME/bin

# add apache

# Please see i4t.com && baidu.com

    COPY apache-tomcat-8.5.39.tar.gz /tmp

    RUN tar zxf apache-tomcat-8.5.39.tar.gz -C /usr/local  && rm -rf /tmp/apache-tomcat-8.5.39.zip

    RUN mv /usr/local/apache-tomcat-8.5.39 /usr/local/tomcat

#port

    EXPOSE 8080

###############################################################################

#                                  START

###############################################################################

ENTRYPOINT /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out

构建tomcat镜像

[root@i4t ~]# docker build -t i4t.com/tomcat/tomcat.v1 /data/tomcat_test/

Sending build context to Docker daemon 205.6 MB

Step 1/14 : FROM centos

---> 9f38484d220f

Step 2/14 : MAINTAINER www.i4t.com "cyh@i4t.com"

---> Using cache

---> 4a7c687c3bf7

Step 3/14 : WORKDIR /tmp

---> Using cache

---> 4bc766547f5c

Step 4/14 : COPY jdk1.8.0_66.tar.gz /tmp

---> Using cache

---> 2fd3ec55a068

Step 5/14 : RUN tar zxf /tmp/jdk1.8.0_66.tar.gz -C /usr/local/ && rm -rf /tmp/jdk1.8.0_66.tar.gz

---> Using cache

---> 3cb37cce7028

Step 6/14 : RUN ln -s /usr/local/jdk1.8.0_66 /usr/local/jdk

---> Using cache

---> 790555e157f7

Step 7/14 : ENV JAVA_HOME /usr/local/jdk

---> Using cache

---> 9a0bcf883c98

Step 8/14 : ENV CLASSPATH .:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

---> Using cache

---> 9d4f614f7979

Step 9/14 : ENV PATH $PATH:$JAVA_HOME/bin

---> Using cache

---> b99a4730d3ea

Step 10/14 : COPY apache-tomcat-8.5.39.tar.gz /tmp

---> Using cache

---> 73a8408bc879

Step 11/14 : RUN tar zxf apache-tomcat-8.5.39.tar.gz -C /usr/local  && rm -rf /tmp/apache-tomcat-8.5.39.zip

---> Using cache

---> 34d63da07d30

Step 12/14 : RUN mv /usr/local/apache-tomcat-8.5.39 /usr/local/tomcat

---> Using cache

---> 7dae5cb15207

Step 13/14 : EXPOSE 8080

---> Using cache

---> 8ec8c8470149

Step 14/14 : ENTRYPOINT /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out

---> Using cache

---> 0eac795556fb

Successfully built 0eac795556fb

#更改镜像名称

docker tag [原镜像]  [新镜像]

例子:docker tag i4t.com/tomcat/tomcatv1  i4t.com/tomcat/i4tv1

镜像打包完成后,我们在docker容器手动启动镜像进行测试

[root@i4t tomcat]# docker run -idt --name i4t_tomcat_test -p 80:8080 i4t.com/tomcat/tomcat.v1

f6f1621d9464ea2d17a4611393b1950e36f5b7b6c9234f322d636d47fee94e10

#run 运行容器

-it 进入容器

-d  后台运行

--name 新容器名称

-p 映射端口

i4t.com/tomcat/tomcat.v1 镜像名称

在Docker本机使用curl命令验证服务是否正常运行 (主要是判断docker build是否有问题)

容器正常启动访问说明我们tomcat镜像是没有问题

当我们镜像打包完成docker启动正常之后,直接push到Harbor镜像仓库即可

docker push i4t.com/tomcat/i4tv1

下面是harbor搭建文档

harbor安装

这里稍微说明一点,如果是线上环境,需要替换war包操作。可以将上面制作的tomcat镜像为基础镜像,在写一个dockerfile。我这里提供一下

#这里不是重点,我不详细说。步骤放在这

# cat dockerfile

FROM i4t.com/tomcat/tomcat.v1

MAINTAINER abcdocker "i4t.com"

COPY ROOT.tgz /data/

RUN tar zxf /data/ROOT.tgz -C /usr/local/tomcat/webapps/ && rm -rf /data/ROOT.tgz

# docker build -t tomcat_video:v1

# docker tag tomcat_video:v1 i4t.com/tomcat_video:v1

# docker push i4t.com/tomcat_video:v1

2.2 Filebeat 制作镜像

我们这里讲的是使用Filebeat来收集日志,ELK安装具体可以参考

ELK 二进制安装并收集nginx日志

tomcat服务已经可以正常运行,现在我们部署filebeat镜像

[root@i4t filebeat]# docker build -t tomcat_filebeat:v2 /data/filebeat/

Sending build context to Docker daemon 50.63 MB

Step 1/9 : FROM docker.io/centos

---> 9f38484d220f

Step 2/9 : MAINTAINER www.i4t.com <cyh@i4t.com>

---> Using cache

---> bbc4c3a8b392

Step 3/9 : WORKDIR /usr/local

---> Using cache

---> 7af655ce0f61

Step 4/9 : ENV FILEBEAT_VERSION 6.7.0

---> Using cache

---> 227c02e65a80

Step 5/9 : RUN set -x      && curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-${FILEBEAT_VERSION}-linux-x86_64.tar.gz      && tar xf filebeat-${FILEBEAT_VERSION}-linux-x86_64.tar.gz -C /usr/local      && ln -s /usr/local/filebeat-${FILEBEAT_VERSION}-linux-x86_64 /usr/local/filebeat      && chmod +x /usr/local/filebeat/filebeat        && mkdir -p /etc/filebeat

---> Running in 6d86756e5c4a

+ curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.7.0-linux-x86_64.tar.gz

  % Total    % Received % Xferd  Average Speed  Time    Time    Time  Current

                                Dload  Upload  Total  Spent    Left  Speed

100 11.1M  100 11.1M    0    0  382k      0  0:00:29  0:00:29 --:--:-- 1149k

+ tar xf filebeat-6.7.0-linux-x86_64.tar.gz -C /usr/local

+ ln -s /usr/local/filebeat-6.7.0-linux-x86_64 /usr/local/filebeat

+ chmod +x /usr/local/filebeat/filebeat

+ mkdir -p /etc/filebeat

---> 8920fb78ff5d

Removing intermediate container 6d86756e5c4a

Step 6/9 : ADD ./docker-entrypoint.sh /usr/bin/

---> d2989df722b1

Removing intermediate container dbe668e7cd75

Step 7/9 : RUN chmod +x /usr/bin/docker-entrypoint.sh

---> Running in eb7c7304647a

---> 5ea2cb81cad6

Removing intermediate container eb7c7304647a

Step 8/9 : ENTRYPOINT docker-entrypoint.sh

---> Running in bed03d3aa8e3

---> cb9d8de0d329

Removing intermediate container bed03d3aa8e3

Step 9/9 : CMD /usr/local/filebeat/filebeat -e -c /etc/filebeat/filebeat.yml

---> Running in 253dcfbc0ff7

---> f26910a9c61d

Removing intermediate container 253dcfbc0ff7

Successfully built f26910a9c61d

Filebeat Dockerfile内容

[root@i4t filebeat]# cat Dockerfile

###############################################################################

#                                INSTALLATION

###############################################################################

FROM  docker.io/centos

MAINTAINER www.i4t.com <cyh@i4t.com>

# Install Filebeat

WORKDIR /usr/local

ENV FILEBEAT_VERSION=5.4.0

RUN set -x \

      && curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-${FILEBEAT_VERSION}-linux-x86_64.tar.gz \

      && tar xf filebeat-${FILEBEAT_VERSION}-linux-x86_64.tar.gz -C /usr/local \

      && ln -s /usr/local/filebeat-${FILEBEAT_VERSION}-linux-x86_64 /usr/local/filebeat \

      && chmod +x /usr/local/filebeat/filebeat  \

      && mkdir -p /etc/filebeat

ADD ./docker-entrypoint.sh /usr/bin/

RUN chmod +x /usr/bin/docker-entrypoint.sh

ENTRYPOINT ["docker-entrypoint.sh"]

CMD ["/usr/local/filebeat/filebeat","-e","-c","/etc/filebeat/filebeat.yml"]

######### 脚本内容

[root@i4t filebeat]# cat docker-entrypoint.sh

#!/bin/bash

config=/etc/filebeat/filebeat.yml

env

echo 'Filebeat init process done. Ready for start up.'

echo "Using the following configuration:"

cat /etc/filebeat/filebeat.yml

exec "$@"

## Dockerfile和脚本在同一个目录下,然后进行build

打包完成后我们push到harbor仓库,和tomcat镜像一样的操作

[root@i4t tmp]# docker tag tomcat_filebeat:v2  i4t.com/filebeat/v1

[root@i4t tmp]# docker push i4t.com/filebeat/v1:latest

The push refers to a repository [i4t.com/filebeat/v1]

de0545fc627a: Pushed

8bd9a1a2863c: Pushed

f01cc0f2d07b: Pushed

d69483a6face: Pushed

latest: digest: sha256:03a8f15e28d012eb19aeb29b4920f7ab5df5365054896fa40f83a97aa1cb55cf size: 1155

2.3 Elasticsearch安装

1.JDK环境安装

2.Elasticsearch安装

这里不写了,博客有很多了

参考https://i4t.com/3552.html

服务正常启动即可(我们这里只需要安装es和es-head插件即可,logstash在另外一台)

2.4 kibana安装

https://i4t.com/3552.html

只要服务正常启动,没有报错即可

2.5 测试镜像

这里我们使用k8s环境进行测试,没有搭建k8s可以参考[k8s 1.11源码安装]

tomcat.yaml

[root@yzsjhl82-119 tomcat_test]# cat tomcat_test.yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: tomcat-abcdocker

  namespace: default

spec:

  replicas: 1

  template:

    metadata:

      labels:

        k8s-app: tomcat-web

    spec:

      containers:

      - image: 镜像地址/filebeat/v2

        imagePullPolicy: Always

        name: filebeat

        volumeMounts:

        - name: app-logs

          mountPath: /logs

        - name: filebeat-config

          mountPath: /etc/filebeat/

      - image: 镜像地址/filebeat/tomcat.v1:latest

        name : tomcat-web

        imagePullPolicy: Always

        ports:

        - containerPort: 8080

        volumeMounts:

        - name: app-logs

          mountPath: /usr/local/tomcat/logs

      volumes:

      - name: app-logs

        emptyDir: {}

      - name: filebeat-config

        configMap:

          name: filebeat-config

tomcat_server.xml (端口暴露)

[root@master tomcat_test]# cat tomcat_server.yaml

apiVersion: v1

kind: Service

metadata:

  name: tomcat-web

  labels:

    k8s-app: tomcat-web

spec:

  type: NodePort

  ports:

  - port: 8080

    protocol: TCP

    targetPort: 8080

    name: http

    nodePort: 30001

  selector:

    k8s-app: tomcat-web

configmap.xml

通过configmap的形式创建filebeat.yml配置文件,指定收集日志的路径、elasticsearch的配置信息及索引名称

[root@master tomcat_test]# cat tomcat_configmap.yaml

apiVersion: v1

kind: ConfigMap

metadata:

  name: filebeat-config

data:

  filebeat.yml: |

    filebeat.prospectors:

    - input_type: log

      paths:

        - "/logs/*"

    output.elasticsearch:

      hosts: ["10.4.82.115:9200"]

      index: "filebeat-tomcat-log"

# hosts指定es地址

# index 索引名称

创建索引

[root@master tomcat_test]# kubectl create -f tomcat_configmap.yaml

configmap/filebeat-config created

[root@master tomcat_test]# kubectl create -f tomcat_test.yaml

deployment.extensions/tomcat-abcdocker created

[root@master tomcat_test]# kubectl create -f tomcat_server.yaml

service/tomcat-web created

2.6 服务检查

我们需要检查以下

1.检查pod是否运行正常

2.检查server是否正常

3.检查configmap是否创建完成

4.kubectl常用命令  https://k.i4t.com/15356201695268.html

查看服务整个状态是否正常

[root@master tomcat_test]# kubectl get svc,pod,configmap

NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP  PORT(S)          AGE

service/kubernetes      ClusterIP  10.254.0.1      <none>        443/TCP          97d

service/nginx-service  NodePort    10.254.167.71    <none>        80:31000/TCP    97d

service/tomcat-web      NodePort    10.254.237.208  <none>        8080:30001/TCP  3m

NAME                                    READY    STATUS    RESTARTS  AGE

pod/tomcat-abcdocker-56f9547997-2zz7c  2/2      Running  0          3m

NAME                        DATA      AGE

configmap/filebeat-config  1        3m

查看pod容器是否异常

1.查看tomcat镜像日志

kubectl logs tomcat-abcdocker-56f9547997-2zz7c filebeat

#这里的pod名称可能不是这个

2.查看filebeat镜像日志

kubectl logs tomcat-abcdocker-56f9547997-2zz7c tomcat-web

Kubernetes kubectl 命令自动补全

容器只要没有error报错就ok

Filebaet log

蓝色为ES地址,红色为启动正常

tomcat log

k8s服务是没有问题,我们浏览器访问一下

端口为31000

接下来查看一下es日志

[root@i4t ~]# curl -XGET '10.4.82.115:9200/_cat/indices?v&pretty'

health status index              uuid                  pri rep docs.count docs.deleted store.size pri.store.size

yellow open  filebeat-tomcat-log jRWrRLQjQ2SPTAe-wmy_EA  5  1        272            0    244.6kb        244.6kb

通过head插件查看是否有数据

并且已经实时打印

进入kibana控制台

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,565评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,021评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,003评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,015评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,020评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,856评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,178评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,824评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,264评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,788评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,913评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,535评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,130评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,102评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,334评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,298评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,622评论 2 343

推荐阅读更多精彩内容