Flannel網(wǎng)絡(luò)方案架構(gòu)方案及原理

一. Flannel 簡(jiǎn)介

flannel是CoreOS提供用于解決Dokcer集群跨主機(jī)通訊的覆蓋網(wǎng)絡(luò)工具晤硕。它的主要思路是:預(yù)先留出一個(gè)網(wǎng)段,每個(gè)主機(jī)使用其中一部分烙博,然后每個(gè)容器被分配不同的ip霞丧;讓所有的容器認(rèn)為大家在同一個(gè)直連的網(wǎng)絡(luò)竹揍,底層通過(guò)`UDP/VxLAN`等進(jìn)行報(bào)文的封裝和轉(zhuǎn)發(fā)。

Flannel目前支持網(wǎng)絡(luò)模式

UDP: 使用用戶(hù)態(tài)udp封裝,默認(rèn)使用8285端口唬复。由于是在用戶(hù)態(tài)封裝和解包控漠,性能上有較大的損失

VXLAN: vxlan封裝蔓倍,需要配置VNI,Port(默認(rèn)8472)和GBP;  是Linux內(nèi)核本身支持的一種網(wǎng)絡(luò)虛擬化技術(shù)盐捷,是內(nèi)核的一個(gè)模塊偶翅,在內(nèi)核態(tài)實(shí)現(xiàn)封裝解封裝,構(gòu)建出覆蓋網(wǎng)絡(luò)碉渡,其實(shí)就是一個(gè)由各宿主機(jī)上的Flannel.1設(shè)備組成的虛擬二層網(wǎng)絡(luò)聚谁,由于VXLAN由于額外的封包解包,導(dǎo)致其性能較差;VXLAN Directrouting模式也支持類(lèi)似host-gw的玩法滞诺,如果兩個(gè)節(jié)點(diǎn)在同一網(wǎng)段時(shí)使用host-gw通信形导,如果不在同一網(wǎng)段中,即 當(dāng)前pod所在節(jié)點(diǎn)與目標(biāo)pod所在節(jié)點(diǎn)中間有路由器习霹,就使用VXLAN這種方式朵耕,使用疊加網(wǎng)絡(luò)

Host-gw: 直接路由的方式,將容器網(wǎng)絡(luò)的路由信息直接更新到主機(jī)的路由表中序愚,僅適用于二層直接可達(dá)的網(wǎng)絡(luò)  推薦使用憔披,效率極高

Flannel 工作模式及架構(gòu)

flannel.png

1 UDP模式

 Udp方式是Flannel項(xiàng)目最早支持的,也是性能最差的一種爸吮。目前已經(jīng)被棄用芬膝,不過(guò),這種方式最直接形娇、也是最容易理解的跨主機(jī)實(shí)現(xiàn)锰霜。

1.1 UDP模式架構(gòu)圖

image.png

1.2 UDP 數(shù)據(jù)流向

1) 容器直接使用目標(biāo)容器的ip訪(fǎng)問(wèn),默認(rèn)通過(guò)容器內(nèi)部的eth0發(fā)送出去桐早。

2) 報(bào)文通過(guò)veth pair被發(fā)送到vethXXX癣缅。

3) vethXXX是直接連接到虛擬交換機(jī)docker0的,報(bào)文通過(guò)虛擬bridge docker0發(fā)送出去哄酝。

4) 由表友存,外部容器ip的報(bào)文都會(huì)轉(zhuǎn)發(fā)到flannel0虛擬網(wǎng)卡,這是一個(gè)P2P的虛擬網(wǎng)卡陶衅,然后報(bào)文就被轉(zhuǎn)發(fā)到監(jiān)聽(tīng)在另一端的flanneld屡立。

5) flanneld通過(guò)etcd維護(hù)了各個(gè)節(jié)點(diǎn)之間的路由表,把原來(lái)的報(bào)文UDP封裝一層搀军,通過(guò)配置的iface發(fā)送出去膨俐。

