第四章 Kubernetes入门及集群搭建

学习目标:

  1. 了解 Kubernetes 的起源和发展

  2. 掌握如何使用 kubeadm搭建 Kubernetes 集群

  3. 查看 Kubernetes 集群部署状态


4-1 Kubernetes的起源和发展

Kubernetes 的起源

  • Kubernetes最初源于谷歌内部的Borg,Kubernetes 的最初目标是为应用的容器化编排部署提供一个最小化的平台,包含几个基本功能:
  1. 将应用水平扩容到多个集群

  2. 为扩容的实例提供负载均衡的策略

  3. 提供基本的健康检查和自愈能力

  4. 实现任务的统一调度

Kubernetes 的发展

  • 2014年6月 谷歌云计算专家Eric Brewer在旧金山的发布会为这款新的开源工具揭牌。

  • 2015年7月22日K8S迭代到 v 1.0并在OSCON大会上正式对外公布。

  • 为了建立容器编排领域的标准和规范,Google、RedHat 等开源基础设施领域玩家们,在 2015 年共同牵头发起了名为 CNCF(Cloud Native Computing Foundation)的基金会。Kubernetes 成为 CNCF 最核心的项目。发起成员:AT&T, Box, Cisco, Cloud Foundry Foundation, CoreOS, Cycle Computing, Docker, eBay, Goldman Sachs, Google, Huawei, IBM, Intel, Joyent, Kismatic, Mesosphere, Red Hat, Switch SUPERNAP, Twitter, Univa, VMware and Weaveworks。

  • 2018年,超过 1700 开发者成为 Kubernetes 项目社区贡献者,全球有 500 多场沙龙。国内出现大量基于 Kubernetes 的创业公司。

  • 2020 年,Kubernetes 项目已经成为贡献者仅次于 Linux 项目的第二大开源项目。成为了业界容器编排的事实标准,各大厂商纷纷宣布支持 Kubernetes 作为容器编排的方案。


4-2 为什么需要 Kubernetes?

传统的容器编排痛点

容器技术虽然解决了应用和基础设施异构的问题,让应用可以做到一次构建,多次部署,但在复杂的微服务场景,单靠 Docker 技术还不够,它仍然有以下问题没有解决:

  • 集成和编排微服务模块

  • 提供按需自动扩容,缩容能力

  • 故障自愈

  • 集群内的通信

Kubernetes 能解决的问题

  • 按需的垂直扩容,新的服务器(node)能够轻易的增加或删除

  • 按需的水平扩容,容器实例能够轻松扩容,缩容

  • 副本控制器,你不用担心副本的状态

  • 服务发现和路由

  • 自动部署和回滚,如果应用状态错误,可以实现自动回滚

什么时候使用 Kubernetes?

  • 当你的应用是微服务架构

  • 开发者需要快速部署自己的新功能到测试环境进行验证

  • 降低硬件资源成本,提高使用率

什么时候不适合使用 Kubernetes

  • 应用是轻量级的单体应用,没有高并发的需求
  • 团队文化不适应变革

4-3 Kubernetes 的架构和核心概念

image

主控制节点组件

主控制节点组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。

主控制节点组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有主控制节点组件,并且不会在此计算机上运行用户容器。

  • apiserver 主节点上负责提供 Kubernetes API 服务的组件;它是 Kubernetes 控制面的前端组件。

  • etcd etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。

  • kube-scheduler 主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。 调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。

  • kube-controller-manager 在主节点上运行控制器的组件。 从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:

  1. 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。

  2. 副本控制器(Replication Controller): 负责为系统中的每个副本控制器对象维护正确数量的 Pod。

  3. 终端控制器(Endpoints Controller): 填充终端(Endpoints)对象(即加入 Service 与 Pod)。

  4. 服务帐户和令牌控制器(Service Account & Token Controllers),为新的命名空间创建默认帐户和 API 访问令牌.

从节点组件

节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。

  • kubelet 一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。

kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。kubelet 不会管理不是由 Kubernetes 创建的容器。

  • kube-proxy kube-proxy 是集群中每个节点上运行的网络代理,实现 Kubernetes Service 概念的一部分。 kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。
  • 容器运行时(Container Runtime) 容器运行环境是负责运行容器的软件。 Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI (容器运行环境接口)。

插件(Addons)

  • DNS 尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该有集群 DNS, 因为很多示例都需要 DNS 服务。

  • Web 界面(仪表盘) Dashboard 是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除。

  • 容器资源监控 容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。

  • 集群层面日志 集群层面日志 机制负责将容器的日志数据 保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。


