Docker Swarm 入門一篇文章就夠了

Swarm 在 Docker 1.12 版本之前屬于一個獨立的項目,在 Docker 1.12 版本發布之后,該項目合并到了 Docker 中,成為 Docker 的一個子命令。目前,Swarm 是 Docker 社區提供的唯一一個原生支持 Docker 集群管理的工具。它可以把多個 Docker 主機組成的系統轉換為單一的虛擬 Docker 主機,使得容器可以組成跨主機的子網網絡。

1. Swarm 認識

Swarm 是目前 Docker 官方唯一指定(綁定)的集群管理工具。Docker 1.12 內嵌了 swarm mode 集群管理模式。

為了方便演示跨主機網絡,我們需要用到一個工具——Docker Machine,這個工具與 Docker Compose、Docker Swarm 并稱 Docker 三劍客,下面我們來看看如何安裝 Docker Machine:

$ curl -L https://github.com/docker/machine/releases/download/v0.9.0-rc2/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
    chmod +x /tmp/docker-machine &&
    sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

安裝過程和 Docker Compose 非常類似。現在 Docker 三劍客已經全部到齊了。
在開始之前,我們需要了解一些基本概念,有關集群的 Docker 命令如下:

  • docker swarm:集群管理,子命令有 init, join,join-token, leave, update
  • docker node:節點管理,子命令有 demote, inspect,ls, promote, rm, ps, update
  • docker service:服務管理,子命令有 create, inspect, ps, ls ,rm , scale, update
  • docker stack/deploy:試驗特性,用于多應用部署,等正式版加進來再說。

2. 創建集群

首先使用 Docker Machine 創建一個虛擬機作為 manger 節點。

$ docker-machine create --driver virtualbox manager1                                    
Running pre-create checks...
(manager1) Unable to get the latest Boot2Docker ISO release version:  Get https://api.github.com/repos/boot2docker/boot2docker/releases/latest: dial tcp: lookup api.github.com on [::1]:53: server misbehaving
Creating machine...
(manager1) Unable to get the latest Boot2Docker ISO release version:  Get https://api.github.com/repos/boot2docker/boot2docker/releases/latest: dial tcp: lookup api.github.com on [::1]:53: server misbehaving
(manager1) Copying /home/zuolan/.docker/machine/cache/boot2docker.iso to /home/zuolan/.docker/machine/machines/manager1/boot2docker.iso...
(manager1) Creating VirtualBox VM...
(manager1) Creating SSH key...
(manager1) Starting the VM...
(manager1) Check network to re-create if needed...
(manager1) Found a new host-only adapter: "vboxnet0"
(manager1) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env manager1

查看虛擬機的環境變量等信息,包括虛擬機的 IP 地址:

$  docker-machine env manager1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/zuolan/.docker/machine/machines/manager1"
export DOCKER_MACHINE_NAME="manager1"
# Run this command to configure your shell: 
# eval $(docker-machine env manager1)

然后再創建一個節點作為 work 節點。

$ docker-machine create --driver virtualbox worker1

現在我們有了兩個虛擬主機,使用 Machine 的命令可以查看:

$ docker-machine ls                             
NAME     ACTIVE   DRIVER       STATE    URL                        SWARM  DOCKER   ERRORS
manager1   -      virtualbox   Running  tcp://192.168.99.100:2376         v1.12.3   
worker1    -      virtualbox   Running  tcp://192.168.99.101:2376         v1.12.3

但是目前這兩臺虛擬主機并沒有什么聯系,為了把它們聯系起來,我們需要 Swarm 登場了。
因為我們使用的是 Docker Machine 創建的虛擬機,因此可以使用 docker-machine ssh 命令來操作虛擬機,在實際生產環境中,并不需要像下面那樣操作,只需要執行 docker swarm 即可。

把 manager1 加入集群:

$ docker-machine ssh manager1 docker swarm init --listen-addr 192.168.99.100:2377 --advertise-addr 192.168.99.100
Swarm initialized: current node (23lkbq7uovqsg550qfzup59t6) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
    192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

用 --listen-addr 指定監聽的 ip 與端口,實際的 Swarm 命令格式如下,本例使用 Docker Machine 來連接虛擬機而已:

$ docker swarm init --listen-addr <MANAGER-IP>:<PORT>

接下來,再把 work1 加入集群中:

$ docker-machine ssh worker1 docker swarm join --token \
    SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
    192.168.99.100:2377
This node joined a swarm as a worker.

上面 join 命令中可以添加 --listen-addr $WORKER1_IP:2377 作為監聽準備,因為有時候可能會遇到把一個 work 節點提升為 manger 節點的可能,當然本例子沒有這個打算就不添加這個參數了。

注意:如果你在新建集群時遇到雙網卡情況,可以指定使用哪個 IP,例如上面的例子會有可能遇到下面的錯誤。

$ docker-machine ssh manager1 docker swarm init --listen-addr $MANAGER1_IP:2377
Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses on different interfaces (10.0.2.15 on eth0 and 192.168.99.100 on eth1) - specify one with --advertise-addr
exit status 1

發生錯誤的原因是因為有兩個 IP 地址,而 Swarm 不知道用戶想使用哪個,因此要指定 IP。

$ docker-machine ssh manager1 docker swarm init --advertise-addr 192.168.99.100 --listen-addr 192.168.99.100:2377 
Swarm initialized: current node (ahvwxicunjd0z8g0eeosjztjx) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
    192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

集群初始化成功。

現在我們新建了一個有兩個節點的“集群”,現在進入其中一個管理節點使用 docker node 命令來查看節點信息:

$ docker-machine ssh manager1 docker node ls
ID                       HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
23lkbq7uovqsg550qfzup59t6 *  manager1    Ready      Active         Leader
dqb3fim8zvcob8sycri3hy98a    worker1     Ready      Active

現在每個節點都歸屬于 Swarm,并都處在了待機狀態。Manager1 是領導者,work1 是工人。

現在,我們繼續新建虛擬機 manger2、worker2、worker3,現在已經有五個虛擬機了,使用 docker-machine ls 來查看虛擬機:

NAME     ACTIVE    DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
manager1   -       virtualbox   Running   tcp://192.168.99.100:2376           v1.12.3   
manager2   -       virtualbox   Running   tcp://192.168.99.105:2376           v1.12.3   
worker1    -       virtualbox   Running   tcp://192.168.99.102:2376           v1.12.3   
worker2    -       virtualbox   Running   tcp://192.168.99.103:2376           v1.12.3   
worker3    -       virtualbox   Running   tcp://192.168.99.104:2376           v1.12.3

然后我們把剩余的虛擬機也加到集群中。

  • 添加 worker2 到集群中:
$ docker-machine ssh worker2 docker swarm join \
    --token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
    192.168.99.100:2377
This node joined a swarm as a worker.
  • 添加 worker3 到集群中:
$ docker-machine ssh worker3 docker swarm join \
    --token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-c036gwrakjejql06klrfc585r \
    192.168.99.100:2377
This node joined a swarm as a worker.
  • 添加 manager2 到集群中:
    先從 manager1 中獲取 manager 的 token:
$ docker-machine ssh manager1 docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-8tn855hkjdb6usrblo9iu700o \
192.168.99.100:2377

然后添加 manager2 到集群中:

$ docker-machine ssh manager2 docker swarm join \
    --token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-8tn855hkjdb6usrblo9iu700o \
    192.168.99.100:2377
This node joined a swarm as a manager.

現在再來查看集群信息:

$ docker-machine ssh manager2 docker node ls
ID                            HOSTNAME   STATUS   AVAILABILITY   MANAGER STATUS
16w80jnqy2k30yez4wbbaz1l8     worker1     Ready     Active        
2gkwhzakejj72n5xoxruet71z     worker2     Ready     Active        
35kutfyn1ratch55fn7j3fs4x     worker3     Ready     Active        
a9r21g5iq1u6h31myprfwl8ln *   manager2    Ready     Active        Reachable
dpo7snxbz2a0dxvx6mf19p35z     manager1    Ready     Active        Leader

3. 建立跨主機網絡

為了演示更清晰,下面我們把宿主機也加入到集群之中,這樣我們使用 Docker 命令操作會清晰很多。
直接在本地執行加入集群命令:

$ docker swarm join \           
    --token SWMTKN-1-3z5rzoey0u6onkvvm58f7vgkser5d7z8sfshlu7s4oz2gztlvj-8tn855hkjdb6usrblo9iu700o \
    192.168.99.100:2377
This node joined a swarm as a manager.

現在我們有三臺 manager,三臺 worker。其中一臺是宿主機,五臺虛擬機。

$ docker node ls
ID                          HOSTNAME    STATUS    AVAILABILITY  MANAGER STATUS
6z2rpk1t4xucffzlr2rpqb8u3    worker3     Ready     Active        
7qbr0xd747qena4awx8bx101s *  user-pc     Ready     Active         Reachable
9v93sav79jqrg0c7051rcxxev    manager2    Ready     Active         Reachable
a1ner3zxj3ubsiw4l3p28wrkj    worker1     Ready     Active        
a5w7h8j83i11qqi4vlu948mad    worker2     Ready     Active        
d4h7vuekklpd6189fcudpfy18    manager1    Ready     Active          Leader

查看網絡狀態:

$ docker network ls
NETWORK ID         NAME            DRIVER          SCOPE
764ff31881e5        bridge          bridge          local                  
fbd9a977aa03        host            host            local               
6p6xlousvsy2        ingress         overlay         swarm            
e81af24d643d        none            null            local

可以看到在 swarm 上默認已有一個名為 ingress 的 overlay 網絡, 默認在 swarm 里使用,本例子中會創建一個新的 overlay 網絡。

$ docker network create --driver overlay swarm_test
4dm8cy9y5delvs5vd0ghdd89s
$ docker network ls
NETWORK ID         NAME                DRIVER              SCOPE
764ff31881e5        bridge              bridge              local
fbd9a977aa03        host                host                local
6p6xlousvsy2        ingress             overlay             swarm
e81af24d643d        none                null                local
4dm8cy9y5del        swarm_test          overlay             swarm

這樣一個跨主機網絡就搭建好了,但是現在這個網絡只是處于待機狀態,下一小節我們會在這個網絡上部署應用。

4. 在跨主機網絡上部署應用

首先我們上面創建的節點都是沒有鏡像的,因此我們要逐一 pull 鏡像到節點中,這里我們使用前面搭建的私有倉庫。