6)報(bào)文通過(guò)主機(jī)之間的網(wǎng)絡(luò)找到目標(biāo)主機(jī)勇皇。

7) 報(bào)文繼續(xù)往上,到傳輸層焚刺,交給監(jiān)聽(tīng)在8285端口的flanneld程序處理敛摘。

8) 數(shù)據(jù)被解包,然后發(fā)送給flannel0虛擬網(wǎng)卡乳愉。

9) 查找路由表兄淫,發(fā)現(xiàn)對(duì)應(yīng)容器的報(bào)文要交給docker0。

10) docker0找到連到自己的容器蔓姚,把報(bào)文發(fā)送過(guò)去拖叙。

2 VXLAN 模式

Vxlan(Virtual eXtensible LAN),虛擬可擴(kuò)展的局域網(wǎng),是一種虛擬化隧道通信技術(shù),他是一種overlay(覆蓋網(wǎng)絡(luò))技術(shù),通過(guò)三層的網(wǎng)絡(luò)搭建虛擬的二層網(wǎng)絡(luò)

Vxlan是再底層物理網(wǎng)絡(luò)(underlay)之上使用隧道技術(shù)赂乐,依托UDP層構(gòu)建的overlay的邏輯網(wǎng)絡(luò),使邏輯網(wǎng)絡(luò)與物理網(wǎng)絡(luò)解耦,實(shí)現(xiàn)靈活的組網(wǎng)需求,不僅能使適配虛擬機(jī)環(huán)境,還用適用于容器環(huán)境

1).VXLAN 支持更多子網(wǎng)(VLAN支持吃2的12次方子網(wǎng)即為4096個(gè)子網(wǎng),Vxlan支持2的24方個(gè)子網(wǎng)),并通過(guò)VNI(Virtual Network identifier)區(qū)分不同 的子網(wǎng),相當(dāng)于VLAN中的LAN ID

2).多租戶(hù)網(wǎng)絡(luò)隔離,不同用戶(hù)之間需要獨(dú)立地分配IP和MAC地址

3).云計(jì)算業(yè)務(wù)對(duì)業(yè)務(wù)靈活性要求很高咖气,虛擬機(jī)可能會(huì)大規(guī)模遷移挨措,并保證網(wǎng)絡(luò)一直可用。解決這個(gè)問(wèn)題同時(shí)保證二層的廣播域不會(huì)過(guò)分?jǐn)U大崩溪,這也是云計(jì)算網(wǎng)絡(luò)的要求

2.1 VXLAN 組網(wǎng)模式

Network Overlay 隧道封裝在物理交換機(jī)完成浅役。這種Overlay的優(yōu)勢(shì)在于物理網(wǎng)絡(luò)設(shè)備性能轉(zhuǎn)發(fā)性能比較高,可以支持非虛擬化的物理服務(wù)器之間的組網(wǎng)互通伶唯。
Host Overlay 隧道封裝在vSwitch觉既、具備VXLAN功能的軟件完成,不用增加新的網(wǎng)絡(luò)設(shè)備即可完成Overlay部署乳幸,可以支持虛擬化的服務(wù)器之間的組網(wǎng)互通瞪讼。
Hybrid Overlay是Network Overlay和Host Overlay的混合組網(wǎng),可以支持物理服務(wù)器和虛擬服務(wù)器之間的組網(wǎng)互通粹断。

2.2 VXLAN 架構(gòu)圖

image.png

2.3 VXLAN 數(shù)據(jù)流向

1) 源容器veth0向目標(biāo)容器發(fā)送數(shù)據(jù)符欠,根據(jù)容器內(nèi)的默認(rèn)路由,數(shù)據(jù)首先發(fā)送給宿主機(jī)的docker0網(wǎng)橋

2)宿主機(jī)docker0網(wǎng)橋接受到數(shù)據(jù)后瓶埋,宿主機(jī)查詢(xún)路由表希柿,pod相關(guān)的路由都是交由flannel.1網(wǎng)卡,因此养筒,將其轉(zhuǎn)發(fā)給flannel.1虛擬網(wǎng)卡處理

