<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一文讀懂藍(lán)綠發(fā)布、A/B 測(cè)試和金絲雀發(fā)布的優(yōu)缺點(diǎn)

          共 8522字,需瀏覽 18分鐘

           ·

          2021-12-31 14:10


          01

          背景

          Aliware

          目前,業(yè)界已經(jīng)總結(jié)出了幾種常見的服務(wù)發(fā)布策略來解決版本升級(jí)過程中帶來的流量有損問題。本文首先會(huì)對(duì)這些普遍的發(fā)布策略進(jìn)行簡(jiǎn)單的原理解析,最后結(jié)合阿里云的云原生網(wǎng)關(guān)對(duì)這些發(fā)布策略進(jìn)行實(shí)踐。


          02

          發(fā)布策略

          Aliware

          被業(yè)界廣泛采用的服務(wù)發(fā)布策略包括藍(lán)綠發(fā)布、A/B 測(cè)試以及金絲雀發(fā)布。


          01


          藍(lán)綠發(fā)布


          藍(lán)綠發(fā)布需要對(duì)服務(wù)的新版本進(jìn)行冗余部署,一般新版本的機(jī)器規(guī)格和數(shù)量與舊版本保持一致,相當(dāng)于該服務(wù)有兩套完全相同的部署環(huán)境,只不過此時(shí)只有舊版本在對(duì)外提供服務(wù),新版本作為熱備。當(dāng)服務(wù)進(jìn)行版本升級(jí)時(shí),我們只需將流量全部切換到新版本即可,舊版本作為熱備。由于冗余部署的緣故,所以不必?fù)?dān)心新版本的資源不夠。如果新版本上線后出現(xiàn)嚴(yán)重的程序 BUG,那么我們只需將流量全部切回至舊版本,大大縮短故障恢復(fù)的時(shí)間。待新版本完成 BUG 修復(fù)并重新部署之后,再將舊版本的流量切換到新版本。


          藍(lán)綠發(fā)布通過使用額外的機(jī)器資源來解決服務(wù)發(fā)布期間的不可用問題,當(dāng)服務(wù)新版本出現(xiàn)故障時(shí),也可以快速將流量切回舊版本。


          如圖,某服務(wù)舊版本為 v1,對(duì)新版本 v2 進(jìn)行冗余部署。版本升級(jí)時(shí),將現(xiàn)有流量全部切換為新版本 v2。


          當(dāng)新版本 v2 存在程序 BUG 或者發(fā)生故障時(shí),可以快速切回舊版本 v1。


          藍(lán)綠部署的優(yōu)點(diǎn):
          1、部署結(jié)構(gòu)簡(jiǎn)單,運(yùn)維方便;
          2、服務(wù)升級(jí)過程操作簡(jiǎn)單,周期短。

          藍(lán)綠部署的缺點(diǎn):
          1、資源冗余,需要部署兩套生產(chǎn)環(huán)境;
          2、新版本故障影響范圍大。


          02


          A/B 測(cè)試

          相比于藍(lán)綠發(fā)布的流量切換方式,A/B 測(cè)試基于用戶請(qǐng)求的元信息將流量路由到新版本,這是一種基于請(qǐng)求內(nèi)容匹配的灰度發(fā)布策略。只有匹配特定規(guī)則的請(qǐng)求才會(huì)被引流到新版本,常見的做法包括基于 Http Header 和 Cookie?;?Http Header 方式的例子,例如 User-Agent 的值為 Android 的請(qǐng)求 (來自安卓系統(tǒng)的請(qǐng)求)可以訪問新版本,其他系統(tǒng)仍然訪問舊版本?;?Cookie 方式的例子,Cookie 中通常包含具有業(yè)務(wù)語義的用戶信息,例如普通用戶可以訪問新版本,VIP 用戶仍然訪問舊版本。


          如圖,某服務(wù)當(dāng)前版本為 v1,現(xiàn)在新版本 v2 要上線。希望安卓用戶可以嘗鮮新功能,其他系統(tǒng)用戶保持不變。


          通過在監(jiān)控平臺(tái)觀察舊版本與新版本的成功率、RT 對(duì)比,當(dāng)新版本整體服務(wù)預(yù)期后,即可將所有請(qǐng)求切換到新版本 v2,最后為了節(jié)省資源,可以逐步下線到舊版本 v1。


          A/B 測(cè)試的優(yōu)點(diǎn):
          1、可以對(duì)特定的請(qǐng)求或者用戶提供服務(wù)新版本,新版本故障影響范圍?。?/span>
          2、需要構(gòu)建完備的監(jiān)控平臺(tái),用于對(duì)比不同版本之間請(qǐng)求狀態(tài)的差異。

          A/B 測(cè)試的缺點(diǎn):
          1、仍然存在資源冗余,因?yàn)闊o法準(zhǔn)確評(píng)估請(qǐng)求容量;
          2、發(fā)布周期長(zhǎng)。


          03


          金絲雀發(fā)布


          在藍(lán)綠發(fā)布中,由于存在流量整體切換,所以需要按照原服務(wù)占用的機(jī)器規(guī)模為新版本克隆一套環(huán)境,相當(dāng)于要求原來1倍的機(jī)器資源。在 A/B 測(cè)試中,只要能夠預(yù)估中匹配特定規(guī)則的請(qǐng)求規(guī)模,我們可以按需為新版本分配額外的機(jī)器資源。相比于前兩種發(fā)布策略,金絲雀發(fā)布的思想則是將少量的請(qǐng)求引流到新版本上,因此部署新版本服務(wù)只需極小數(shù)的機(jī)器。驗(yàn)證新版本符合預(yù)期后,逐步調(diào)整流量權(quán)重比例,使得流量慢慢從老版本遷移至新版本,期間可以根據(jù)設(shè)置的流量比例,對(duì)新版本服務(wù)進(jìn)行擴(kuò)容,同時(shí)對(duì)老版本服務(wù)進(jìn)行縮容,使得底層資源得到最大化利用。


          如圖,某服務(wù)當(dāng)前版本為 v1,現(xiàn)在新版本 v2 要上線。為確保流量在服務(wù)升級(jí)過程中平穩(wěn)無損,采用金絲雀發(fā)布方案,逐步將流量從老版本遷移至新版本。


          金絲雀發(fā)布的優(yōu)點(diǎn):
          1、按比例將流量無差別地導(dǎo)向新版本,新版本故障影響范圍?。?/span>
          2、發(fā)布期間逐步對(duì)新版本擴(kuò)容,同時(shí)對(duì)老版本縮容,資源利用率高。

          金絲雀發(fā)布的缺點(diǎn):
          1、流量無差別地導(dǎo)向新版本,可能會(huì)影響重要用戶的體驗(yàn);
          2、發(fā)布周期長(zhǎng)。


          03

          實(shí)踐

          Aliware

          接下來,我們會(huì)基于阿里云的容器運(yùn)維平臺(tái) ACK 以及 MSE 云原生網(wǎng)關(guān)對(duì)以上介紹的三種發(fā)布策略進(jìn)行實(shí)踐。這里我們采用最簡(jiǎn)單的業(yè)務(wù)架構(gòu)來展示,即一個(gè)云原生網(wǎng)關(guān)、一個(gè)后端服務(wù)(響應(yīng)中返回當(dāng)前版本信息)和注冊(cè)中心。注冊(cè)中心決定了業(yè)務(wù)架構(gòu)中服務(wù)發(fā)現(xiàn)方式,我們會(huì)分別以 K8s 容器服務(wù)和 Nacos 兩種服務(wù)發(fā)現(xiàn)機(jī)制來實(shí)踐不同的發(fā)布策略。


          01


          前提條件


          • 創(chuàng)建了阿里云容器運(yùn)維平臺(tái) ACK
          • 創(chuàng)建了 MSE 云原生網(wǎng)關(guān)
          • 創(chuàng)建了 MSE 注冊(cè)中心 Nacos(服務(wù)發(fā)現(xiàn)方式為 Nacos 時(shí)需要)


          02


          服務(wù)發(fā)現(xiàn)方式:K8s 容器服務(wù)


          在這個(gè)例子中,我們使用 K8s 原生的服務(wù)發(fā)現(xiàn)方式,即通過聲明式 Service API 資源將后端服務(wù)注冊(cè)到 CoreDNS。例子中的后端服務(wù)提供一個(gè)查詢當(dāng)前版本的接口/version,并且當(dāng)前版本為 v1。云原生網(wǎng)關(guān)深度集成 ACK,可以實(shí)時(shí)動(dòng)態(tài)地從 ACK 集群中獲取服務(wù)信息,方便通過云原生網(wǎng)關(guān)將該后端服務(wù)暴露給外部用戶。


          業(yè)務(wù)架構(gòu)如下圖:


          1、部署


          將以下資源(Service和Deployment)應(yīng)用到 ACK 集群,完成后端服務(wù)的部署和發(fā)布,當(dāng)前應(yīng)用版本為 v1。
          apiVersion: v1kind: Servicemetadata:  name: httpbinspec:  ports:  - port: 8080    protocol: TCP  selector:    app: httpbin---apiVersion: apps/v1kind: Deploymentmetadata:  name: httpbin-v1spec:  replicas: 3  selector:    matchLabels:      app: httpbin      version: v1  template:    metadata:      labels:        app: httpbin        version: v1    spec:      containers:      - image: specialyang/spring-cloud-httpbin-k8s:v1        imagePullPolicy: Always        name: spring-cloud-httpbin-k8s        ports:        - containerPort: 8080

          在云原生網(wǎng)關(guān)的服務(wù)管理->來源管理中,添加目標(biāo) ACK 集群。


          在服務(wù)管理中導(dǎo)入要暴露給云原生網(wǎng)關(guān)的服務(wù) httpbin。


          在 httpbin 服務(wù)的策略配置中添加服務(wù)版本 v1,注意需要選擇對(duì)應(yīng)的標(biāo)簽來篩選出 v1 版本的節(jié)點(diǎn),因?yàn)槟壳拔覀冎徊渴鹆?v1 版本,所以 v1 版本的節(jié)點(diǎn)數(shù)占總實(shí)例數(shù) 100%。


          在路由管理中為該服務(wù)創(chuàng)建一條路由規(guī)則,從而將服務(wù)暴露給外部用戶。httpbin 服務(wù)暴露的 api 的 path 為/version,請(qǐng)求轉(zhuǎn)發(fā)至服務(wù) httpbin 的 v1 版本。


          執(zhí)行以下腳本測(cè)試請(qǐng)求的響應(yīng)結(jié)果。
          for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo "";  doneversion: v1version: v1version: v1version: v1version: v1version: v1version: v1version: v1version: v1version: v1

          2、藍(lán)綠部署


          藍(lán)綠部署需要按照服務(wù)當(dāng)前版本所占用的資源狀況為服務(wù)新版本申請(qǐng)同樣的資源規(guī)格,部署完畢之后將流量整體切換到服務(wù)新版本。


          利用 K8s 的聲明式 API 資源部署 httpbin 服務(wù)的新版本 v2,副本數(shù)同樣是 3。
          apiVersion: apps/v1kind: Deploymentmetadata:  name: httpbin-v2spec:  replicas: 3  selector:    matchLabels:      app: httpbin      version: v2  template:    metadata:      labels:        app: httpbin        version: v2    spec:      containers:      - image: specialyang/spring-cloud-httpbin-k8s:v2        imagePullPolicy: Always        name: spring-cloud-httpbin-k8s        ports:        - containerPort: 8080

          在 httpbin 服務(wù)的策略配置中添加服務(wù)版本 v2,注意需要選擇對(duì)應(yīng)的標(biāo)簽來篩選出 v2 版本的節(jié)點(diǎn),集群中現(xiàn)在 v1 和 v2 版本的節(jié)點(diǎn)數(shù)一致,所以各占 50%。


          現(xiàn)在,我們開始利用藍(lán)綠發(fā)布的思想將流量從 v1 整體切換至 v2,僅需要之前修改上面創(chuàng)建的路由規(guī)則中目標(biāo)服務(wù)即可。


          執(zhí)行以下腳本測(cè)試請(qǐng)求的響應(yīng)結(jié)果。
          for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo "";  doneversion: v2version: v2version: v2version: v2version: v2version: v2version: v2version: v2version: v2version: v2

          現(xiàn)在我們發(fā)現(xiàn)訪問 api 資源/version 的請(qǐng)求的流量已經(jīng)全部從 v1 切換至 v2。


          3、A/B測(cè)試


          A/B 測(cè)試基于用戶請(qǐng)求的元信息將流量路由到新版本,換句話說,就是可以根據(jù)請(qǐng)求內(nèi)容來動(dòng)態(tài)路由。舉個(gè)例子,我們希望 User-Agent 的值為 Android 的請(qǐng)求 (來自安卓系統(tǒng)的請(qǐng)求)可以訪問新版本,其他系統(tǒng)仍然訪問舊版本。


          我們?nèi)匀焕蒙厦鎸?shí)踐中部署的 httpbin 的 v1,v2 的 deployment。此外,需要?jiǎng)?chuàng)建兩條路由規(guī)則:
          • 匹配 path 為/version 的請(qǐng)求訪問服務(wù)版本 v1


          • 匹配 path 為/version,且 User-Agent 頭部含有 Android 的請(qǐng)求訪問服務(wù)版本 v2




          注意相比 version 路由規(guī)則,version-v2 的路由規(guī)則中需要增加請(qǐng)求頭匹配規(guī)則。

          通過以下腳本測(cè)試 A/B test 的效果。
          // user agent中不含有 androidcurl ${GATEWAY_EXTERNAL_IP}/versionversion: v1
          // user agent中含有 androidcurl -H "User-Agent: Mozilla/5.0 (Linux; Android 4.0.3)" ${GATEWAY_EXTERNAL_IP}/versionversion: v2

          可以看出,當(dāng)前請(qǐng)求會(huì)按照來源的操作系統(tǒng)對(duì)流量進(jìn)行分流。

          4、金絲雀發(fā)布


          金絲雀發(fā)布允許引流一小部分流量到服務(wù)新版本,待驗(yàn)證通過后,逐步調(diào)大流量,直至切流完畢,期間可伴隨著新版本的擴(kuò)容,舊版本的縮容操作,達(dá)到資源利用率最大化。


          在金絲雀發(fā)布策略中,服務(wù)新版本的副本初始部署數(shù)無需與原始保持一致。僅需保持資源始終滿足灰度流量,所以我們將新版本的副本數(shù)調(diào)為 1,可以在服務(wù)策略中服務(wù)版本模塊看到當(dāng)前各版本節(jié)點(diǎn)數(shù)的占比情況。


          清除掉其他發(fā)布策略遺留的路由規(guī)則,我們新創(chuàng)建一條路由規(guī)則,在目標(biāo)服務(wù)中按照權(quán)重將流量轉(zhuǎn)發(fā)至新舊版本。


          其中,目標(biāo)服務(wù)需要配置兩個(gè)目的地,httpbin 的 v1 和 v2 版本,并設(shè)置對(duì)應(yīng)的流量比。


          通過以下腳本測(cè)試金絲雀發(fā)布的效果。
          for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo "";  doneversion: v1version: v1version: v1version: v1version: v1version: v2version: v1version: v2version: v1version: v1

          在以上測(cè)試結(jié)果中,可以發(fā)現(xiàn) 10 個(gè)請(qǐng)求中,有 2 個(gè)是訪問的新版本 v2,其流量比確實(shí)符合期望的 8:2。


          在真實(shí)業(yè)務(wù)場(chǎng)景中,新版本驗(yàn)證完畢后,就可以繼續(xù)調(diào)大訪問新版本的流量權(quán)重,期間注意對(duì)新版本擴(kuò)容,按需對(duì)舊版本縮容。

          03


          服務(wù)發(fā)現(xiàn)方式:Nacos 注冊(cè)中心


          Kubernetes 平臺(tái)為容器化應(yīng)用帶來了動(dòng)態(tài)彈性,加快了應(yīng)用交付進(jìn)程,提高了底層資源的利用率,但在服務(wù)發(fā)現(xiàn)能力上,相比其他主流注冊(cè)中心 Nacos、Consul 等,其功能完整性、可用性上略顯不足。因此,即使大部分業(yè)務(wù)應(yīng)用已經(jīng)遷移至 Kubernetes 運(yùn)維平臺(tái),但仍然選擇為業(yè)務(wù)保留了原始的注冊(cè)中心。

          針對(duì)這種業(yè)務(wù)場(chǎng)景,我們額外舉例當(dāng)使用 Nacos 注冊(cè)中心時(shí),如何為服務(wù)進(jìn)行藍(lán)綠發(fā)布、A/B 測(cè)試和金絲雀發(fā)布。例子中的后端服務(wù)提供一個(gè)查詢當(dāng)前版本的接口/version,并且當(dāng)前版本為 v1。云原生網(wǎng)關(guān)深度集成 MSE Nacos 注冊(cè)中心,可以實(shí)時(shí)動(dòng)態(tài)地從 Nacos 實(shí)例中獲取服務(wù)信息,方便通過云原生網(wǎng)關(guān)將該后端服務(wù)暴露給外部用戶。


          業(yè)務(wù)架構(gòu)如下圖:


          01


          部署


          將以下資源(Deployment)應(yīng)用到 ACK 集群,完成后端服務(wù)的部署,并將服務(wù)發(fā)布到 Nacos 注冊(cè)中心,當(dāng)前應(yīng)用版本為 v1。需要注意以下幾點(diǎn):

          1、該 yaml 資源中變量${NACOS_SERVER_ADDRESS}需要替換為你的 MSE Nacos 地址,如果和網(wǎng)關(guān)在一個(gè) VPC,那么內(nèi)網(wǎng)域名即可;否則,你需要配置公網(wǎng)域名。

          2、在 K8s Service 服務(wù)發(fā)現(xiàn)中,Pod 中 Labels 信息可看做是節(jié)點(diǎn)的元數(shù)據(jù)信息。而在 Nacos 注冊(cè)中心中,節(jié)點(diǎn)的元數(shù)據(jù)信息取決于服務(wù)注冊(cè)時(shí)攜帶的信息。在 Spring Cloud 框架中,通過環(huán)境變量 spring.cloud.nacos.discovery.metadata.xxx 無侵入式為節(jié)點(diǎn)添加元數(shù)據(jù)信息,在該例子中,我們以 version 作為版本標(biāo)用來區(qū)分不同版本的節(jié)點(diǎn)。因此,需要為業(yè)務(wù)容器添加環(huán)境變量 spring.cloud.nacos.discovery.metadata.version=v1。
          apiVersion: apps/v1kind: Deploymentmetadata:  name: httpbin-v1spec:  replicas: 3  selector:    matchLabels:      app: httpbin  template:    metadata:      labels:        app: httpbin    spec:      containers:      - image: specialyang/spring-cloud-httpbin-nacos:v1        imagePullPolicy: Always        name: spring-cloud-httpbin-nacos        ports:        - containerPort: 8080        env:        - name: spring.cloud.nacos.discovery.server-addr          value: ${NACOS_SERVER_ADDRESS}        - name: spring.cloud.nacos.discovery.metadata.version          value: v1

          在云原生網(wǎng)關(guān)的服務(wù)管理->來源管理中,添加目標(biāo) MSE Nacos 注冊(cè)中心集群。


          在服務(wù)管理中導(dǎo)入要暴露給云原生網(wǎng)關(guān)的服務(wù) httpbin,注意服務(wù)來源選擇 MSE Nacos 注冊(cè)中心。


          與 K8s Service 服務(wù)發(fā)現(xiàn)的例子一樣,在策略配置中添加服務(wù)版本 v1,標(biāo)簽名和標(biāo)簽值可以選擇為我們?cè)?httpbin 服務(wù)注冊(cè)時(shí)添加的元數(shù)據(jù)信息 version=v1。之后配置路由匹配 path為/version 的請(qǐng)求轉(zhuǎn)發(fā)至 httpbin 服務(wù)的 v1 版本。


          執(zhí)行以下腳本測(cè)試請(qǐng)求的響應(yīng)結(jié)果。
          for i in {1..10}; do curl "${GATEWAY_EXTERNAL_IP}/version"; echo "";  doneversion: v1version: v1version: v1version: v1version: v1version: v1version: v1version: v1version: v1version: v1

          02


          藍(lán)綠部署


          其發(fā)布策略如下圖所示:


          部署 httpbin 服務(wù)的新版本 v2,注意注冊(cè)中心與上面保持一致,同時(shí)為業(yè)務(wù)容器增加環(huán)境變量 spring.cloud.nacos.discovery.metadata.version=v2,業(yè)務(wù)應(yīng)用啟動(dòng)時(shí)會(huì)向指定 Nacos 注冊(cè)服務(wù),同時(shí)攜帶上用戶自定義的元數(shù)據(jù)信息。云原生網(wǎng)關(guān)可以利用這些元數(shù)據(jù)信息來對(duì)節(jié)點(diǎn)區(qū)分不同的版本。
          apiVersion: apps/v1kind: Deploymentmetadata:  name: httpbin-v2spec:  replicas: 3  selector:    matchLabels:      app: httpbin  template:    metadata:      labels:        app: httpbin    spec:      containers:      - image: specialyang/spring-cloud-httpbin-nacos:v2        imagePullPolicy: Always        name: spring-cloud-httpbin-nacos        ports:        - containerPort: 8080        env:        - name: spring.cloud.nacos.discovery.server-addr          value: ${NACOS_SERVER_ADDRESS}        - name: spring.cloud.nacos.discovery.metadata.version          value: v2

          與 K8s Service 的例子中藍(lán)綠發(fā)布操作一樣,在 httpbin 服務(wù)的策略配置中添加服務(wù)版本 v2,然后將路由規(guī)則中的目標(biāo)服務(wù) httpbin 的 v1 版本修改為 v2 版本,發(fā)布成功之后,查看請(qǐng)求結(jié)果全部為 version: v2。

          3、A/B 測(cè)試


          其發(fā)布策略如下圖所示:


          我們同樣用之前的例子,User-Agent 的值為 Android 的請(qǐng)求 (來自安卓系統(tǒng)的請(qǐng)求)可以訪問新版本,其他系統(tǒng)仍然訪問舊版本。涉及的路由規(guī)則的操作、與驗(yàn)證方式與 K8s Service 的例子一致。


          4、金絲雀發(fā)布

          其發(fā)布策略如下圖所示:


          同樣,涉及的路由規(guī)則的操作、與驗(yàn)證方式與 K8s Service 的例子一致。


          04

          總結(jié)

          Aliware

          本文對(duì)常見的發(fā)布策略進(jìn)行了簡(jiǎn)單介紹和原理解析,并以圖文并茂的方式對(duì)每個(gè)發(fā)布策略進(jìn)行了詳細(xì)探討,總結(jié)如下:

          • 藍(lán)綠發(fā)布:簡(jiǎn)單理解就是流量切換,依據(jù)熱備的思想,冗余部署服務(wù)新版本。
          • A/B 測(cè)試:簡(jiǎn)單理解就是根據(jù)請(qǐng)求內(nèi)容(header、cookie)將請(qǐng)求流量路由到服務(wù)的不同版本。
          • 金絲雀發(fā)布:是一種基于流量比例的發(fā)布策略,部署一個(gè)或者一小批新版本的服務(wù),將少量(比如 1%)的請(qǐng)求引流到新版本,逐步調(diào)大流量比重,直到所有用戶流量都被切換新版本為止。


          云原生網(wǎng)關(guān)以托管的方式來作為您的流量入口,提供了豐富的流量治理能力,支持多種服務(wù)發(fā)現(xiàn)方式,如 K8s Service、Nacos、Eurake、ECS 和域名,并以統(tǒng)一的模型支持了服務(wù)版本以及灰度發(fā)布能力。在上面的實(shí)踐中,可以發(fā)現(xiàn)兩種服務(wù)發(fā)現(xiàn)方式僅僅是元數(shù)據(jù)信息所處的位置不同,但服務(wù)版本管理以及路由規(guī)則中的灰度發(fā)布模型都是一致的,您可以輕松學(xué)會(huì)為不同服務(wù)發(fā)現(xiàn)方式的服務(wù)進(jìn)行灰度發(fā)布,確保版本升級(jí)過程中平滑無損。



          瀏覽 29
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  午夜欧美精品久久久久久久 | 狠狠操狠狠操狠狠操 | 99国产精品人妻人伦 | 青青草A∨在线视频免费 | 日韩伦人妻无码 |