Docker容器详解(4)

容器

容器是Docker的另一个核心概念。
简单的说,容器是镜像的一个运行实例,所不同的是,它带有额外的可写入层。
如果认为虚拟机是模拟运行的一套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。那么Docker容器就是独立运行的一个或一组应用。以及它们的必须运行环境。

本篇文章具体介绍围绕容器的重要操作,包括创建一个容器,启动容器,停止一个容器,进入容器进行具体的操作,删除容器和通过导入容器来实现容器容器的迁移

4.1 创建容器

Docker的容器十分轻量级,用户可以随时创建或删除容器。

新建容器

可以使用docker create 命令创建一个新的容器,例如:

[root@private_vpn ~]# docker pull centos
Using default tag: latest
Trying to pull repository docker.io/library/centos ... 
latest: Pulling from docker.io/library/centos
d9aaf4d82f24: Pull complete 
Digest: sha256:4565fe2dd7f4770e825d4bd9c761a81b26e49cc9e3c9631c58cfc3188be9505a
[root@private_vpn ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    latest              d123f4e55e12        3 weeks ago         196.6 MB
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@private_vpn ~]# docker create -it d123
480b9fb36e0dc83bf2072d96c909f33a9a6ae5dedc18d30d994228ab50880e4e
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
480b9fb36e0d        d123                "/bin/bash"         7 seconds ago       Created                                 goofy_raman
4.2 容器的启动
启动容器(方式一)

此时创建的容器处于停止状态,可以使用docker start 容器ID命令来启动它。

[root@private_vpn ~]# docker start 480
480
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
480b9fb36e0d        d123                "/bin/bash"         2 minutes ago       Up 4 seconds                            goofy_raman

对比容器启动前后的STATUS状态则可以看出容器现在已经在运行了。

启动容器(方式二)

容器的启动有2种方式,一种是基于镜像创建容器并启动,如上面所讲。另一种是将终止(stopped)状态的容器重启启动。所需要的主要命令是docker run,等价于先执行docker create 镜像ID再执行docker start 容器ID

例如,下面的命令输出一个"hello,world!"后自动终止运行。

