成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺析 Kubernetes 多集群調(diào)度方案

系統(tǒng) Linux
本文不會詳細介紹這些項目在部署和網(wǎng)絡管理的內(nèi)容,重點分析兩個項目(Kubefed、Liqo)的跨集群資源調(diào)度。

圖片

Kubernetes 是一個容器編排平臺,用于調(diào)度、部署和管理容器化應用。并且經(jīng)過幾年的發(fā)展,k8s 已經(jīng)成為事實上的容器編排平臺標準。集群是 k8s 架構的構建塊(building block)。集群由多個工作節(jié)點(物理機或者虛擬機)組成,提供一個可供容器運行的資源池。一個集群擁有:

  • 一個單獨的 API 入口
  • 一個集群范圍的資源命名組織結(jié)構
  • 一個調(diào)度域
  • 一個服務路由域
  • ……

每個集群都是獨立的系統(tǒng),可以部署在公司的自建機房,也可以部署在云廠商的一個可用區(qū)。k8s 負責管理集群的可用資源:調(diào)度器將容器調(diào)度到適當?shù)臋C器、kubelet 負責 pod/ 容器的生命周期管理。這些都是大家很熟悉的概念了。但是 k8s 的作用范圍是集群內(nèi),一個集群內(nèi)的控制平面無法感知另一個集群的資源余量和服務狀態(tài)。當多集群的應用場景出現(xiàn)時,我們怎么處理多個集群的調(diào)度呢。

為什么要有多集群調(diào)度?

通常來說,一個集群的大小需要預估業(yè)務的資源總量。當資源不夠時,可以通過增加機器數(shù)量來進行集群擴容。但是集群規(guī)模也不是無限上升的。當節(jié)點 /pod 的數(shù)量越多,對控制平臺的組件的壓力就越大,進而影響集群整體穩(wěn)定性。

  • 單集群的容量限制:單集群的最大節(jié)點數(shù)不是一個確定值,其受到集群的部署方法和業(yè)務使用集群資源的方式的影響。在官方文檔中的集群注意事項里提到單集群 5000 個節(jié)點上限,我們可以理解為推薦最大節(jié)點數(shù)。
  • 多租戶:因為容器沒法做到完美的隔離,不同租戶可以通過不同宿主機或者不同集群分割開。對企業(yè)內(nèi)部也是如此,業(yè)務線就是租戶。不同業(yè)務線對于資源的敏感程度也不同,企業(yè)也會將機器資源劃分為不同集群給不同業(yè)務線用。
  • 云爆發(fā):云爆發(fā)是一種部署模式,通過公有云資源來滿足應用高峰時段的資源需求。正常流量時期,業(yè)務應用部署在有限資源的集群里。當資源需求量增加,通過擴容到公有云來消減高峰壓力。
  • 高可用:單集群能夠做到容器級別的容錯,當容器異常或者無響應時,應用的副本能夠較快地另一節(jié)點上重建。但是單集群無法應對網(wǎng)絡故障或者數(shù)據(jù)中心故障導致的服務的不可用。跨地域的多集群架構能夠達到跨機房、跨區(qū)域的容災。
  • 地域親和性:盡管國內(nèi)互聯(lián)網(wǎng)一直在提速,但是處于帶寬成本的考量,同一調(diào)用鏈的服務網(wǎng)絡距離越近越好。服務的主調(diào)和被調(diào)部署在同一個地域內(nèi)能夠有效減少帶寬成本;并且分而治之的方式讓應用服務本區(qū)域的業(yè)務,也能有效緩解應用服務的壓力。

當然,使用多集群調(diào)度肯定會增加整體架構的復雜度,集群之間的狀態(tài)同步也會增加控制面的額外開銷。所以,多集群的主要攻克的難點就是跨集群的信息同步和跨集群網(wǎng)絡連通方式。跨集群網(wǎng)絡連通方式一般的處理方式就是確保不同機房的網(wǎng)絡相互可達,這也是最簡單的方式。

而我比較干興趣的是跨集群的信息同步。多集群的服務實例調(diào)度,需要保證在多集群的資源同步的實時,將 pod 調(diào)度不同的集群中不會 pod pending 的情況。控制平面的跨集群同步主要有兩類方式:

  • 定義專屬的 API server:通過一套統(tǒng)一的中心化 API 來管理多集群以及機器資源。KubeFed 就是采用的這種方法,通過擴展 k8s API 對象來管理應用在跨集群的分布。
  • 基于 Virtual Kubelet:Virtual Kubelet 本質(zhì)上是允許我們冒充 Kubelet 的行為來管理 virtual node 的機制。這個 virtual node 的背后可以是任何物件,只要 virtual  node 能夠做到上報 node 狀態(tài)、和 pod 的生命周期管理。Liqo 就是通過定制的 virtual kubelet 來實現(xiàn)多集群管理。

