Docker初步认识

一、Docker简介

1、Docker是什么?

“Docker 是一个基于Go语言实现的开源应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。” ——百度百科

2、为什么用docker ?

1、加快应用交付速度;
传统的开发过程中,开发、测试、运维是三个独立运作的团队,团队之间沟通不畅,开发运维之间冲突时有发生,导致协作效率低下,产品交付延迟, 影响了企业的业务运行。Docker技术将应用以集装箱的方式打包交付,使应用在不同的团队中共享,通过镜像的方式应用可以部署于任何环境中。
2、系统性能的损耗也要比虚拟机低的多;

3、docker有哪些局限性?

Docker并不是全能的,设计之初也不是KVM之类虚拟化手段的替代品,简单总结几点:

1、Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用
2、LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
3、隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库,(库控制受限:在沙盒里使用它是有风险的。在不知道谁以及如何创建镜像的情况下,可能会存在任意数量的有意或无意的稳定性和安全性风险。)
4、网络管理相对简单,主要是基于namespace隔离
5、cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费)
6、Docker对disk的管理比较有限
7、container随着用户进程的停止而销毁,container中的log等用户数据不便收集;
8、网络限制:网络配置操作是受限的,而且到目前为止可以说这些手段都是人工的。

二、Docker安装和常用命令

1、ubuntu上安装docker:

参考:https://www.cnblogs.com/lighten/p/6034984.html
简单来说下,在ubuntu16.04上安装docker:

1) 确定kernel内核至少要在3.10版本之上:
uname -r
2) 登陆机器,用户必须使用sudo或者root权限:
sudo su
3)更新包信息,确保APT能使用https方式工作,并且CA证书已安装:
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates
4) 添加一个新的GPG密钥:
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
5) 添加apt源:
echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
6) 更新APT包索引:
sudo apt-get update
7)校验APT是从一个正确的仓库拉取安装包:
apt-cache policy docker-engine
8)安装linux-iamge-extra-*的kernel包,这个包允许你使用aufs存储驱动:
sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
9)更新APT包索引:
sudo apt-get update
10)安装docker:
sudo apt-get install docker-engine
11)开启docker后台进程:
sudo service docker start
12)校验docker是否安装成功:
sudo docker run hello-world
2、docker常用命令:

1)基础命令:

docker run 启动容器
docker rm containerId 删除容器
docker ps 可以看到容器的基本信息,其中container ID很重要;(-a 查看所有存在的包括没有启动的容器)
docker exec -it [container id] bash 进入容器内部
docker images 查看镜像

2)docker大扫除:

docker kill $(docker ps -q) ;
docker rm -v $(docker ps -a -q) ;(加上-v会删除没有其它容器连接到该Volume,以及主机目录是也没被指定为Volume)
docker rmi $(docker images -q -a)

3)查看容器重启次数

docker inspect -f "{{ .RestartCount }}" container_name
查看容器最后一次的启动时间
docker inspect -f "{{ .State.StartedAt }}" container_name
查看容器cpu内存占用率
docker stats 容器名  
docker-compose top

4)docker镜像离线使用:

1.将容器做成镜像:
docker commit -m  ""   -a  ""   container_id  image_name (注解:-m 提示信息,-a 作者)
例:docker commit -a "jingchen" faa165fb2a5  my_mongo
2.将镜像本地化:
docker save -o local_file.tar image_name 
例:docker save -o myMongodb.tar my_mongo
3.开发环境导入本地打包的镜像:
docker load -i local_file.tar 
或者
docker load < local_file.tar
例:docker load -i myMongodb.tar

5)查看容器各个命令占用空间:

docker history image_name
3、docker重启策略:
  • no,默认策略,在容器退出时不重启容器
  • on-failure,在容器非正常退出时(退出状态非0),才会重启容器
  • on-failure:3,在容器非正常退出时重启容器,最多重启3次
  • always,在容器退出时总是重启容器
  • unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

三、Docker实现自动化部署

1、思路和主要步骤:

1)确定需要安装的组件;
2)定制化Dockerfile,制作镜像;
3)运行docker

2、Dockerfile案列:

1)Dockerfile内容参考:

#设置继承的镜像
FROM ubuntu:16.04

# 创建者信息
MAINTAINER xianglin.zhou "xianglin.zhou@sihuatech.com"