3)flannel.1接受到數(shù)據(jù)后曾撤,查詢(xún)etcd數(shù)據(jù)庫(kù),獲取目標(biāo)pod網(wǎng)段對(duì)應(yīng)的目標(biāo)宿主機(jī)地址晕粪、目標(biāo)宿主機(jī)的flannel網(wǎng)卡的mac地址挤悉、vxlan vnid等信息。然后對(duì)數(shù)據(jù)進(jìn)行udp封裝如下:

udp頭封裝:

source port >1024兵多,target port 8427

udp內(nèi)部封裝:

  vxlan封裝:vxlan vnid等信息

  original layer 2 frame封裝:source {源 flannel.1網(wǎng)卡mac地址} target{目標(biāo)flannel.1網(wǎng)卡的mac地址}

完成以上udp封裝后尖啡,將數(shù)據(jù)轉(zhuǎn)發(fā)給物理機(jī)的eth0網(wǎng)卡

4)宿主機(jī)eth0接收到來(lái)自flannel.1的udp包橄仆,還需要將其封裝成正常的通信用的數(shù)據(jù)包,為它加上通用的ip頭衅斩、二層頭盆顾,這項(xiàng)工作在由linux內(nèi)核來(lái)完成。

Ethernet Header的信息:

source:{源宿主機(jī)機(jī)網(wǎng)卡的MAC地址}

target:{目標(biāo)宿主機(jī)網(wǎng)卡的MAC地址}

IP Header的信息:

source:{源宿主機(jī)網(wǎng)卡的IP地址}

target:{目標(biāo)宿主機(jī)網(wǎng)卡的IP地址}

通過(guò)此次封裝畏梆,一個(gè)真正可用的數(shù)據(jù)包就封裝完成您宪,可以通過(guò)物理網(wǎng)絡(luò)傳輸了。

5)目標(biāo)宿主機(jī)的eth0接收到數(shù)據(jù)后奠涌,對(duì)數(shù)據(jù)包進(jìn)行拆封宪巨,拆到udp層后,將其轉(zhuǎn)發(fā)給8427端口的flannel進(jìn)程

6)目標(biāo)宿主機(jī)端flannel拆除udp頭溜畅、vxlan頭捏卓,獲取到內(nèi)部的原始數(shù)據(jù)幀,在原始數(shù)據(jù)幀內(nèi)部慈格,解析出源容器ip怠晴、目標(biāo)容器ip,重新封裝成通用的數(shù)據(jù)包浴捆,查詢(xún)路由表蒜田,轉(zhuǎn)發(fā)給docker0網(wǎng)橋;

7)最后选泻,docker0網(wǎng)橋?qū)?shù)據(jù)送達(dá)目標(biāo)容器內(nèi)的veth0網(wǎng)卡冲粤,完成容器之間的數(shù)據(jù)通信

3 Host-GW方式

flannel的udp模式和vxlan模式都是屬于隧道方式,也就是在udp的基礎(chǔ)之上页眯,構(gòu)建虛擬網(wǎng)絡(luò)梯捕,host-gw模式是個(gè)例外,host-gw模式屬于路由的方式餐茵,由于沒(méi)有經(jīng)過(guò)任何封裝科阎,純路由實(shí)現(xiàn),數(shù)據(jù)只經(jīng)過(guò)協(xié)議棧一次忿族,因此性能比較高;
host-gw模式通過(guò)建立主機(jī)IP到主機(jī)上對(duì)應(yīng)flannel子網(wǎng)的mapping锣笨,以直接路由的方式聯(lián)通flannel的各個(gè)子網(wǎng)。這種互聯(lián)方式?jīng)]有vxlan等封裝方式帶來(lái)的負(fù)擔(dān)道批,通過(guò)路由機(jī)制错英,實(shí)現(xiàn)flannel網(wǎng)絡(luò)數(shù)據(jù)包在主機(jī)之間的轉(zhuǎn)發(fā)。但是這種方式也有不足隆豹,那就是所有節(jié)點(diǎn)之間都要相互有點(diǎn)對(duì)點(diǎn)的路由覆蓋椭岩,并且所有加入flannel網(wǎng)絡(luò)的主機(jī)需要在同一個(gè)LAN里面;所以每個(gè)節(jié)點(diǎn)上有n-1個(gè)路由,而n個(gè)節(jié)點(diǎn)一共有n(n-1)/2個(gè)路由以保證flannel的flat網(wǎng)絡(luò)能力
host-gw的工作原理判哥,其實(shí)就是在宿主機(jī)上献雅,添加一條到達(dá)每個(gè)fannel子網(wǎng)的路由,這條路由的下一跳即網(wǎng)關(guān)就是相對(duì)應(yīng)的fannel子網(wǎng)所在的“主機(jī)”塌计。這些路由規(guī)則是flanneld根據(jù)容器部署的場(chǎng)景創(chuàng)建和更新的