KubeFed[1]Liqo[2]都是開源項目,兩者的主要區(qū)別如下:

場景

Kubefed

Liqo

Pod 調(diào)度

靜態(tài)調(diào)度、動態(tài)調(diào)度只支持 Deployment/ReplicaSet

動態(tài)調(diào)度,但是還是會出現(xiàn) pending 情況

控制平面

一套中心化管理組件

每個集群對等管理

集群發(fā)現(xiàn)

主動注冊

動態(tài)發(fā)現(xiàn)和注冊新集群

本文不會詳細介紹這些項目在部署和網(wǎng)絡管理的內(nèi)容,重點分析兩個項目(Kubefed、Liqo)的跨集群資源調(diào)度。

KubeFed

KubeFed 的目的是通過統(tǒng)一的 API 管理多個 k8s 集群,實現(xiàn)單一集群管理多個 k8s 集群的機制,并通過 CRD 的機制來擴展現(xiàn)有的 k8s 資源跨集群編排的能力。

KubeFed 將集群分為 host cluster,member cluster 兩個角色:

  • host cluster:KubeFed 的控制平面面,用戶需要安裝 KubeFed 的 operator 組件。
  • member cluster:注冊到 KubeFed API 上的集群,由 KubeFed 統(tǒng)一管理。通過命令行??kubefedctl join 的??方式手動注冊到 host cluster。

被聯(lián)邦管理的 k8s API 資源統(tǒng)稱為 Federated Resources,例如 FederatedDeployments。開啟跨集群調(diào)度也需要在 host cluster 上顯式地對應用資源開啟集群聯(lián)邦管理,開啟的方式是通過 ??kubefedctl federate?? 創(chuàng)建 FederatedTypeConfig。KubeFed 也支持聯(lián)邦化 namespace,讓 namespace 下面的資源都聯(lián)邦化。通過 federation control plane 來下發(fā)資源到 member cluster。

圖片

圖片kubefed-overview

KubeFed 概覽

資源調(diào)度

那 KubeFed 怎么支持跨集群部署的呢?在開啟資源的聯(lián)邦化之后,F(xiàn)ederated Resources 的 spec 分成 3 個基礎配置 :

  • template:原資源類型的 spec
  • placement:定義期望部署的集群
  • overrides:定義集群特定配置,基于原資源類型的 spec 進行修改,比如副本數(shù)的變化

用戶在部署服務時,可以在 spec 下定義部署的集群(placement)和集群指定參數(shù)(overrides)。比如服務需要在 cluster2 集群上增加副本數(shù),修改 deployment 的 replicas,需要在 overrides 上填寫“/spec/replicas”的修改。可以想到為了通用,overrides 的配置有一定復雜性。

spec:
template:
metadata:
labels:
app: nginx
spec:
replicas: 3
...
placement:
clusters:
- name: cluster2
- name: cluster1
overrides:
- clusterName: cluster2
clusterOverrides:
- path: "/spec/replicas"
value: 5
...

Federated  Resources 還支持通過另一個 CRD 來 ReplicaSchedulingPreference 配置資源類型級別的集群調(diào)度傾向。該方法通過指定資源類型在 member cluster 的最大 / 最小副本數(shù)實現(xiàn)了依據(jù)剩余可用資源的動態(tài)平衡。最終 controller 會將 preference 信息更新到 Federated Resources 的 overrides 上,從而重新分配實例。不過該功能還只支持 deployment/replicaset 資源。

可以看出在 KubeFed 的架構,還是區(qū)分了不同集群的配置和動態(tài)調(diào)度。

具體看看靜態(tài)調(diào)度和動態(tài)調(diào)度。

靜態(tài)調(diào)度

首先,F(xiàn)ederatedTypeConfig 的 spec 里定義了 host cluster 中的 Federated Resources 和 member cluster 集群的所代表的資源:

  • federatedType 定義在 host cluster 在多集群中的狀態(tài)的 API 資源類型(由用戶創(chuàng)建)
  • targetType 定義在 member cluster 集群代表 Federated Resources 的 API 資源類型(由 controller 創(chuàng)建)
  • statusType 用來更新 federated resource 的狀態(tài) (由 controller 創(chuàng)建,默認為 federatedType)