# 设置环境变量,所有操作都是非交互式的
ENV DEBIAN_FRONTEND noninteractive
# 设置jdk的环境变量
ENV JAVA_HOME /opt/jdk
ENV PATH $JAVA_HOME/bin:$PATH

# 复制tomcat、jdk、redis和nginx.conf配置文件到镜像中
ADD jdk1.8.0_151 /opt/jdk
ADD apache-tomcat-8.5.24 /opt/tomcat-8088
RUN rm -r /opt/tomcat-8088/webapps/ROOT/*
ADD apache-tomcat-8.5.24 /opt/tomcat-8091
RUN rm -r /opt/tomcat-8091/webapps/ROOT/*

#获取宿主机的ip
ADD ip /opt/ip

#修改tomcat端口
RUN rm /opt/tomcat-8088/conf/server.xml \
&& rm /opt/tomcat-8091/conf/server.xml
ADD tomcat_conf/tomcat_8088/server.xml /opt/tomcat-8088/conf
ADD tomcat_conf/tomcat_8091/server.xml /opt/tomcat-8091/conf

ADD nginx.conf /opt

# 将war包发布到tomcat
ADD code/sihuaTech-SYS-Web.war /opt/tomcat-8088/webapps
ADD code/sihuaTech-Qlt-Web.war /opt/tomcat-8091/webapps

#将sql拷贝到容器
ADD psms2.1.sql /opt/psms2.1.sql

#前台包放在/opt下
ADD code/dist /opt/dist

# 复制启动脚本至镜像,并赋予脚本可执行权限
ADD run.sh /opt/run.sh
RUN chmod +x /opt/*.sh \
&& chmod +x /opt/tomcat-8088/bin/*.sh \
&& chmod +x /opt/tomcat-8091/bin/*.sh

#将ubuntu系统默认源改为阿里源
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak
ADD sources.list /etc/apt

# 安装和启动redis
RUN apt-get update && apt-get -y install redis-server

#安装nginx
RUN apt-get update && apt-get -y install nginx \
&& cd /etc/nginx && rm nginx.conf && mv /opt/nginx.conf .

#安装mysql
RUN groupadd -r mysql && useradd -r -g mysql mysql
#将源改回原来的ubuntu源,不然会报错,原因未知
RUN mv /etc/apt/sources.list /etc/apt/sources.list.aliyun \
&& mv /etc/apt/sources.list.bak /etc/apt/sources.list

RUN { \
         echo mysql-server mysql-server/root_password password '123456'; \
         echo mysql-server mysql-server/root_password_again password '123456';\
    } | debconf-set-selections \
    && apt-get update && apt-get install -y mysql-server
#配置mysql.cnf,使其可以远程登录,不区分大小写
RUN  sed -i '40i lower_case_table_names=1' /etc/mysql/mysql.conf.d/mysqld.cnf \
&& sed -i 's/bind-address/#bind-address/g' /etc/mysql/mysql.conf.d/mysqld.cnf

# 暴露tomcat和redis接口
EXPOSE 8088
EXPOSE 8091
EXPOSE 6379
EXPOSE 3306

CMD ["/opt/run.sh"]

2)run.sh内容参考:

#!/bin/bash

set -x
#获取宿主机ip
ip=$(sed -r "s/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\n\1/;s/^.*\n//" /opt/ip)

#修改nginx配置:代理ip
sed -i "s/127.0.0.1/${ip}/g" /etc/nginx/nginx.conf

#重要:给mysql的数据卷重新赋予mysql的用户权限,挂载之后的用户权限会变动
chown mysql:mysql -R /var/lib/mysql/
#启动数据库,并创建数据库
service mysql restart
sleep 2;
#准备数据库脚本(使用数据库,并解决乱码问题)
sed -i '1i\use `psms2.1`;set names utf8;' /opt/psms2.1.sql
MYSQL="mysql -uroot -p123456"
sql_i="GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;"
sql_j="flush privileges;"
#导入mysql数据
sql_creatTable="create DATABASE  if not exists \`psms2.1\` DEFAULT CHARSET UTF8;"
#sql_dropDb="drop DATABASE  if exists \`psms2.1\`;"
#sql_createDb="create DATABASE  if not exists \`psms2.1\` DEFAULT CHARSET UTF8;"
sql_z="exit"
#修改远程登录权限
$MYSQL -e "${sql_i}"
$MYSQL -e "${sql_j}"
$MYSQL -e "${sql_z}"
#创建数据库,并导入数据
$MYSQL -e "${sql_creatTable}"
#判断是否第一次初始化psms2.1数据库数据,文件不存在,则执行sql脚本初始化数据库
if [ ! -f "/var/lib/mysql/psms2@002e1/sys_user.frm" ];then
  echo "init psms2.1!"
  $MYSQL -e "source /opt/psms2.1.sql"
fi
#$MYSQL -e "source /opt/psms2.1.sql"
$MYSQL -e "${sql_z}"

#修改前台代码配置
sed -i "s/localhost/${ip}/g" /opt/dist/static/config.js
#TODO 此处缺省配置视频源ip

#sys项目,8088相关配置
#启动tomcat,自动解压war包
/opt/tomcat-8088/bin/catalina.sh start
#等待sql执行完成,等待war包解压完成
sleep 60
#停止8088服务,以免后面修改文件失败,进程占用冲突
/opt/tomcat-8088/bin/catalina.sh stop
#将项目移动到tomcat/webapps/ROOT下
mv /opt/tomcat-8088/webapps/sihuaTech-SYS-Web/* /opt/tomcat-8088/webapps/ROOT
rm /opt/tomcat-8088/webapps/sihuaTech-SYS-Web.war
rm -r /opt/tomcat-8088/webapps/sihuaTech-SYS-Web
#修改sys项目的相关配置
sed -i 's/10.221.100.115/localhost/g' /opt/tomcat-8088/webapps/ROOT/WEB-INF/classes/config/jdbc.properties
sed -i 's/psms2.1_deploy/psms2.1/g' /opt/tomcat-8088/webapps/ROOT/WEB-INF/classes/config/jdbc.properties
sed  -i 's/^file.wordCreateDir=.*$/file.wordCreateDir=\/opt\/dist\/static\/PSMSFile\/word/' /opt/tomcat-8088/webapps/ROOT/WEB-INF/classes/config/system.properties
sed  -i 's/^file.uploadDir=.*$/file.uploadDir=\/opt\/upload/'  /opt/tomcat-8088/webapps/ROOT/WEB-INF/classes/config/system.properties
#echo "\n"${ip}>> /opt/tomcat-8088/webapps/ROOT/WEB-INF/classes/csrfWhite.txt
sed -i '$a\'${ip}'' /opt/tomcat-8088/webapps/ROOT/WEB-INF/classes/csrfWhite.txt


#qlt项目,8091相关配置
#启动tomcat,自动解压war包
/opt/tomcat-8091/bin/catalina.sh start
#等待sql执行完成,等待war包解压完成
sleep 60
/opt/tomcat-8091/bin/catalina.sh stop
#将项目移动到tomcat/webapps/ROOT下
mv /opt/tomcat-8091/webapps/sihuaTech-Qlt-Web/* /opt/tomcat-8091/webapps/ROOT
rm /opt/tomcat-8091/webapps/sihuaTech-Qlt-Web.war
rm -r /opt/tomcat-8091/webapps/sihuaTech-Qlt-Web
#修改qlt项目的相关配置
sed -i 's/10.221.100.115/localhost/g' /opt/tomcat-8091/webapps/ROOT/WEB-INF/classes/config/jdbc.properties
sed -i 's/psms2.1_deploy/psms2.1/g' /opt/tomcat-8091/webapps/ROOT/WEB-INF/classes/config/jdbc.properties
sed -i '$a\'${ip}'' /opt/tomcat-8091/webapps/ROOT/WEB-INF/classes/csrfWhite.txt


#启动服务
service nginx restart
service redis-server restart
/opt/tomcat-8088/bin/catalina.sh start
/opt/tomcat-8091/bin/catalina.sh start

#保持容器处于任务状态,不然会自动结束容器生命周期
tail -f /opt/tomcat-8088/logs/catalina.out
while true; do sleep 1000; done

#tail -f /var/log/redis/redis-server.log

3)运行docker shell脚本参考:

#!/bin/bash

#自动部署入口脚本

#docker Registry地址
REGISTRY_URL=localhost:5000

#docker工作目录
DOCKERDIR=/opt/workspace/psmsDocker

#进入到docker工作目录
# cd /opt/workspace/psmsDocker

#查询ip并写入ip文件
ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:" |sed  -n '2p' > ip

#检查并启动docker本地仓库容器
if docker ps -a|grep -i myRegistry;then
   echo "myRegistry is running!"
else
   docker run -d -p 5000:5000 -v /root/my_registry:/tmp/registry --name="myRegistry" registry
fi

#删除可能已启动的名为psms的容器
if docker ps -a|grep -i psms;then
   docker rm -f psms
fi


#使用当前目录的Dockerfile创建镜像,命名为docker_psms
docker build -t $REGISTRY_URL/docker_psms .

#给镜像打上Tag
docker tag $REGISTRY_URL/docker_psms v1.0

#(此处需要先启动本地仓库容器,否则将显示connection failed)推送psms镜像到docker远程仓库
docker push $REGISTRY_URL/docker_psms

#启动tomcat容器,容器名为psms
docker run -it -d -p 8088:8088 -p 80:80 -p 3306:3306 -p 8091:8091 --name psms $REGISTRY_URL/docker_psms

#初始化主机挂载卷目录,从容器中拷贝mysql数据到宿主机
if [ ! -d "$DOCKERDIR/mysql" ];then
  echo "$DOCKERDIR/mysql not exited"
  docker cp psms:/var/lib/mysql  $DOCKERDIR
fi

#删除容器,并挂载重新启动
docker rm -f psms
#TODO 重新启动psms,并设置自动重启规则
docker run -it -d --restart=always -p 8088:8088 -p 80:80 -p 3306:3306 -p 8091:8091 --name psms -v $DOCKERDIR/mysql:/var/lib/mysql $REGISTRY_URL/docker_psms

四、Docker进阶

1、三剑客:
1)docker-machine:

docker-machine就是docker公司官方提出的,用于在各种平台上快速创建具有docker服务的虚拟机的技术,甚至可以通过指定driver来定制虚拟机的实现原理(一般是virtualbox)。

2)docker-compose:

dcoker-compose技术,就是通过一个.yml配置文件,将所有的容器的部署方法、文件映射、容器连接等等一系列的配置写在一个配置文件里,最后只需要执行docker-compose up命令就会像执行脚本一样的去一个个安装容器并自动部署他们,极大的便利了复杂服务的部署。

3)docker-swarm:

swarm是基于docker平台实现的集群技术,他可以通过几条简单的指令快速的创建一个docker集群,接着在集群的共享网络上部署应用,最终实现分布式的服务。

相比起zookeeper等集群管理框架来说,swarm显得十分轻量,作为一个工具,它把节点的加入、管理、发现等复杂的操作都浓缩为几句简单的命令,并且具有自动发现节点和调度的算法,还支持自定制。虽然swarm技术现在还不是非常成熟,但其威力已经可见一般。

2、docker-compose详解:
1)安装docker-compose:
注意:安装Docker compose之前需要安装Docker!
1)运行此命令下载Docker组合的最新版本:
sudo curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
2)将可执行权限应用于二进制文件:
sudo chmod +x /usr/local/bin/docker-compose
3)测试安装:
docker-compose --version
4)启动命令:(进入workspace)
docker-compose up
2)docker-compose.yml文件内容参考:
version: '2'  
# 这个version是指dockerfile解析时用的版本,不是给我们自己定义版本号用的.
services: 
  webapp_sys:
    image: tomcat:8
    container_name: sys # 容器名
    depends_on:
        - mysql
        - redis
       # - nginx


    volumes:
       - ./conf/tomcat_8088/server.xml:/usr/local/tomcat/conf/server.xml
       - ./code/SYS:/usr/local/tomcat/webapps/ROOT
    ports:
       - "8088:8088"
    restart: unless-stopped # 容器重启策略
    networks:
       - front-tier
  webapp_qlt:
    image: tomcat:8
    container_name: qlt # 容器名
    depends_on:
       - mysql
       - redis
      # - nginx
    volumes:
       - ./conf/tomcat_8091/server.xml:/usr/local/tomcat/conf/server.xml
       - ./code/Qlt:/usr/local/tomcat/webapps/ROOT
    ports:
       - "8091:8091"
    restart: unless-stopped # 容器重启策略
    networks:
       - front-tier
  redis:
    image: redis
    container_name: redis # 容器名
    restart: unless-stopped # 容器重启策略
    networks:
       - front-tier
    ports:
       - "6379:6379"
  nginx:
    image: nginx
    container_name: nginx # 容器名
    restart: unless-stopped # 容器重启策略
    ports:
       - "80:80"
    volumes:
       - ./code/web:/opt
       - ./conf/nginx.conf:/etc/nginx/nginx.conf
    networks:
       - front-tier
  mysql:  
    build: ./mysql
    container_name: mysql # 容器名  
    restart: unless-stopped # 容器重启策略
    volumes:  
      - ./mysql/dbdata:/var/lib/mysql # 挂载数据到主机
      - ./mysql/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf # 设置不区分大小写,屏蔽只允许本地ip访问
    ports:  
       - "3306:3306"  
    environment:  
      MYSQL_USER: root  
      MYSQL_PASSWORD: 123456  
      MYSQL_ROOT_PASSWORD: 123456  
    networks:  
      - front-tier 
networks:
  front-tier:
    driver: bridge
3)运行docker-compose脚本参考:
#!/bin/bash

#linux shell 脚本编写好要经过漫长的调试阶段,可以使用sh -x 执行
set -x
#查询ip并写入ip文件
ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:" |tail -n 1 > ip
#获取宿主机ip
ip=$(sed -r "s/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\n\1/;s/^.*\n//" ./ip)
echo ${ip}

#war解压目录
SYSDIR=./code/SYS
QltDIR=./code/Qlt

#需要判断是否已经解压
if [ ! -f "$SYSDIR/index.jsp" ];then
  unzip ./code/sihuaTech-SYS-Web.war -d $SYSDIR
else
  echo "SYSDIR have been ziped!"
fi

if [ ! -d "$QltDIR/WEB-INF" ];then
  unzip ./code/sihuaTech-Qlt-Web.war -d $QltDIR
else
  echo "QltDIR have been ziped!"
fi

#修改sys项目的相关配置
#此处需要换成宿主机ip
sed -i 's/10.221.100.115/'${ip}'/g' $SYSDIR/WEB-INF/classes/config/jdbc.properties
# redis需要换成宿主机ip,所以需要暴露端口
sed -i "s/127.0.0.1/${ip}/g" $SYSDIR/WEB-INF/classes/config/system.properties

sed -i 's/psms2.1_deploy/psms2.1/g' $SYSDIR/WEB-INF/classes/config/jdbc.properties
sed -i 's/^file.wordCreateDir=.*$/file.wordCreateDir=\/opt\/dist\/static\/PSMSFile\/word/' $SYSDIR/WEB-INF/classes/config/system.properties
sed -i 's/^file.uploadDir=.*$/file.uploadDir=\/opt\/upload/'  $SYSDIR/WEB-INF/classes/config/system.properties
sed -i '$a\'${ip}'' $SYSDIR/WEB-INF/classes/csrfWhite.txt

#nginx容器跨域请求
#sed -i '$a\172.19.0.233' $SYSDIR/WEB-INF/classes/csrfWhite.txt

#修改qlt项目的相关配置
#此处需要换成宿主机ip
sed -i 's/10.221.100.115/'${ip}'/g' $QltDIR/WEB-INF/classes/config/jdbc.properties
# redis需要换成宿主机ip,所以需要暴露端口
sed -i "s/127.0.0.1/${ip}/g" $QltDIR/WEB-INF/classes/config/system.properties

sed -i 's/psms2.1_deploy/psms2.1/g' $QltDIR/WEB-INF/classes/config/jdbc.properties
sed -i '$a\'${ip}'' $QltDIR/WEB-INF/classes/csrfWhite.txt

#nginx跨域请求
#sed -i '$a\172.19.0.233' $QltDIR/WEB-INF/classes/csrfWhite.txt

echo "后台配置完成!"


#修改前台的相关配置
#修改nginx配置:代理ip
sed -i "s/127.0.0.1/${ip}/g" ./conf/nginx.conf
sed -i "s/localhost/${ip}/g" ./code/web/dist/static/config.js
#TODO 此处缺省配置视频源ip

echo "前台配置完成!"
#拉去依赖的所有镜像
docker-compose pull

docker-compose build

#启动docker compose
#使用 --force-recreate 可以强 制重建容器 (否则只能在容器配置有更改时才会重建容器)
docker-compose up -d --force-recreate
4)docker-compose常用命令:
docker-compose up   启动docker-compose项目;
docker-compose logs 查看日志;
docker-compose exec container_name bash   进入到compose里面的某个容器;
docker-compose stop   停止docker-compose;

五、遇到问题及解决办法:

1、docker pull镜像超时:(切换国内镜像)
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://ef017c13.m.daocloud.io
然后再重启:
systemctl restart docker

参考网址:

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

推荐阅读更多精彩内容