4-4 Kubernetes 的部署方案介绍

部署目标

  • 在所有节点上安装Docker和kubeadm

  • 部署Kubernetes Master

  • 部署容器网络插件

部署架构

image.png

环境准备

  • 3台虚拟机CentOS7.x-86_x64

  • 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多

  • 集群中所有机器之间网络互通

  • 可以访问外网,需要拉取镜像

  • 禁止swap分区


4-5 Virtualbox 虚拟机配置双网卡实现固定IP

  • Virtualbox安装 CentOS

  • 配置虚机双网卡,实现固定 IP,且能访问外网 网卡 1: 仅主机host-only 网卡 2: 网络转换地址NAT 查看虚拟机网络,点击管理—>主机网络管理器,记住ip地址(192.168.99.1),并选择“手动配置网卡”。

  • 重启虚拟机,此时在虚拟机 ping www.baidu.com 是返回成功的。

  • 设置外部网络访问虚拟机 设置静态ip地址,编辑网络配置文件,编辑网络设置文件

vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
#BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp0s3
UUID=08012b4a-d6b1-41d9-a34d-e0f52a123e7a
DEVICE=enp0s3
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.99.101
  • 重启网络

systemctl restart network

  • 查看 enp0s3 网卡的 ip
[root@localhost Final]#ip addr |grep 192
inet 192.168.99.101/24 brd 192.168.99.255 scope global noprefixroute enp0s3
  • 此时虚拟机既可以访问外网,也能够和宿主机( 192.168.31.178)进行通信
ping 192.168.31.178
PING 192.168.31.178 (192.168.31.178): 56 data bytes
64 bytes from 192.168.31.178: icmp_seq=0 ttl=64 time=0.060 ms
  • 使用iTerm2 连接虚拟机

4-6 Master节点安装 kubeadm, kubelet and kubectl

  • 配置 Master 和 work 节点的域名
vim /etc/hosts
192.168.56.101 master
192.168.56.102 node1
192.168.56.103 node2
  • 设置域名解析服务器
vi /etc/resolv.conf
# Generated by NetworkManager
search lan
nameserver 114.114.114.114
image

剩余步骤可通过这个脚本执行:

base_install.sh

  • 下载阿里云的yum源:

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

  • 安装基本软件包

yum install wget net‐tools ntp vim bash‐comp* ‐y

  • 同步系统时间

ntpdate 0.asia.pool.ntp.org

  • 将桥接的IPv4流量传递至iptables的链
[root@master ~]# modprobe br_netfilter
[root@master ~]# echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
[root@master ~]# vi /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
image
  • 关闭 防火墙
systemctl stop firewalld
systemctl disable firewalld
  • 关闭 SeLinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

也可以修改 /etc/selinux/config 文件,如图片中所示

image
  • 关闭 swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab

也可以直接编辑 /etc/fstab 文件注释掉图片的内容

image
  • free -m 发现swap全为0表示设置成功
image
  • 设置主机名,管理节点设置主机名为master
[root@master ~]# hostnamectl set-hostname master
[root@master ~]# su ‐
  • 配置Docker, K8S的阿里云yum源