spec 對應的 federatedType 是定義的聯(lián)邦資源(由用戶創(chuàng)建),而 targetType 實際上是真正的 k8s workload 資源, KubeFed 的 controller 可以通過 federatedType 的 placement 和 overrides 來控制各個集群里的對應的  targetType  的資源的分布。具體來說,負責下發(fā) targetType 的 SyncController 會調(diào)用 dispatcher 生成 JSONPatch 并向 member cluster 創(chuàng)建底層資源。

圖片

kubefed-static-scheduling

KubeFed 靜態(tài)調(diào)度

默認創(chuàng)建 Federated 資源時,可以在 spec 下定義部署的集群(placement)和集群指定參數(shù)(overrides),實現(xiàn)多集群的 pod 分配。但是這種調(diào)度是靜態(tài)的。如果 overrides 設置的副本數(shù)超過集群剩余可用資源,那么新 pod 在集群里因為資源不夠?qū)е?pending。靜態(tài)方式在大規(guī)模場景下無非是低效的,擴集群調(diào)度在極端情況下需要人工觀測集群剩余資源來規(guī)劃集群分布。但是很多服務是不需要感知集群信息的,他最在意的是還是服務實例能夠正常啟動,希望服務在不同集群的打散是一種動態(tài)被平臺托管的。所以 KubeFed 引入了 ReplicaSchedulingPreference(RSP)的功能。

RSP 的實現(xiàn)依賴于一個新的 CRD——ReplicaSchedulingPreference 關鍵的幾個配置項為:

  • totalReplicas:期望的副本數(shù)
  • rebalance:是否允許已調(diào)度的副本被重新平衡
  • intersectWithClusterSelector:是否結(jié)合 Fed Resources 的 placement 下定義的集群結(jié)合
  • clusters:定義各集群期望的最大最小副本數(shù),以及分配權重

例如,下面這個例子期望 cluster1 和 cluster2 以 2:3 的比例下發(fā)服務的副本。當集群資源充足時,cluster1 會分配 4 個 pod,cluster2 被分配 6 個實例。當集群 cluster2 資源不足時,rebalance 的設置允許將 cluster2 的副本挪到 cluster1。

spec:
targetKind: FederatedDeployment
totalReplicas: 10
rebalance: true
intersectWithClusterSelector: false
clusters:
cluster1:
weight: 2
cluster2:
weight: 3

下圖描述了 KubeFed RSP 的工作流程,起作用的組件是 ReplicaScheduler。

圖片

kubefed-rsp-sched

KubeFed ReplicaSchedulingPreference workflow

ReplicaScheduler 首先會獲取 PreferredClusters,將健康的集群的信息收集。然后獲取當前服務副本的集群分布,會統(tǒng)計每個集群的 currentReplicasPerCluster、estimatedCapacity:

  • currentReplicasPerCluster:集群內(nèi) running 并且 ready 的 pod 數(shù)量
  • estimatedCapacity:期望的副本數(shù) spec.replicas - unschedulable 的 pod 數(shù)量

圖片

pod-unschedulable

ReplicaScheduler.Planner 依據(jù)上述信息(RSP 的 spec、currentReplicasPerCluster 和 estimatedCapacity),在可用集群中分配副本。Planner 的第一步會依據(jù) ReplicaSchedulingPreference 中集群權重將可用集群排序,并劃定每個集群的可分配上界和下界:

  • 下界:從 RSP 的 minReplicas 和 totalReplicas(totalReplicas 累減)、estimatedCapacity,三值中選擇最小的值作為每個集群的分配下界。
  • 上界:如果 rebalance 未開啟:首先在 currentReplicasPerCluster 的數(shù)量、estimatedCapacity 和 RSP 的 maxReplicas 選擇最小值,作為集群可用數(shù)量的增量,每個集群的上界是 下界+增量。

最終依據(jù)集群權重,將副本分配到各集群中。

ReplicaScheduler.Plugin 獲得新的 overrides 信息將原 Federated  resources 的 spec 更新。之后的流程就是原有靜態(tài)調(diào)度負責下發(fā)到集群。整個 ReplicaSchedulingPreference 能夠動態(tài)地在多個集群分配 pod,并且包含了處理 Pending Pod 的情況。

但是局限在于只支持 Deployment/ReplicaSet 資源。

Liqo