$ docker-machine ssh manager1 docker pull reg.example.com/library/nginx:alpine     
alpine: Pulling from library/nginx
e110a4a17941: Pulling fs layer
... ...
7648f5d87006: Pull complete
Digest: sha256:65063cb82bf508fd5a731318e795b2abbfb0c22222f02ff5c6b30df7f23292fe
Status: Downloaded newer image for reg.example.com/library/nginx:alpine
$ docker-machine ssh manager2 docker pull reg.example.com/library/nginx:alpine
alpine: Pulling from library/nginx
e110a4a17941: Pulling fs layer
... ...
7648f5d87006: Pull complete
Digest: sha256:65063cb82bf508fd5a731318e795b2abbfb0c22222f02ff5c6b30df7f23292fe
Status: Downloaded newer image for reg.example.com/library/nginx:alpine
$ docker-machine ssh worker1 docker pull reg.example.com/library/nginx:alpine 
alpine: Pulling from library/nginx
e110a4a17941: Pulling fs layer
... ...
7648f5d87006: Pull complete
Digest: sha256:65063cb82bf508fd5a731318e795b2abbfb0c22222f02ff5c6b30df7f23292fe
Status: Downloaded newer image for reg.example.com/library/nginx:alpine
$ docker-machine ssh worker2 docker pull reg.example.com/library/nginx:alpine
alpine: Pulling from library/nginx
e110a4a17941: Pulling fs layer
... ...
7648f5d87006: Pull complete
Digest: sha256:65063cb82bf508fd5a731318e795b2abbfb0c22222f02ff5c6b30df7f23292fe
Status: Downloaded newer image for reg.example.com/library/nginx:alpine
$ docker-machine ssh worker3 docker pull reg.example.com/library/nginx:alpine
alpine: Pulling from library/nginx
e110a4a17941: Pulling fs layer
... ...
7648f5d87006: Pull complete
Digest: sha256:65063cb82bf508fd5a731318e795b2abbfb0c22222f02ff5c6b30df7f23292fe
Status: Downloaded newer image for reg.example.com/library/nginx:alpine

上面使用 docker pull 分別在五個虛擬機節點拉取 nginx:alpine 鏡像。接下來我們要在五個節點部署一組 Nginx 服務。

部署的服務使用 swarm_test 跨主機網絡。

$ docker service create --replicas 2 --name helloworld --network=swarm_test nginx:alpine
5gz0h2s5agh2d2libvzq6bhgs

查看服務狀態:

$ docker service ls
ID            NAME        REPLICAS  IMAGE         COMMAND
5gz0h2s5agh2  helloworld  0/2       nginx:alpine  

查看 helloworld 服務詳情(為了方便閱讀,已調整輸出內容):

$ docker service ps helloworld
ID          NAME          IMAGE         NODE      DESIRED STATE   CURRENT STATE              ERROR
ay081uome3   helloworld.1  nginx:alpine  manager1  Running         Preparing 2 seconds ago  
16cvore0c96  helloworld.2  nginx:alpine  worker2   Running         Preparing 2 seconds ago

可以看到兩個實例分別運行在兩個節點上。

進入兩個節點,查看服務狀態(為了方便閱讀,已調整輸出內容):

$ docker-machine ssh manager1 docker ps -a
CONTAINER ID   IMAGE         COMMAND         CREATED        STATUS         PORTS            NAMES
119f787622c2   nginx:alpine  "nginx -g ..."   4 minutes ago  Up 4 minutes   80/tcp, 443/tcp  hello ...
$ docker-machine ssh worker2 docker ps -a
CONTAINER ID   IMAGE         COMMAND         CREATED         STATUS        PORTS             NAMES
5db707401a06   nginx:alpine  "nginx -g ..."   4 minutes ago   Up 4 minutes  80/tcp, 443/tcp   hello ...

上面輸出做了調整,實際的 NAMES 值為:

helloworld.1.ay081uome3eejeg4mspa8pdlx
helloworld.2.16cvore0c96rby1vp0sny3mvt

記住上面這兩個實例的名稱。現在我們來看這兩個跨主機的容器是否能互通:
首先使用 Machine 進入 manager1 節點,然后使用 docker exec -i 命令進入 helloworld.1 容器中 ping 運行在 worker2 節點的 helloworld.2 容器。

$ docker-machine ssh manager1 docker exec -i helloworld.1.ay081uome3eejeg4mspa8pdlx \
    ping helloworld.2.16cvore0c96rby1vp0sny3mvt