3.1 Host-GW 架構(gòu)圖

image.png

3.2 Host-GW 數(shù)據(jù)流向

1)源容器veth0向目標(biāo)容器發(fā)送數(shù)據(jù)挺身,根據(jù)容器內(nèi)的默認(rèn)路由,數(shù)據(jù)首先發(fā)送給宿主機(jī)的docker0網(wǎng)橋锌仅,并進(jìn)入內(nèi)核協(xié)議棧

2)經(jīng)過(guò)netfilter的PREROUTING章钾,再進(jìn)入到路由子系統(tǒng),此時(shí)由于宿主機(jī)沒(méi)有任何額外的設(shè)備热芹,**匹配到默認(rèn)路由**,從宿主機(jī)的eth0發(fā)出,數(shù)據(jù)包直接發(fā)送至目的節(jié)點(diǎn)所在的宿主機(jī)

3)  數(shù)據(jù)幀通過(guò)宿主機(jī)的二層網(wǎng)絡(luò)順利到達(dá)節(jié)點(diǎn)目的節(jié)點(diǎn)

二. Flannel 安裝部署:

1 部署環(huán)境

image.png

2 安裝部署

  #tar -xf flannel-v0.13.0.tar.gz

 #mv /apps/svr/flannel-v0.13.0

 #ln –svfn /apps/svr/flannel-v0.13.0 /apps/svr/flannel

2.1 調(diào)整Flannel配置文件

#cd /apps/conf/flannel

#cat flannel.cfg

# Flanneld configuration options 

# etcd url location. Point this to the server where etcd runs

ETCD_ENDPOINTS="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379"

# etcd config key. This is the configuration key that flannel queries

# For address range assignment

ETCD_PREFIX="/flannel/network"

# Any additional options that you want to pass

FLANNEL_OPTIONS="-iface=bond0"

2.2 啟動(dòng)命令

#cd /usr/libs/systemd/system
#cat flannel.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
#Before=docker.service

[Service]
Type=notify
EnvironmentFile=/apps/conf/flannel/flannel.cfg
ExecStart=/apps/svr/flannel/bin/flanneld \
 -etcd-endpoints=${ETCD_ENDPOINTS} \
 -etcd-prefix=${ETCD_PREFIX} \
 $FLANNEL_OPTIONS
ExecStartPost=/apps/svr/flannel/bin/mk-docker-opts.sh -d /run/flannel/subnet.env
Restart=on-failure
LimitNOFILE=1000000
LimitNPROC=1000000
LimitCORE=1000000
[Install]
WantedBy=multi-user.target

2.3 調(diào)整docker啟動(dòng)配置,增加flannel subnet.env環(huán)境變量,并重啟docker進(jìn)程

#vim /usr/libs/system/system/docker.service
[Service]
Type=notify
EnvironmentFile=-/run/flannel/subnet.env
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd $DOCKER_OPTS -H fd:// --containerd=/run/containerd/containerd.sock
#systemctl daemon-reload
#systemctl restart docker

2.4 通過(guò)etcd設(shè)置flannel管理的網(wǎng)段及flannel工作模式