[root@master ~]# cat >>/etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
[root@master ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
[root@master ~]# yum repolist
  • 安装并启动 docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum -y install docker-ce

mkdir /etc/docker

cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6yus5ux3.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

如果报错如下,则重新下载
wget -O /etc/yum.repos.d/CentOS-Base.repo [http://mirrors.aliyun.com/repo/Centos-7.repo](http://mirrors.aliyun.com/repo/Centos-7.repo)

image

如果还不行就使用以下脚本:

curl -fsSL get.docker.com -o get-docker.sh
bash get-docker.sh
  • 编辑/usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
# Restart Docker
systemctl daemon-reload
systemctl enable docker
systemctl restart docker

此时查看 docker info,可以看到默认 Cgroup Driversystemd

  • 卸载旧版本

yum remove -y kubelet kubeadm kubectl

  • 安装kubelet、kubeadm、kubectl

yum install -y kubelet kubeadm kubectl

  • 重启 docker,并启动 kubelet

systemctl enable kubelet && systemctl start kubelet

之后便可给Master节点打上快照,然后worker节点便可用这个快照进行构建。


4-8 初始化Master 节点

  • 设置主机名,管理节点设置主机名为master
[root@master ~]# hostnamectl set-hostname master
[root@master ~]# su ‐
  • 将桥接的IPv4流量传递到iptables的链
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
vi /etc/sysctl.d/k8s.conf 
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

剩余操作可通过以下脚本执行:注意修改版本和节点地址

init_master.sh

image
  • 初始化主节点
kubeadm init --kubernetes-version=1.23.1 \
--apiserver-advertise-address=192.168.56.101 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
  • 初始化完成后记住图片中的内容(token),用于node节点的搭建
kubeadm join 192.168.56.101:6443 --token j0tuuf.p635m3gjlcn3d2w7 \
        --discovery-token-ca-cert-hash sha256:b072d61cbfe86def68800a610e2f9eac45c34e83a55c6dab14691bf8a64cd4c1
image
  • 检查节点信息
NAME     STATUS     ROLES                  AGE     VERSION
master   NotReady   control-plane,master   6m26s   v1.23.1
  • 安装网络插件 Flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml<
kubectl apply -f kubeblog/docs/Chapter4/flannel.yaml
image

这个文件将flannel镜像上传到了dockerhub https://hub.docker.com/repository/docker/wangqingjiewa/flannel

  • 查看kube-system状态
[root@master ~]# kubectl get po -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-6d8c4cb4d-r7q7n          1/1     Running   0          17m
coredns-6d8c4cb4d-sfqlb          1/1     Running   0          17m
etcd-master                      1/1     Running   0          18m
kube-apiserver-master            1/1     Running   0          18m
kube-controller-manager-master   1/1     Running   0          18m
kube-flannel-ds-chd2n            1/1     Running   0          101s
kube-proxy-p42n2                 1/1     Running   0          17m
kube-scheduler-master            1/1     Running   0          18m
  • 查看master节点状态已经是ready
[root@master ~]# kubectl get node
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   21m   v1.23.1
  • 查看是否成功创建flannel网络

ifconfig |grep flannel

报错处理

  • 如果出现“node 'master' not found”错误
# 检查权限
chmod 777 /run/flannel/subnet.env
  • 如果flannel pod启动失败,执行以下命令查看报错信息
kubectl describe pod kube-flannel-ds-xxx -n kube-system
  • 如果是镜像拉取失败,可尝试修改 quay.io 的镜像路径。可以执行以下命令,并将结果保存至flannel.yml,修改 quay.io 的镜像路径,再执行delete和create操作
kubectl get pod kube-flannel-ds-xx -n kube-system -o yaml
kubectl delete -f flannel.yaml
kubectl create -f flannel.yaml
  • 查看运行的Kubernetes组件

docker ps

如果出现“The connection to the server 192.168.56.101:6443 was refused - did you specify the right host or port?"错误

先执行: kubectl get po -n kube-system ,查看所有服务是否正常启动,如果某个服务启动失败,则执行

kubectl describe pod <pod name> -n kube-system

查看错误原因。

  • 重置 kubeadm

kubeadm reset


4-9 安装配置 worker Node节点

  • 初始虚拟机,Centos,配置双网卡
    image
    image

    注意 clone snapshot 虚拟机时,选择Generate new MAC address

  • ssh 免密登录

  • 设置 ip 地址为 192.168.99.102

  • 配置域名

hostnamectl set-hostname node1
vi /etc/hosts
192.168.99.101 master
192.168.99.102 node1
192.168.99.103 node2
  • 机器间互相免密,配置完成后需要重启机器
yum install openssh-server
ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.56.101
reboot -f

如果安装有报错:没有安装deltarpm就执行以下命令

yum provides '*/applydeltarpm'

yum -y install deltarpm
  • 将 master 节点的 admin.conf 拷贝到 node1

scp /etc/kubernetes/admin.conf root@node1ip:/etc/kubernetes/

  • 配置端口转发
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/ipv4/ip_forward
  • 配置 Kubeconfig 环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
  • 安装网络相关的工具

yum install net-tools

  • 加入集群之前先清理拷贝过来的Master环境的网络
kubeadm reset
systemctl stop kubelet
systemctl stop docker
rm -rf /var/lib/cni/
rm -rf /var/lib/kubelet/*
rm -rf /etc/chi/
ifconfig cni0 down
ifconfig flannel.1 down
ifconfig docker0 down
ip link delete cni0
ip link delete flannel.1
systemctl start docker
systemctl start kubelet
  • kubadm join 加入集群
systemctl enable kubelet.service
kubeadm join 192.168.99.101:6443 --token vrqf1w.dyg1wru7nz0ut9jz    --discovery-token-ca-cert-hash sha256:1832d6d6c8386de5ecb1a7f512cfdef27a6d14ef901ffbe7d3c01d999d794f90

默认token的有效期为24小时,当过期之后,该token就不可用了。解决方法如下:

重新生成新的token,在master端执行

kubeadm token create --print-join-command

  • 安装 flannel 网络插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  • 将master节点下面/etc/cni/net.d/下面的所有文件拷贝到node节点上

在node1节点上面创建目录: mkdir -p /etc/cni/net.d/

在master: scp /etc/cni/net.d/* root@nodeip:/etc/cni/net.d/

执行命令: kubectl get nodes 查看 node 节点处于ready状态

  • 检查集群状态 稍等几分钟,在master节点输入命令检查集群状态.
kubectl get nodes
image

4-10 剖析kubeadm安装原理

Init 命令的工作流程

kubeadm init命令通过执行下列步骤来启动一个 Kubernetes Control Plane节点。

  1. 运行一系列的预检项来验证系统状态。一些检查项目仅仅触发警告, 其它的则会被视为错误并且退出 kubeadm,除非问题得到解决或者用户指定了 --ignore-preflight-errors= 参数。

  2. 生成一个自签名的CA证书(或者使用现有的证书,如果提供的话)来为集群中的每一个组件建立身份标识。如果用户已经通过--cert-dir配置的证书目录(默认为/etc/kubernetes/pki)提供了他们自己的 CA 证书以及/或者密钥,那么将会跳过这个步骤,正如文档使用自定义证书所述。

  3. kubeconfig文件写入/etc/kubernetes/目录,以便kubelet、控制器管理器和调度器用来连接到API 服务器,它们每一个都有自己的身份标识,同时生成一个名为 admin.conf的独立的 kubeconfig文件,用于管理操作。

  4. 为 API服务器、控制器管理器和调度器生成静态Pod的清单文件。静态Pod的清单文件被写入到/etc/kubernetes/manifests目录;kubelet 会监视这个目录以便在系统启动的时候创建 Pod。一旦Control Plane的 Pod 都运行起来, kubeadm init的工作流程就继续往下执行。

  5. Control Plane节点应用 labels 和 taints 标记以便不会在它上面运行其它的工作负载。

  6. 生成令牌以便其它节点以后可以使用这个令牌向Control Plane节点注册自己。

  7. Kubeadm 会创建 configmap,提供添加节点所需要的信息。

查看创建的configmap

image
image

安装问题

  • docker ps -a查看Kubernetes系统服务的状态
  • Kubernetes集群启动问题,用journalctl查看日志
systemctl status kubelet
journalctl -xefu kubelet
journalctl -u kube-apiserver
  • 用kubectl查看日志

注意:使用Kubelet describe 查看日志,一定要注意是否应包含命名空间

kubectl describe pod kubernetes-dashboard-xxx --namespace
kubectl logs -f pods/monitoring-influxdb-xxx -n kube-system
kubectl logs --tail 200 -f podname -n jenkins
  • 执行kubeadm join 异常问题

执行 kubeadm reset,并且将 cni0,flannel1.1,docker0等网络规则删除,参考 Worker node 安装的章节。

  • 镜像拉取不下来

修改 yaml 文件中的 image路径


4-11 安装Dashboard

  • 下载Kubernetes Dashboard yaml 文件

https://www.yuque.com/insaneloafer/eqq96o/kssab0?inner=ltYwM

  • 修改Service类型为NodePort
image
spec:
    type: NodePort
  ports:
  - port: 443
    targetPort: 8443
    nodePort: 31111
  selector:
    k8s-app: kubernetes-dashboard
  • 部署dashboard
kubectl create -f kubernetes-dashboard.yaml
kubectl apply -f kubernetes-dashboard.yaml
image
  • 查看pod、svc状态
kubectl get pod,svc -n kubernetes-dashboard
image
  • 非安全的浏览器访问

通过chrome浏览器访问https://192.168.99.102:31111,此时会返回“Your connection is not private”,无法跳转页面到Dashboard,这是由于 chrome 的安全设置,解决办法:鼠标点击当前页面,直接键盘输入thisisunsafe,然后回车,即可进行页面跳转至 Dashboard登录页

  • 获取登录 token
kubectl -n kube-system describe $(kubectl -n kube-system get secret -n kube-system -o name | grep namespace) | grep token 
image
  • 登录 Dashboard

在登录页面输入之前生成的 token,即可完成登录。

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

推荐阅读更多精彩内容