[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
480b9fb36e0d        d123                "/bin/bash"         15 minutes ago      Exited (0) 8 minutes ago                       goofy_raman
[root@private_vpn ~]# docker run centos /bin/echo "hello,world"
hello,world
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
7ef6cbb4b7f9        centos              "/bin/echo hello,worl"   4 seconds ago       Exited (0) 3 seconds ago                       gloomy_bardeen
480b9fb36e0d        d123                "/bin/bash"              15 minutes ago      Exited (0) 8 minutes ago                       goofy_raman

可以看到输出了"hello,world"的容器的STATUS是Exited (0) 3 seconds ago,此处也可以看到我之前用第一种方式启动的容器也是处于Exited状态了,这是因为我用docker attach 480进入容器后又exit退出了,所以显示这个容器也是exit状态,此处可以先不看这个。后面会细讲。

现在回到我们说的第二种启动容器的上来。
这跟在本地直接执行/bin/echo "hello world" 几乎感觉不出有任何区别。

当利用docker run来创建并启动容器时,Docker在后台运行的标准操作包括:

  1. 检查本地是否存在指定的镜像,不存在就从公有仓库下载。
  2. 利用镜像创建并启动一个容器。
  3. 分配一个文件系统,并在只读的镜像层外面挂在一层可读写层。
  4. 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去。
  5. 从地址池配置一个IP地址给容器。
  6. 执行用户指定的应用程序。
  7. 执行完毕后容器被终止。

当然我们也可以加些参数允许我们可以和容器进行交互。

[root@private_vpn ~]# docker run   -t -i  d123f4e55e12  /bin/bash
[root@a2328599c69d /]# ls -l /tmp/
total 4
-rwx------ 1 root root 836 Sep 11 15:53 ks-script-q6TWGF
-rw------- 1 root root   0 Sep 11 15:51 yum.log
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a2328599c69d        d123f4e55e12        "/bin/bash"         16 seconds ago      Up 15 seconds                           determined_cray

其中参数-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,参数-i则让容器的标准输入保持打开。
在交互式模式下,用户可以通过所创建的伪终端来输入命令,如上所示的ls -l /tmp
在容器内执行ps -ef可以看到如下结果

[root@a2328599c69d /]# ps -ef 
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 16:40 ?        00:00:00 /bin/bash
root        14     1  0 16:44 ?        00:00:00 ps -ef

容器只运行了bash应用,并没有运行其他不需要的进程。

[root@a2328599c69d /]# exit
exit
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
a2328599c69d        d123f4e55e12        "/bin/bash"         7 minutes ago       Exited (0) 4 seconds ago                       determined_cray

对于所创建的bash容器,当使用exit命令退出之后,该容器就自动处于终止状态了。这是因为对于Docker容器来说,当运行的应用(此处例子是bash)退出后,容器也就没有运行下去的必要了。
这也是上面说到的创建容器然后启动容器,再进入容器,最后exit退出后,容器的STATUS显示Exited

守护态运行
更多的时候,需要让Docker容器在后台以守护态(Daemonized)形式运行。
使用 -d参数

[root@private_vpn ~]# docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx             latest              9e7424e5dbae        7 days ago          108.5 MB
docker.io/nuagebec/ubuntu   latest              7c2ea61fd57e        12 days ago         329.4 MB
docker.io/centos            latest              d123f4e55e12        3 weeks ago         196.6 MB
[root@private_vpn ~]# 
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
d1311a650a77        nginx               "nginx -g 'daemon off"   About an hour ago   Up About an hour    0.0.0.0:80->80/tcp   webserver
6935f8fff19c        d123f4e55e12        "/bin/bash"              4 days ago          Up 24 hours                              grave_pasteur
[root@private_vpn ~]# 
[root@private_vpn ~]# 
[root@private_vpn ~]# docker run -tid 7c2ea61fd57e /bin/bash
be037923b36fc1731a4a3abf36973c772efe1289d47f612fc2c083b5b017c647
[root@private_vpn ~]# 
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
be037923b36f        7c2ea61fd57e        "/bin/bash"              7 seconds ago       Up 6 seconds        22/tcp               cocky_blackwell
d1311a650a77        nginx               "nginx -g 'daemon off"   About an hour ago   Up About an hour    0.0.0.0:80->80/tcp   webserver
6935f8fff19c        d123f4e55e12        "/bin/bash"              4 days ago          Up 24 hours                              grave_pasteur

新创建的容器(ID:be037923b36f )此时已经放入后台运行,STATUS可以看出。

4.3 容器的停止

可以使用docker stop 来终止一个运行中的容器。此命令格式:
docker stop [-t | --time [=10] ] [container...]
首先向容器发送sigterm信号,等待一端超时时间(默认是10s)后,再发送sigkill信号来终止容器:

[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
be037923b36f        7c2ea61fd57e        "/bin/bash"              14 minutes ago      Up 14 minutes       22/tcp               cocky_blackwell
d1311a650a77        nginx               "nginx -g 'daemon off"   About an hour ago   Up About an hour    0.0.0.0:80->80/tcp   webserver
6935f8fff19c        d123f4e55e12        "/bin/bash"              4 days ago          Up 24 hours                              grave_pasteur
[root@private_vpn ~]# 
[root@private_vpn ~]# docker stop be
be
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                NAMES
be037923b36f        7c2ea61fd57e        "/bin/bash"              14 minutes ago      Exited (0) 2 seconds ago                        cocky_blackwell
d1311a650a77        nginx               "nginx -g 'daemon off"   About an hour ago   Up About an hour           0.0.0.0:80->80/tcp   webserver
6935f8fff19c        d123f4e55e12        "/bin/bash"              4 days ago          Up 24 hours                                     grave_pasteur

容器的重启
docker restart container
此命令会将一个运行态的容器先停止,然后再重新启动它。

4.4 进入容器

使用-d参数时,容器启动后会进入后台,用户无法看到容器中的信息,也无法进行操作。这个时候如果需要进入容器进行操作,有多种方法,包括使用官方的attach或exec命令,以及第三方的nsenter工具等,下面分别介绍一下。

1. attach命令

attach是docker自带的命令,命令格式为:
docker attach [--detach-keys[=[]]] [--no-stdin] [--sig-proxy [=true]] container
示例:

[root@private_vpn ~]# docker run -itd ubuntu
e41d5b8cdc4705622fc05b334717911a0e3afa1287aabf0462f795ec3332ef3d
[root@private_vpn ~]# 
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS                NAMES
e41d5b8cdc47        ubuntu              "/bin/bash"              5 seconds ago       Up 4 seconds                                         grave_heisenberg
7d265677e942        ubuntu              "/bin/bash"              4 minutes ago       Exited (0) About a minute ago                        dreamy_chandrasekhar
9fe70e55acad        ubuntu              "/bin/bash"              4 minutes ago       Exited (127) 4 minutes ago                           prickly_sinoussi
be037923b36f        7c2ea61fd57e        "/bin/bash"              About an hour ago   Up 20 minutes                   22/tcp               cocky_blackwell
d1311a650a77        nginx               "nginx -g 'daemon off"   2 hours ago         Up 2 hours                      0.0.0.0:80->80/tcp   webserver
6935f8fff19c        d123f4e55e12        "/bin/bash"              4 days ago          Up 25 hours                                          grave_pasteur
[root@private_vpn ~]# 
[root@private_vpn ~]# docker attach grave_heisenberg
root@e41d5b8cdc47:/# 
root@e41d5b8cdc47:/# ls -l
total 12
drwxr-xr-x   2 root root 4096 Nov 14 13:49 bin
...
root@e41d5b8cdc47:/# exit
exit
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS                NAMES
e41d5b8cdc47        ubuntu              "/bin/bash"              50 seconds ago      Exited (0) 1 seconds ago                             grave_heisenberg
7d265677e942        ubuntu              "/bin/bash"              4 minutes ago       Exited (0) About a minute ago                        dreamy_chandrasekhar
9fe70e55acad        ubuntu              "/bin/bash"              5 minutes ago       Exited (127) 4 minutes ago                           prickly_sinoussi
be037923b36f        7c2ea61fd57e        "/bin/bash"              About an hour ago   Up 21 minutes                   22/tcp               cocky_blackwell
d1311a650a77        nginx               "nginx -g 'daemon off"   2 hours ago         Up 2 hours                      0.0.0.0:80->80/tcp   webserver
6935f8fff19c        d123f4e55e12        "/bin/bash"              4 days ago          Up 25 hours                                          grave_pasteur

但是使用attach命令有时候不方便,当多个窗口同时使用attach命令连接到同一个容器的时候,所有窗口都会同步显示,当某个窗口命令阻塞时,其他窗口也无法执行操作。根据上面的示例我们也可以看到当使用attach进入到容器后,再执行exit退出容器后可以看到容器已处于停止运行状态。

2. exec命令

docker从1.3.0版本开始就提供了一个更加方便的exec命令,可以在容器内直接执行任意命令。该命令的基本格式为:
docker exec [-d|--detach] [--detach-keys[=[]]] [-i|--interactive] [--priveleged] [-t|--tty] [-u|--user[=USER]] container command [arg...]
比较重要的参数有:
-i,--interactive=true|false:打开标准输入接受用户输入命令,默认为false;
--privileged=true|false:是否给执行命令以高权限,默认为false;
-t,--tty=true|false:分配伪终端,默认为false
-u,--user="":执行命令的用户名或ID
例如进入到刚创建的容器中,并启动一个bash

[root@private_vpn ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
be037923b36f        7c2ea61fd57e        "/bin/bash"              About an hour ago   Up About an hour    22/tcp               cocky_blackwell
d1311a650a77        nginx               "nginx -g 'daemon off"   2 hours ago         Up 2 hours          0.0.0.0:80->80/tcp   webserver
6935f8fff19c        d123f4e55e12        "/bin/bash"              4 days ago          Up 26 hours                              grave_pasteur
[root@private_vpn ~]# docker exec -it d1  /bin/bash
root@d1311a650a77:/# ls -l                                                                                                                                                
total 12
drwxr-xr-x   2 root root 4096 Oct  9 00:00 bin
...
  1. nsenter工具
    在util-linux软件包版本2.23+中包含nsenter工具。如果系统中的util-linux包没有该命令,可以按照下面的方法从源码安装:
    注:我的测试机已经有了此工具,所以此处不再做实验,只贴上方法,自己验证。
cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf -; cd util-linux-2.24;
./configure --without-nucrses
make nsenter && cp nsenter /usr/local/bin

为了使nsenter连接到容器,还需要找到容器进程的PID,可以通过下面的命令获取:

PID=$(docker inspect --format "{{ .State.Pid }}" <container>)

通过这个PID,就可以连接到这个容器:
nsenter --target $PID --mount --uts --ipc --net --pid
eg:

[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
cf5de6a10e7c        centos6:0.2         "/bin/bash"         18 minutes ago      Up 18 minutes       0.0.0.0:80->80/tcp   webserver02
78b0969bc01a        centos6:0.2         "/bin/bash"         About an hour ago   Up About an hour    0.0.0.0:81->80/tcp   webserver03
6935f8fff19c        d123f4e55e12        "/bin/bash"         10 days ago         Up 7 days                                grave_pasteur
[root@private_vpn ~]# 
[root@private_vpn ~]# PID=$(docker inspect --format "{{ .State.Pid }}" 6935 ) && echo $PID
11751
[root@private_vpn ~]# nsenter --target 11751 --mount --uts --ipc --net --pid
[root@6935f8fff19c /]# ls -l
total 24
-rw-r--r--   1 root root 15836 Sep 11 15:53 anaconda-post.log
......

此方式exit退出容器时也不会停止容器。

4.5 删除容器

可以使用docker rm命令来删除处于中止或退出状态的容器,命令格式为:
docker rm [-f|--force] [-l|--link] [-v|--volumes] container [container ...]

主要支持的选项包括:

  • -f,--force=false: 是否强行中止并删除一个运行中的容器
  • -l,--link=false: 删除容器的连接,但保留容器
  • -v,--volumes: 删除容器挂载的数据卷
    eg:
    删除处于停止状态的容器,并删除:
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS                NAMES
13c6d062dd37        20                  "/bin/bash"         11 seconds ago      Exited (0) 6 seconds ago                        drunk_hawking
cf5de6a10e7c        centos6:0.2         "/bin/bash"         31 minutes ago      Up 31 minutes              0.0.0.0:80->80/tcp   webserver02
78b0969bc01a        centos6:0.2         "/bin/bash"         About an hour ago   Up About an hour           0.0.0.0:81->80/tcp   webserver03
6935f8fff19c        d123f4e55e12        "/bin/bash"         10 days ago         Up 7 days                                       grave_pasteur
[root@private_vpn ~]# 
[root@private_vpn ~]# docker rm 13
13
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
cf5de6a10e7c        centos6:0.2         "/bin/bash"         32 minutes ago      Up 32 minutes       0.0.0.0:80->80/tcp   webserver02
78b0969bc01a        centos6:0.2         "/bin/bash"         About an hour ago   Up About an hour    0.0.0.0:81->80/tcp   webserver03
6935f8fff19c        d123f4e55e12        "/bin/bash"         10 days ago         Up 7 days                                grave_pasteur

默认情况下,docker rm 命令只能删除处于停止状态的容器,并不能删除还处于运行状态的容器。
如果一定要直接删除一个正在运行中的容器,可以加-f 参数。docker 会先发送sigkill信号给容器,终止其中的应用,之后强行删除,这个在前面的文章中已经讲过,此处不再赘述。

4.6 导入和导出容器

某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用docker的导入和导出功能。这也是docker自身提供的一个重要特性。

1. 导出容器

导出容器是指导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态,可以使用docker export命令,该命令的格式为docker export [-o|--output [=""]] container。其中,可以通过-o选项来指定导出的tar文件名,也可以直接通过重定向来实现。

首先查看所有的容器,如下所示:

[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
cf5de6a10e7c        centos6:0.2         "/bin/bash"         49 minutes ago      Up 49 minutes       0.0.0.0:80->80/tcp   webserver02
78b0969bc01a        centos6:0.2         "/bin/bash"         About an hour ago   Up About an hour    0.0.0.0:81->80/tcp   webserver03
6935f8fff19c        d123f4e55e12        "/bin/bash"         10 days ago         Up 7 days                                grave_pasteur

现在导出容器"cf5de6a10e7c"到文件webserver02.tar:
先进入容器并创建一个文件写入内容,以便测试。

[root@private_vpn ~]# docker exec -ti cf5 /bin/bash
[root@cf5de6a10e7c /]# cd /tmp/
[root@cf5de6a10e7c tmp]# echo "test" >> test.txt

然后导出容器:

[root@private_vpn ~]# docker export -o webserver02.tar cf5
[root@private_vpn ~]# ls -l
-rw------- 1 root root  990253056 Dec  9 17:55 webserver02.tar

之后就可以将导出的tar文件传输到其他服务器上,然后再通过导入命令导入到系统中,从而实现容器的迁移。

2.容器的迁移

导出的文件又可以使用docker import命令导入变成镜像,该命令格式为:
docker import [-c|--change [=[]]] [-m|--message [=MESSAGE]] file|URL| -[repository[:tag]]
用户可以通过-c,--change=[]选项在导入的同时执行对容器进行修改的Dockerfile指令(此处后面会讲到)。

下面将导出的webserver02.tar文件导入到系统中:

[root@private_vpn ~]# cat webserver02.tar | docker import - webserver:v0.21
sha256:e230d26d7671212bdd89dcd4373f32fe266c9dd7ae7d3419ef38300a3c9213ed
[root@private_vpn ~]# docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
webserver                   v0.21               e230d26d7671        6 seconds ago       967.9 MB
centos6.8                   0.21                7e48bfa0489e        28 hours ago        1.052 GB
centos6                     0.2                 9ceeba2e3b82        3 days ago          990.2 MB
centos6                     0.1                 d8af0a913398        3 days ago          824.6 MB

现在基于e230d镜像创建一个容器并进入查看/tmp/test.txt文件

[root@private_vpn ~]# docker run -tid e23 /bin/bash
2717b6b2c5ae80038872c5e23ed4901a899783aa77f2af205d1337a470a70413
[root@private_vpn ~]# 
[root@private_vpn ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
2717b6b2c5ae        e23                 "/bin/bash"         7 seconds ago       Up 7 seconds                             focused_ritchie
cf5de6a10e7c        centos6:0.2         "/bin/bash"         2 days ago          Up 2 days           0.0.0.0:80->80/tcp   webserver02
78b0969bc01a        centos6:0.2         "/bin/bash"         2 days ago          Up 2 days           0.0.0.0:81->80/tcp   webserver03
[root@private_vpn ~]# 
[root@private_vpn ~]# docker exec -ti 2717 /bin/bash
[root@2717b6b2c5ae /]# cat /tmp/test.txt 
test

可以看到test.txt文件是存在且内容相同,测试成功。

之前镜像章节中曾介绍过使用docker load命令来导入一个镜像文件,与docker import命令十分相似

实际上,既可以使用docker load命令来导入镜像存储文件到本地镜像库,也尅一使用docker import命令来导入一个容器快照到本地镜像库

这两者的区别在于容器快照将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息

小结:
容器是直接提供应用服务的组件,也是docker实现快速启停和高效服务性能的基础。
在生产环境中,因为容器自身的轻量级特性,推荐在使用容器时在一组容器前引入HA(High Availability)机制。例如使用HAProxy工具来代理容器访问,这样在容器出现故障时,可以快速切换到功能正常的容器(前提是,如果这些容器跑在同一宿主机时,宿主机不出现故障)。此外,建议通过合适的容器重启策略,来自动重启退出的容器。

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

推荐阅读更多精彩内容