#設(shè)置vxlan
/apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "vxlan"}}'
#設(shè)置vxlan Directrouting
/apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "vxlan","Directrouting": true }}'

#設(shè)置HOST-GW 模式
 /apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "host-gw" }}'
#設(shè)置UDP模式
/apps/svr/etcd/sbin/etcdctl \
--endpoints="http://10.65.6.3:2379,http://10.65.6.4:2379,http://10.65.6.5:2379" set /flannel/network/config '{"Network":"10.80.0.0/16", "SubnetLen": 24, "Backend": {"Type": "udp" }}'

2.5 查看flannel.1網(wǎng)卡及路由信息

# ifconfig flannel.1
flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
 inet 10.80.58.0 netmask 255.255.255.255 broadcast 10.80.58.0
 inet6 fe80::74f9:1bff:fe63:37 prefixlen 64 scopeid 0x20<link>
 ether 76:f9:1b:63:00:37 txqueuelen 0 (Ethernet)
 RX packets 161301 bytes 34062775 (32.4 MiB)
 RX errors 0 dropped 0 overruns 0 frame 0
 TX packets 88102 bytes 53006628 (50.5 MiB)
 TX errors 0 dropped 5 overruns 0 carrier 0 collisions 0
  到mtu為1450(IP頭贱傀、UDP頭、MAC頭伊脓、vxlan協(xié)議共占了50)

# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
 inet 10.80.58.1 netmask 255.255.255.0 broadcast 10.80.58.255
 inet6 fe80::42:e0ff:fe58:276b prefixlen 64 scopeid 0x20<link>
 ether 02:42:e0:58:27:6b txqueuelen 0 (Ethernet)
 RX packets 51631431 bytes 5646040919 (5.2 GiB)
 RX errors 0 dropped 0 overruns 0 frame 0
 TX packets 55496509 bytes 14532143853 (13.5 GiB)
 TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

2.6 查看路由

# ip route show
default via 10.65.4.254 dev bond0.100
10.65.4.0/24 dev bond0.100 proto kernel scope link src 10.65.4.1
10.80.20.0/24 via 10.80.20.0 dev flannel.1 onlink
10.80.27.0/24 via 10.80.27.0 dev flannel.1 onlink
10.80.58.0/24 dev docker0 proto kernel scope link src 10.80.58.1
169.254.0.0/16 dev bond0 scope link metric 1006
169.254.0.0/16 dev bond0.100 scope link metric 1007
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末府寒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子报腔,更是在濱河造成了極大的恐慌椰棘,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榄笙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡祷蝌,警方通過(guò)查閱死者的電腦和手機(jī)茅撞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)巨朦,“玉大人米丘,你說(shuō)我怎么就攤上這事『龋” “怎么了拄查?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)棚蓄。 經(jīng)常有香客問(wèn)我堕扶,道長(zhǎng),這世上最難降的妖魔是什么梭依? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任稍算,我火速辦了婚禮,結(jié)果婚禮上役拴,老公的妹妹穿的比我還像新娘糊探。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布科平。 她就那樣靜靜地躺著褥紫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瞪慧。 梳的紋絲不亂的頭發(fā)上髓考,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音汞贸,去河邊找鬼绳军。 笑死,一個(gè)胖子當(dāng)著我的面吹牛矢腻,可吹牛的內(nèi)容都是我干的门驾。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼多柑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼奶是!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起竣灌,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤聂沙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后初嘹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體及汉,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年屯烦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坷随。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驻龟,死狀恐怖温眉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翁狐,我是刑警寧澤类溢,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站露懒,受9級(jí)特大地震影響闯冷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜懈词,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一窃躲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钦睡,春花似錦蒂窒、人聲如沸躁倒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)秧秉。三九已至,卻和暖如春衰抑,著一層夾襖步出監(jiān)牢的瞬間象迎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工呛踊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砾淌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓谭网,卻偏偏與公主長(zhǎng)得像汪厨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子愉择,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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