Docker Swarm - 服務(wù)發(fā)現(xiàn)和負(fù)載均衡原理

本文將介紹基于 DNS 的負(fù)載均衡、基于 VIP 的負(fù)載均衡和路由網(wǎng)格(Routing Mesh)辽故。

使用的技術(shù)

Docker 使用了 Linux 內(nèi)核 iptables 和 IPVS 的功能來實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡。

  • iptables 是 Linux 內(nèi)核中可用的包過濾技術(shù)腐碱,它可用于根據(jù)數(shù)據(jù)包的內(nèi)容進(jìn)行分類誊垢、修改和轉(zhuǎn)發(fā)決策。
  • IPVS 是 Linux 內(nèi)核中可用的傳輸級(jí)負(fù)載均衡器症见。

準(zhǔn)備工作

  • swarm 集群:【Manager】node1喂走、【W(wǎng)orker】node2
  • 客戶端鏡像: registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu
  • 服務(wù)端鏡像: registry.cn-hangzhou.aliyuncs.com/anoy/vote

如圖所示,我們將在 swarm 集群中部署 “client” 服務(wù) 和 “vote” 服務(wù)谋作,其中 “vote” 服務(wù)部署多個(gè)副本芋肠。客戶端請(qǐng)求 “vote” 服務(wù)時(shí)遵蚜,輸出結(jié)果中包含服務(wù)端的容器 ID帖池,這樣就更方便演示網(wǎng)絡(luò)請(qǐng)求奈惑。

集群狀態(tài)