與 KubeFed 相比,Liqo 有著 pod 無縫調(diào)度、去中心化治理等優(yōu)勢。

  • 去中心化管理:采用 P2P 的對等管理,減少中心化管理組件。
  • 無縫調(diào)度:創(chuàng)建用戶服務資源時,和單集群操作一致。

Liqo 將集群劃分為 home cluster 和 foreign cluster。在每個集群都需要安裝 liqo 的組件來管理多集群,這兩類集群本質(zhì)上沒有區(qū)別。只是對于 home cluster 來說,其他的 foreign cluster 都是通過 Virtual Kubelet[3] 的方式映射成本集群節(jié)點。home cluster 將 foreign cluster 當作一個大的節(jié)點來使用。這樣就能做到用戶在 home  cluster 上創(chuàng)建資源時,能夠調(diào)度到 foregin cluster 上。Virutal Kubelet 具體的內(nèi)容可以看這篇文章《Virtual Kubelet[4]》。Virutal Kubelet 依據(jù)目的實現(xiàn)如下功能,就能在 k8s 集群內(nèi)注冊一個虛擬的節(jié)點。

?

自定義的 provider 必須提供以下功能:

  • 提供 pod、容器、資源的生命周期管理的功能
  • 符合 virtual kubelet 提供的 API
  • 不直接訪問 k8s apiserver,定義獲取數(shù)據(jù)的回調(diào)機制,例如 configmap、secrets

在集群注冊方面,Liqo 支持動態(tài)發(fā)現(xiàn)集群(mDNS、LAN 兩種方式)。在安裝 Liqo 組件時,可配置集群通過何種方式發(fā)現(xiàn)和集群共享出去的資源百分比(默認 30%)。所以 Liqo 的多集群前提是集群之間已經(jīng)網(wǎng)絡可達。

Ligo 調(diào)度

在調(diào)度方面,因為 remote cluster 通過 virtual  kueblet 將該集群視為一個大節(jié)點,可以直接依賴本集群的 kube-scheduler 來調(diào)度。但是這里還是有個問題。當 remote  cluster 的資源碎片比較多時,大節(jié)點上報資源時會聚合成一個大塊資源。導致大套餐的 pod 調(diào)度到 remote  cluster 會出現(xiàn) pending。

Ligo 的工作流程如下圖所示 . 當用戶創(chuàng)建一個 deployment 時,默認調(diào)度器負責判斷能否調(diào)度到 virtual node 上。之后這個服務的 pod 創(chuàng)建會被 virtual kubelet 接管。當 pod 被調(diào)度的 virtual node 上時,virtual  kubelet 會在 remote cluster 會對應的 replicaSet。使用 replicaSet 原因是 remote  cluster 上的 pod 被驅(qū)逐時,能夠在集群上重建,而不是在 home cluster 重新調(diào)度。

圖片

liqo-pods-management

在了解多集群調(diào)度的細節(jié)之前,需要先弄清楚 virtual kubelet 的工作機制。我們知道 Kubelet 有個 SyncHandler, virtual  kubelet 也有 PodLifecycleHandler,處理 pod 被 k8s 創(chuàng)建、更新、刪除的情況。例如,Liqo 的 virtual  kubelet 處理創(chuàng)建 pod 時,會先將 pod 的元數(shù)據(jù)里包含 home cluster 的信息轉(zhuǎn)換成 foreign cluster  (比如 label 和 namespace),然后將 pod 包在 ReplicaSet 里通過 foreign Client 創(chuàng)建 ReplicaSet 資源。

上面介紹了一個 pod 在不同集群之間的映射。接下來從 foreign cluster 的角度發(fā)現(xiàn) home cluster 的共享資源的具體流程。下屬 Controller 和 CRD 都是由 Liqo 安裝。

圖片

liqo-discovery