PING helloworld.2.16cvore0c96rby1vp0sny3mvt (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.591 ms
64 bytes from 10.0.0.4: seq=1 ttl=64 time=0.594 ms
64 bytes from 10.0.0.4: seq=2 ttl=64 time=0.624 ms
64 bytes from 10.0.0.4: seq=3 ttl=64 time=0.612 ms
^C

然后使用 Machine 進入 worker2 節點,然后使用 docker exec -i 命令進入 helloworld.2 容器中 ping 運行在 manager1 節點的 helloworld.1 容器。

$ docker-machine ssh worker2 docker exec -i helloworld.2.16cvore0c96rby1vp0sny3mvt \
    ping helloworld.1.ay081uome3eejeg4mspa8pdlx 
PING helloworld.1.ay081uome3eejeg4mspa8pdlx (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.466 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.465 ms
64 bytes from 10.0.0.3: seq=2 ttl=64 time=0.548 ms
64 bytes from 10.0.0.3: seq=3 ttl=64 time=0.689 ms
^C

可以看到這兩個跨主機的服務集群里面各個容器是可以互相連接的。

為了體現 Swarm 集群的優勢,我們可以使用虛擬機的 ping 命令來測試對方虛擬機內的容器。

$ docker-machine ssh worker2 ping helloworld.1.ay081uome3eejeg4mspa8pdlx
PING helloworld.1.ay081uome3eejeg4mspa8pdlx (221.179.46.190): 56 data bytes
64 bytes from 221.179.46.190: seq=0 ttl=63 time=48.651 ms
64 bytes from 221.179.46.190: seq=1 ttl=63 time=63.239 ms
64 bytes from 221.179.46.190: seq=2 ttl=63 time=47.686 ms
64 bytes from 221.179.46.190: seq=3 ttl=63 time=61.232 ms
^C
$ docker-machine ssh manager1 ping helloworld.2.16cvore0c96rby1vp0sny3mvt
PING helloworld.2.16cvore0c96rby1vp0sny3mvt (221.179.46.194): 56 data bytes
64 bytes from 221.179.46.194: seq=0 ttl=63 time=30.150 ms
64 bytes from 221.179.46.194: seq=1 ttl=63 time=54.455 ms
64 bytes from 221.179.46.194: seq=2 ttl=63 time=73.862 ms
64 bytes from 221.179.46.194: seq=3 ttl=63 time=53.171 ms
^C

上面我們使用了虛擬機內部的 ping 去測試容器的延遲,可以看到延遲明顯比集群內部的 ping 值要高。

5. Swarm 集群負載

現在我們已經學會了 Swarm 集群的部署方法,現在來搭建一個可訪問的 Nginx 集群吧。體驗最新版的 Swarm 所提供的自動服務發現與集群負載功能。
首先刪掉上一節我們啟動的 helloworld 服務:

$ docker service rm helloworld                                 
helloworld

然后在新建一個服務,提供端口映射參數,使得外界可以訪問這些 Nginx 服務:

$ docker service create --replicas 2 --name helloworld -p 7080:80 --network=swarm_test nginx:alpine
9gfziifbii7a6zdqt56kocyun

查看服務運行狀態:

$ docker service ls                                                                                
ID           NAME         REPLICAS     IMAGE           COMMAND
9gfziifbii7a  helloworld     2/2        nginx:alpine  

不知你有沒有發現,雖然我們使用 --replicas 參數的值都是一樣的,但是上一節中獲取服務狀態時,REPLICAS 返回的是 0/2,現在的 REPLICAS 返回的是 2/2。
同樣使用 docker service ps 查看服務詳細狀態時(下面輸出已經手動調整為更易讀的格式),可以看到實例的 CURRENT STATE 中是 Running 狀態的,而上一節中的 CURRENT STATE 中全部是處于 Preparing 狀態。

$ docker service ps helloworld
ID          NAME      IMAGE     NODE    DESIRED STATE   CURRENT STATE    ERROR
9ikr3agyi...   helloworld.1  nginx:alpine  user-pc    Running         Running 13 seconds ago  
7acmhj0u...   helloworld.2  nginx:alpine  worker2    Running         Running 6 seconds ago

這就涉及到 Swarm 內置的發現機制了,目前 Docker 1.12 中 Swarm 已經內置了服務發現工具,我們不再需要像以前使用 Etcd 或者 Consul 這些工具來配置服務發現。對于一個容器來說如果沒有外部通信但又是運行中的狀態會被服務發現工具認為是 Preparing 狀態,本小節例子中因為映射了端口,因此有了 Running 狀態。
現在我們來看 Swarm 另一個有趣的功能,當我們殺死其中一個節點時,會發生什么。
首先 kill 掉 worker2 的實例:

$ docker-machine ssh worker2 docker kill helloworld.2.7acmhj0udzusv1d7lu2tbuhu4
helloworld.2.7acmhj0udzusv1d7lu2tbuhu4

稍等幾秒,再來看服務狀態:

$ docker service ps helloworld
ID         NAME          IMAGE     NODE   DESIRED STATE  CURRENT STATE   ERROR
9ikr3agyi...  helloworld.1     nginx:alpine  zuolan-pc  Running       Running 19 minutes ago  
8f866igpl...  helloworld.2     nginx:alpine  manager1  Running       Running 4 seconds ago   
7acmhj0u...   \_ helloworld.2  nginx:alpine  worker2   Shutdown       Failed 11 seconds ago  ...exit...
$ docker service ls           
ID            NAME        REPLICAS  IMAGE         COMMAND
9gfziifbii7a  helloworld  2/2       nginx:alpine

可以看到即使我們 kill 掉其中一個實例,Swarm 也會迅速把停止的容器撤下來,同時在節點中啟動一個新的實例頂上來。這樣服務依舊還是兩個實例在運行。
此時如果你想添加更多實例可以使用 scale 命令:

$ docker service scale helloworld=3
helloworld scaled to 3

查看服務詳情,可以看到有三個實例啟動了:

$ docker service ps helloworld
ID         NAME        IMAGE      NODE   DESIRED STATE  CURRENT STATE    ERROR
9ikr3agyi...  helloworld.1    nginx:alpine  user-pc   Running        Running 30 minutes ago  8f866igpl...  helloworld.2    nginx:alpine  manager1  Running        Running 11 minutes ago  7acmhj0u...  \_ helloworld.2  nginx:alpine  worker2   Shutdown       Failed 11 minutes ago   exit137
1vexr1jm...  helloworld.3    nginx:alpine   worker2   Running       Running 4 seconds ago

現在如果想減少實例數量,一樣可以使用 scale 命令:

$ docker service scale helloworld=2
helloworld scaled to 2

至此,Swarm的主要用法都已經介紹完了,主要講述了 Swarm 集群網絡的創建與部署。介紹了 Swarm 的常規應用,包括 Swarm 的服務發現、負載均衡等,然后使用 Swarm 來配置跨主機容器網絡,并在上面部署應用。

關于Swarm的更多實戰例子,以后有機會還會寫的,就這樣啦。

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

推薦閱讀更多精彩內容

  • Docker — 云時代的程序分發方式 要說最近一年云計算業界有什么大事件?Google Compute Engi...
    ahohoho閱讀 15,562評論 15 147
  • 目錄 Swarm簡介 Swarm架構 Swarm命令 總結 1. Swarm簡介 Docker自誕生以來,其容器特...
    garyond閱讀 1,329評論 1 9
  • 早上送兒子們上學的路上,聽著兩小子一路閑侃,弟向哥得瑟自己的跆拳道課如何使自己強壯威武,哥由于學過一學期也毫不示弱...
    簡繁君閱讀 326評論 7 3
  • 那天下著小雨,貌似這里的細雨已成為當地的一種習慣,從一進城就感覺到,我下了車。 車站不大,我只背了個背包,快速找了...
    暗門閱讀 257評論 0 0
  • 他真的很喜歡你 像風走了八千里 他真的很喜歡你 像陣雨下到了南極 他真的很想念你 像珊瑚沉在海底 他真的很喜歡你 ...
    冬冬小眠閱讀 1,015評論 0 1