[root@node1 ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
rnr2i1y2of3n5vy2vzh2vkzq0 *   node1               Ready               Active              Leader              18.03.1-ce
qvik057dvphx5s06evmswahaf     node2               Ready               Active                                  18.03.1-ce

使用如下命令,創(chuàng)建 overlay 網(wǎng)絡(luò):

docker network create --driver overlay overlay1

基于 DNS 的負(fù)載均衡

下圖描述了基于 DNS 的負(fù)載均衡是如何工作的:

DNS server 內(nèi)嵌于 Docker 引擎睡汹。Docker DNS 解析服務(wù)名 “vote” 并返回容器 ID 地址列表(隨機(jī)排序)肴甸。客戶端通常會(huì)挑第一個(gè) IP 訪問囚巴,因此負(fù)載均衡可能發(fā)生在服務(wù)器的不同實(shí)例之間原在。

使用如下命令創(chuàng)建 2 個(gè)基于 DNS 負(fù)載均衡的服務(wù) “client” 、 “vote”:

docker service create --endpoint-mode dnsrr --replicas 1 --name client --network overlay1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu ping anoyi.com

docker service create --endpoint-mode dnsrr --name vote --network overlay1 --replicas 2 registry.cn-hangzhou.aliyuncs.com/anoy/vote

查看服務(wù)信息:

[root@node1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                                                  PORTS
2mrj3pqyioc3        client              replicated          1/1                 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest
826s79tsixuh        vote                replicated          2/2                 registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest

[root@node1 ~]# docker service ps client
ID                  NAME                IMAGE                                                  NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
f74i688vbh12        client.1            registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest   node2               Running             Running 2 minutes ago

[root@node1 ~]# docker service ps vote
ID                  NAME                IMAGE                                                NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
7iiuzl2a63hy        vote.1              registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest   node1               Running             Running 47 seconds ago
uyhxxqfdima7        vote.2              registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest   node2               Running             Running about a minute ago

可以看出 "client" 運(yùn)行于 node2彤叉,在 node2 上進(jìn)入 client 容器晤斩,使用 dig 來解析服務(wù)名 "vote",如下所示姆坚,"vote" 解析到 10.0.0.6 和 10.0.0.5

[root@node2 ~]# docker ps
CONTAINER ID        IMAGE                                                  COMMAND                  CREATED              STATUS              PORTS               NAMES
1eed67d37cbb        registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest     "gunicorn app:app -b…"   About a minute ago   Up About a minute   80/tcp              vote.2.uyhxxqfdima7smos5pki84wul
436702b21a1c        registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest   "ping anoyi.com"         3 minutes ago        Up 3 minutes                            client.1.f74i688vbh12on8oniufht633

[root@node2 ~]# docker exec -it 436702b21a1c /bin/bash

root@436702b21a1c:/# dig vote

;; ANSWER SECTION:
vote.           600 IN  A   10.0.0.5
vote.           600 IN  A   10.0.0.6

使用 ping 解析 "vote" 服務(wù)澳泵,如下所示,交替解析到 10.0.0.6 和 10.0.0.5

root@436702b21a1c:/# ping -c1 vote
PING vote (10.0.0.6) 56(84) bytes of data.
64 bytes from vote.2.uyhxxqfdima7smos5pki84wul.overlay1 (10.0.0.6): icmp_seq=1 ttl=64 time=0.087 ms

root@436702b21a1c:/# ping -c1 vote
PING vote (10.0.0.5) 56(84) bytes of data.
64 bytes from vote.1.7iiuzl2a63hyj084qgufc175v.overlay1 (10.0.0.5): icmp_seq=1 ttl=64 time=0.767 ms

如果使用 curl兼呵,如下所示兔辅,請(qǐng)求也能解析到不同的容器

root@436702b21a1c:/# curl vote  | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0   7542      0 --:--:-- --:--:-- --:--:--  7546
          Processed by container ID 9b42319d4f13

root@436702b21a1c:/# curl vote  | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0   452k      0 --:--:-- --:--:-- --:--:--  514k
          Processed by container ID 1eed67d37cbb

基于 DNS 負(fù)載均衡存在如下問題:

  • 某些應(yīng)用程序?qū)?DNS 主機(jī)名緩存到 IP 地址映射筋量,這會(huì)導(dǎo)致應(yīng)用程序在映射更改時(shí)超時(shí)
  • 具有非零 DNS ttl 值會(huì)導(dǎo)致 DNS 條目反映最新的詳細(xì)信息時(shí)發(fā)生延遲

基于 VIP 的負(fù)載均衡

基于 VIP 的負(fù)載均衡克服了基于 DNS 負(fù)載均衡的一些問題沉帮。在這種方法中口注,每個(gè)服務(wù)都有一個(gè) IP 地址蚁阳,并且該 IP 地址映射到與該服務(wù)關(guān)聯(lián)的多個(gè)容器的 IP 地址。在這種情況下寺谤,與服務(wù)關(guān)聯(lián)的服務(wù) IP 不會(huì)改變报咳,即使與該服務(wù)關(guān)聯(lián)的容器死亡并重新啟動(dòng)蒜埋。

下圖描述了基于 VIP 的負(fù)載均衡是如何工作的:

DNS server 會(huì)將服務(wù)名 "vote" 解析到 VIP凌彬,使用 iptables 和 ipvs沸柔,VIP 實(shí)現(xiàn) 2 個(gè)服務(wù)端 "vote" 容器的負(fù)載均衡。

使用如下命令創(chuàng)建 2 個(gè) VIP 模式的服務(wù) “client” 铲敛、 “vote”:

docker service create --replicas 1 --name client --network overlay1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu ping anoyi.com

docker service create --name vote --network overlay1 --replicas 2 registry.cn-hangzhou.aliyuncs.com/anoy/vote

查看這 2 個(gè)服務(wù)和它們的服務(wù) IP:

[root@node1 ~]# docker service inspect --format {{.Endpoint.VirtualIPs}}  vote
[{tetug0isdx1gri62g7cfm889i 10.0.0.9/24}]

[root@node1 ~]# docker service inspect --format {{.Endpoint.VirtualIPs}}  client
[{tetug0isdx1gri62g7cfm889i 10.0.0.7/24}]

在 "client" 的容器中使用如下命令褐澎,可以看到服務(wù)名 "vote" 映射到 VIP "10.0.0.9"

[root@node2 ~]# docker exec -it f3d1c4ef53f8 /bin/bash

root@f3d1c4ef53f8:/# dig vote

;; ANSWER SECTION:
vote.           600 IN  A   10.0.0.9

Service IP "10.0.0.9" 使用 Linux 內(nèi)核的 iptables 和 IPVS 負(fù)載均衡到 2 個(gè)容器。iptables 實(shí)現(xiàn)防火墻規(guī)則伐蒋,IPVS 實(shí)現(xiàn)負(fù)載均衡工三。為了證明這一點(diǎn),我們需要使用 nsenter 進(jìn)入容器的網(wǎng)絡(luò)空間 (namespace)先鱼。為此俭正,我們需要找到網(wǎng)絡(luò)的命名空間。

如下是 node2 上的網(wǎng)絡(luò)命名空間:

[root@node2 ~]# cd /run/docker/netns/

[root@node2 netns]# ls
1-tetug0isdx  1-vyy22w04t6  be7330b99a27  d67fa9efb59e  ingress_sbox

前 2 個(gè)命名空間是用于 overlay 網(wǎng)絡(luò)焙畔,后面的用于容器掸读。下面的命令用于找到 "client" 容器的網(wǎng)絡(luò)命名空間:

[root@node2 netns]# docker ps
CONTAINER ID        IMAGE                                                  COMMAND                  CREATED             STATUS              PORTS               NAMES
43a789312e70        registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest     "gunicorn app:app -b…"   3 minutes ago       Up 3 minutes        80/tcp              vote.1.u46ms31e8zjdxtwrxvaec8zub
f3d1c4ef53f8        registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest   "ping anoyi.com"         4 minutes ago       Up 4 minutes                            client.1.ycox088aek5ajejezubwsjqf2

[root@node2 netns]# docker inspect f3d1c4ef53f8 | grep -i sandbox
            "SandboxID": "be7330b99a274a03a7f58e9e991346dc6f048836a1682c7244a6068acbfb664c",
            "SandboxKey": "/var/run/docker/netns/be7330b99a27",

SandboxID 即為 "client" 容器的網(wǎng)絡(luò)命名空間。

使用如下命令,我們就能夠進(jìn)入到 "client" 容器的網(wǎng)絡(luò)命令空間:

nsenter --net=f3d1c4ef53f8 sh

下面寺枉,我們可以看到 iptables 的轉(zhuǎn)發(fā)規(guī)則和 IPVS 輸出:

sh-4.2# iptables -nvL -t mangle

Chain OUTPUT (policy ACCEPT 606 packets, 50867 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MARK       all  --  *      *       0.0.0.0/0            10.0.0.7             MARK set 0x102
    0     0 MARK       all  --  *      *       0.0.0.0/0            10.0.0.9             MARK set 0x103

sh-4.2# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
FWM  258 rr
  -> node2:0                      Masq    1      0          0
FWM  259 rr
  -> 10.0.0.10:0                  Masq    1      0          0
  -> 10.0.0.11:0                  Masq    1      0          0

Service IP "10.0.0.9" 使用 iptables OUTPUT 鏈獲得標(biāo)記 0x103 (十六進(jìn)制 -> 十進(jìn)制:259)抑淫,然后 IPVS 使用此標(biāo)記并將它負(fù)載均衡到 "10.0.0.10" 和 "10.0.0.11" 绷落。

查看 vote 服務(wù)的 2 個(gè)容器的 IP 如下所示姥闪,即 VIP "10.0.0.9" 負(fù)載均衡到不同的容器實(shí)例:

[root@node2 netns]# docker inspect vote.1.u46ms31e8zjdxtwrxvaec8zub | grep IPv4
                        "IPv4Address": "10.0.0.10"

[root@node1 ~]# docker inspect vote.2.tutj19i4iwu1xn7arsaq815cu | grep IPv4
                        "IPv4Address": "10.0.0.11"

進(jìn)入 client 服務(wù)的容器,使用 curl 請(qǐng)求 vote 服務(wù)砌烁,輸出結(jié)果如下筐喳,即請(qǐng)求分發(fā)到不同的容器:

root@f3d1c4ef53f8:/# curl vote | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0  14409      0 --:--:-- --:--:-- --:--:-- 14438
          Processed by container ID c2af209c4e90

root@f3d1c4ef53f8:/# curl vote | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0   165k      0 --:--:-- --:--:-- --:--:--  171k
          Processed by container ID 43a789312e70

路由網(wǎng)格 (Routing mesh)

使用路由網(wǎng)格,服務(wù)暴露的端口會(huì)暴露在 Swarm 集群中的所有工作節(jié)點(diǎn)函喉。Docker 是通過創(chuàng)建 "ingress" overlay 網(wǎng)絡(luò)來實(shí)現(xiàn)這一點(diǎn)的避归,所有節(jié)點(diǎn)默認(rèn)使用內(nèi)在的 sandbox 網(wǎng)絡(luò)命名空間成為 "ingress" overlay 網(wǎng)絡(luò)的一部分。

下圖描述了 Routing mesh 如何實(shí)現(xiàn)負(fù)載均衡的:

首先管呵,會(huì)將 Hostname 或 IP 映射到 Sandbox IP梳毙,Sandbox 中的 iptables 和 IPVS 負(fù)責(zé)將請(qǐng)求負(fù)載均衡到 2 個(gè) vote 容器。Ingress sandbox 網(wǎng)絡(luò)命名空間駐留在 swarm 集群中的所有工作節(jié)點(diǎn)捐下,它通過將主機(jī)映射的端口負(fù)載均衡到后端容器來協(xié)助路由網(wǎng)格功能账锹。

使用如下命令創(chuàng)建 vote 服務(wù),使用路由網(wǎng)格暴露端口到所有節(jié)點(diǎn):

docker service create --name vote --network overlay1 --replicas 2 -p 8080:80 registry.cn-hangzhou.aliyuncs.com/anoy/vote

下圖顯示了 Sandbox坷襟、容器和每個(gè)節(jié)點(diǎn)的網(wǎng)絡(luò)之間的映射關(guān)系:

如圖所示奸柬,Sandbox 和 vote 容器是 "ingress" 網(wǎng)絡(luò)的一部分,它有助于路由網(wǎng)格婴程。client 容器和 vote 容器是 "overlay1" 網(wǎng)絡(luò)的一部分廓奕,它有助于內(nèi)部負(fù)載均衡。所有容器都是默認(rèn) "docker_gwbridge" 網(wǎng)絡(luò)的一部分档叔。

遵循 iptables 中的 NAT 規(guī)則顯示桌粉,端口 8080 上的主機(jī)流量發(fā)送到 node1 里的 Sandbox:

[root@node1 ~]# iptables -nvL -t nat

Chain DOCKER-INGRESS (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.18.0.2:8080
  315 18876 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

進(jìn)入 node1 上的 Sandbox 網(wǎng)絡(luò)命名空間 (ingress_sbox),查看 iptables 的轉(zhuǎn)發(fā)規(guī)則和 IPVS 輸出:

[root@node1 netns]# nsenter --net=ingress_sbox sh

sh-4.2# iptables -nvL -t mangle
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MARK       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 MARK set 0x105

sh-4.2# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
FWM  261 rr
  -> 10.255.0.5:0                 Masq    1      0          0
  -> 10.255.0.6:0                 Masq    1      0          0

端口 8080 標(biāo)記為 0x105 (十六進(jìn)制 -> 十進(jìn)制:261)衙四,IPVS 使用此標(biāo)記將它負(fù)載均衡到 "10.255.0.5" 和 "10.255.0.6" 番甩。

查看 vote 服務(wù)的 2 個(gè)容器的 IP 如下所示,即主機(jī)端口 8080 的流量會(huì)負(fù)載均衡到不同的容器實(shí)例:

[root@node1 netns]# docker inspect 6173afd5fab8 | grep IPv4
                        "IPv4Address": "10.255.0.6"
                        "IPv4Address": "10.0.0.14"

[root@node2 ~]# docker inspect b07e95c5c681 | grep IPv4
                        "IPv4Address": "10.255.0.5"
                        "IPv4Address": "10.0.0.13"

驗(yàn)證負(fù)載均衡届搁,在 node1 上通過 node2 的 IP 和 8080 端口請(qǐng)求 vote 服務(wù):

[root@node1 netns]# curl node2:8080 | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0   199k      0 --:--:-- --:--:-- --:--:--  192k
          Processed by container ID 6173afd5fab8

[root@node1 netns]# curl node2:8080 | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0   7551      0 --:--:-- --:--:-- --:--:--  7546
          Processed by container ID b07e95c5c681

在 node2 上通過 node1 的 IP 和 8080 端口請(qǐng)求 vote 服務(wù):

[root@node2 ~]# curl node1:8080 | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0   7531      0 --:--:-- --:--:-- --:--:--  7546
          Processed by container ID 6173afd5fab8

[root@node2 ~]# curl node1:8080 | grep -i "container id"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3162  100  3162    0     0   169k      0 --:--:-- --:--:-- --:--:--  171k
          Processed by container ID b07e95c5c681
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缘薛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子卡睦,更是在濱河造成了極大的恐慌宴胧,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件表锻,死亡現(xiàn)場(chǎng)離奇詭異恕齐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瞬逊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門显歧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仪或,“玉大人,你說我怎么就攤上這事士骤》渡荆” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵拷肌,是天一觀的道長到旦。 經(jīng)常有香客問我,道長巨缘,這世上最難降的妖魔是什么添忘? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮若锁,結(jié)果婚禮上搁骑,老公的妹妹穿的比我還像新娘。我一直安慰自己又固,他們只是感情好仲器,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著口予,像睡著了一般娄周。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沪停,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天煤辨,我揣著相機(jī)與錄音,去河邊找鬼木张。 笑死众辨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舷礼。 我是一名探鬼主播鹃彻,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼妻献!你這毒婦竟也來了蛛株?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤育拨,失蹤者是張志新(化名)和其女友劉穎谨履,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熬丧,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笋粟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片害捕。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绿淋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尝盼,到底是詐尸還是另有隱情吞滞,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布东涡,位于F島的核電站冯吓,受9級(jí)特大地震影響倘待,放射性物質(zhì)發(fā)生泄漏疮跑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一凸舵、第九天 我趴在偏房一處隱蔽的房頂上張望祖娘。 院中可真熱鬧,春花似錦啊奄、人聲如沸渐苏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琼富。三九已至,卻和暖如春庄新,著一層夾襖步出監(jiān)牢的瞬間鞠眉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工择诈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留械蹋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓羞芍,卻偏偏與公主長得像哗戈,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子荷科,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容