第一階段:發(fā)現(xiàn) foreign cluster 并上報可用資源

  1. DiscoveryController 是第一個集群注冊的 controller,DiscoveryController 發(fā)現(xiàn)并創(chuàng)建 foreignCluster 資源:通過 WAN/LAN 發(fā)現(xiàn)遠端集群,將 remote  cluster 的信息填入 foreignCluster.spec,之后的 Controller 通過 foreignCluster 來獲取 remote  cluster 的信息。
  2. ForeignClusterController 監(jiān)聽 foreignCluster  CR,并維護 remote cluster 的 identity 信息。這些信息用來構建 virtual  kubelet,和 crdReplicator 使用。ForeignClusterController 通過 Authentication  Service 向遠端的集群 ForeignAuthURL 驗證 remote cluster 的身份信息,并將集群的證書存儲在本地 secret。
  3. ForeignClusterController 在確認 foreign cluster 期望 outgoingPeering(即 home cluster 可以分享資源給 foreign cluster 使用),會創(chuàng)建  resourceRequest CR(不包含具體資源,只有集群元數(shù)據(jù)  authURL,用作后續(xù)資源請求的處理)。ResourceRequestController 監(jiān)聽 resourceRequest  CR,首先確保 foreignCluster 的 foreignCluster/tenant 資源存在;如果不存在則創(chuàng)建 CR,確保 ForeignAuthURL 是 resourceRequest.Spec.AuthURL。
  4. ResourceRequestController 負責監(jiān)控本地資源,將需要更新共享資源配額的 remote cluster  id 壓入 Broadcaster 組件的隊列里。將集群 Broadcaster 組件接著調(diào)用 OfferUpdater.Push 做資源同步。OfferUpdater 負責組裝 resourceOffer 里。resourceOffer 的 spec 保存集群的可共享資源,供遠端的 virtual kubelet 查詢。
  5. 并且 ResourceRequestController 還會監(jiān)聽本地 node/pod 事件,維護集群資源緩存(將 home cluster 全局可用資源,和 remote  cluster 占用資源分開)。當達到更新閾值(默認 80%),也會主動調(diào)用 OfferUpdate.Push 更新可用資源。當創(chuàng)建 pod 時,集群資源減去 pod 資源;當 pod 有 remoteClusterId 標簽(vk 添加)時,會累加共享的 remote 集群的資源。做到區(qū)分本集群和 remote pod,當集群資源-pod 變化資源,會觸發(fā)更新。
  6. 最終 ResourceRequestController 的 OfferUpdater 按序處理 5、6 步 pushed 的 queue 里集群 id,獲取 home cluster 集群資源并更新 home 集群的 ResourceOffer  資源上限(offer.Spec.ResourceQuota.Hard) 。計算公式:(本集群可用資源量 + remote  cluster 的 pod 資源 )* ResourceSharingPercentage(依據(jù)配置共享給遠端所有集群的資源)。

第二階段:virtual kubelet 監(jiān)聽 home cluster 的資源變化

  1. 從 foreign cluster 的角度,也會發(fā)現(xiàn) home cluster 并創(chuàng)建相應的 foreign cluster。virtual  kubelet 在 foreign cluster 注冊時,初始化 virtual-kubelet  provider。在初始化的時候通過 foreignClusterID 拿到 home cluster 的 kubeClient  Config(上一階段集群注冊時生成的 secret)。
  2. LiqoNodeProvider 監(jiān)聽 resourceOffer 資源(通過 foreignClusterID 獲得自己的可用資源量)。從 offer 里的 ResourceQuota 中獲的 node 的資源的 Capacity 和 Allocatable 值并調(diào)用 onNodeChangeCallback。在 virtual  kubelet 機制中,NodeProvider 是被上層 NodeController 調(diào)用 NotifyNodeStatus 方法,來監(jiān)控 virtual node 的變化。
  3. 實際的狀態(tài)更新由 NodeController 定義的回調(diào)函數(shù)將節(jié)點信息壓入 channel,NodeController 的控制循環(huán)實時異步地將資源變化向本集群的 api server 更新。

可以看到 home cluster 和 foreign cluster 沒有本質(zhì)上的區(qū)別,兩者可以相互使用對方允許共享的機器資源。當然,集群 A 也可以配置成不貢獻自己的資源出去,只使用別的集群分享出來的資源。

總結(jié)

本文介紹了 KubeFed/Liqo 兩個開源項目多集群的資源管理和 pod 調(diào)度。

KubeFed 的資源調(diào)度總體上比較靜態(tài),需要創(chuàng)建 workload 之前確保各集群有充足資源。它的動態(tài)調(diào)度能力有限,因為只能對 Deployment/ReplicaSet 開啟。當 KubeFed 下發(fā) pod 到集群出現(xiàn) pod pending 的情況時,動態(tài)調(diào)度的能力能夠?qū)?pod 遷移到其他集群。

Liqo 是能做到動態(tài)的資源發(fā)現(xiàn)和 pod 調(diào)度,但是它的方法是將一個集群抽象成一個工作節(jié)點。這種方式必然忽略了資源碎片的現(xiàn)象,使得虛擬節(jié)點的資源余量存在失真。比如集群內(nèi)的 2 個節(jié)點共剩余 40 核可用資源,并不一定代表集群還能調(diào)度一個 40 核資源的 pod。但是從 Liqo 的方式來看,這個集群是能夠調(diào)度 40 核 pod 的。并且目前來看,如果集群內(nèi)出現(xiàn) pod pending 的情況,也沒法自動遷移 pod 到其他集群。

不過 Liqo 的整個思想是比較新穎的,通過對等的 P2P 方式將多個集群聚合成一個大的可用資源池。對于現(xiàn)有集群也不會引入一套新的 API。或許 Liqo 可以引入 descheduler 將 pending pod 遷移到其他機器來解決資源余量的誤差問題。

參考資料

  • A Brief History of Multicluster Kubernetes:https://www.tfir.io/a-brief-history-of-multicluster-kubernetes/
  • Simplifying multi-clusters in Kubernetes:https://www.cncf.io/blog/2021/04/12/simplifying-multi-clusters-in-kubernetes/
  • kubefed 簡介 :https://jimmysong.io/kubernetes-handbook/practice/federation.html
  • Unleashing the multi-cluster potential with Liqo:https://youtu.be/Ru-VrLcRXDg
  • Virtual Kubelet:https://www.huweihuang.com/kubernetes-notes/virtual-kubelet/virtual-kubelet.html

引用鏈接

[1]KubeFed: https://github.com/kubernetes-sigs/kubefed

[2]Liqo: https://github.com/liqotech/liqo

[3]Virtual Kubelet: https://github.com/virtual-kubelet/virtual-kubelet

[4]Virtual Kubelet: https://www.huweihuang.com/kubernetes-notes/virtual-kubelet/virtual-kubelet.html

責任編輯:龐桂玉 來源: 奇妙的Linux世界
相關推薦

2022-01-12 11:55:43

Kubernetes多集群Linux

2022-07-11 09:46:43

Kubernetes開源Linux

2021-02-18 09:28:32

Kubernetes開源SaaS

2009-06-11 09:35:47

GlassFish配置多機集群

2022-05-24 09:00:00

云計算Kubernetes安全

2021-02-07 08:00:00

Kubernetes集群云原生

2021-12-24 10:47:49

Kubernetes容器化微服務

2023-11-01 07:55:44

K8sKubernetes

2021-11-22 16:21:28

Kubernetes 運維開源

2023-03-21 15:26:02

Kubernetes容器開發(fā)

2017-02-27 09:21:23

Kubernetes架構service

2021-12-30 07:42:13

Kubernetes集群架構

2020-09-23 14:20:07

Kubernetes容器網(wǎng)絡模型

2009-07-29 13:50:08

MySQL基本調(diào)度策略

2021-06-25 15:53:25

Kubernetes程序技巧

2022-06-27 19:16:12

KubernetesK8s 集群

2014-02-21 15:21:29

集群共享運維人員

2021-12-29 17:24:16

Kubernetes集群事件

2022-05-12 14:25:44

Kubernetesvcluster

2024-02-21 07:48:37

KubeSlice云原生Kubernetes
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久久久模特 | 亚洲成人网在线 | 日韩a v在线免费观看 | 精品中文字幕在线观看 | 一级视频在线免费观看 | 九九久久在线看 | 亚洲一区二区国产 | 国产精品99久久久久久宅男 | 2018国产大陆天天弄 | 久久久久网站 | 一区在线视频 | 在线看国产 | 国产黄色av网站 | 九九热这里 | 久久高清 | 青草青草久热精品视频在线观看 | 精品欧美激情精品一区 | 国产日韩精品在线 | 射久久 | 久久一日本道色综合久久 | 国产精品免费一区二区三区四区 | 国产成年人视频 | 欧美精品在欧美一区二区 | 国产精品视频久久 | 国产在线精品免费 | 99精品国产一区二区青青牛奶 | 久久久91精品国产一区二区三区 | 久久国产亚洲 | 中文字幕视频在线观看 | 久久久久久久久国产精品 | 国产婷婷在线视频 | 中文字幕一区在线观看视频 | 国产蜜臀97一区二区三区 | 国产影音先锋 | 国产精品污www一区二区三区 | 毛片免费观看 | 罗宾被扒开腿做同人网站 | www.夜夜骑 | 欧美久久久久久久 | 国产精品亚洲成在人线 | 日韩一 |