先發制人遇事不慌:Kubernetes集群主動擴展?

閱讀:560 2023-11-08 23:44:02

當集群資源不足時,Cluster Autoscaler會提供新節點并將其加入集群。使用Kubernetes時你可能會注意到,創建節點并將其加入集群的過程可能需要花費數分鐘。在這段時間里,應用程序很容易被連接淹沒,因為已經無法進一步擴展了。

虛擬機的配置可能需要花費數分鐘,在這期間可能無法擴展應用

如何消除如此長的等待時間?

主動擴展(Proactive scaling),或者:

  1. 理解集群Autoscaler的工作原理并最大限度提升其效用;
  2. 使用Kubernetes scheduler為節點分配另一個Pod;以及
  3. 主動配置工作節點,以改善擴展效果。

注意:本文涉及的所有代碼都已發布至LearnK8s GitHub。

Linode可以支持這些解決方案。近期Lincode加入了 Akamai解決方案大家庭,現在注冊Linode,就可免費獲得價值100美元的使用額度,可以隨意使用Linode云平臺提供的各種服務。立即點擊這里了解詳情并注冊吧↓↓↓

進一步了解Akamai Linode云計算服務與能力!

Cluster Autoscaler如何在Kubernetes中生效

Cluster Autoscaler在觸發自動擴展時并不檢查內存或CPU的可用數,而是會對事件作出反應,檢查所有不可調度的Pod。當調度器找不到能容納某個Pod的節點時,我們就說這個Pod是不可調度的。

我們可以這樣創建一個集群來測試看看。

復制
bash
$ linode-cli lke cluster-create \
 --label learnk8s \
 --region eu-west \
 --k8s_version 1.23 \
 --node_pools.count 1 \
 --node_pools.type g6-standard-2 \
 --node_pools.autoscaler.enabled enabled \
 --node_pools.autoscaler.max 10 \
 --node_pools.autoscaler.min 1 \
$ linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
 

請留意下列細節:

  1. 每個節點有4GB內存和2個vCPU(例如“g6-standard-2”實例)
  2. 集群中只有一個節點,并且
  3. Cluster autoscaler被配置為從1個節點擴展至10個節點

我們可以用下列命令驗證安裝已成功完成:

復制
bash
$ kubectl get pods -A --kubecnotallow=kubeconfig
  • 1.
  • 2.
 

用環境變量導出kubeconfig文件通常是一種很方便的做法,為此我們可以運行:

復制
bash
$ export KUBECONFIG=${PWD}/kubeconfig
$ kubectl get pods
  • 1.
  • 2.
  • 3.
 

部署應用程序

讓我們部署一個需要1GB內存和250m* CPU的應用程序。

注意:m = 內核的千分之一容量,因此250m = CPU的25%容量。

復制
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: podinfo
spec:
 replicas: 1
 selector:
 matchLabels:
 app: podinfo
 template:
 metadata:
 labels:
 app: podinfo
 spec:
 containers:
 - name: podinfo
 image: stefanprodan/podinfo
 ports:
 - containerPort: 9898
 resources:
 requests:
 memory: 1G
 cpu: 250m
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
 

用下列命令將資源提交至集群:

復制
bash
$ kubectl apply -f podinfo.yaml
  • 1.
  • 2.
 

隨后很快會發現一些情況。首先,三個Pod幾乎會立即開始運行,另有一個Pod處于“未決”狀態。

 

隨后很快:

  1. 幾分鐘后,Autoscaler創建了一個額外的Pod,并且
  2. 第四個Pod會被部署到一個新節點中。

最終,第四個Pod被部署到一個新節點中

第四個Pod為何沒有部署到第一個節點中?讓我們一起看看已分配的資源。

Kubernetes節點中資源的分配

Kubernetes集群中部署的Pod會消耗內存、CPU以及存儲資源。而且在同一個節點上,操作系統和Kubelet也需要消耗內存和CPU。

在Kubernetes工作節點上,內存和CPU會被拆分為:

  1. 運行操作系統和系統守護進程(如SSH、Systemd等)所需的資源。
  2. 運行Kubernetes代理程序(如Kubelet、容器運行時以及節點故障檢測程序等)所需的資源。
  3. 可用于Pod的資源。
  4. 為排空閾值(Eviction threshold)保留的資源。

Kubernetes節點中分配和保留的資源

如果集群運行了DaemonSet(如kube-proxy),那么可用內存和CPU數量還將進一步減少。

那么我們不妨降低需求,以確保能將所有Pod都放入同一個節點中:

復制
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: podinfo
spec:
 replicas: 4
 selector:
 matchLabels:
 app: podinfo
 template:
 metadata:
 labels:
 app: podinfo
 spec:
 containers:
 - name: podinfo
 image: stefanprodan/podinfo
 ports:
 - containerPort: 9898
 resources:
 requests:
 memory: 0.8G # <- lower memory
 cpu: 200m # <- lower CPU
我們可以使用下列命令修改這個部署:
bash
$ kubectl apply -f podinfo.yaml
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
 

選擇恰當數量的CPU和內存以優化實例的運行,這是個充滿挑戰的工作。Learnk8s計算器工具可以幫助我們更快速地完成這項工作。

一個問題解決了,但是創建新節點花費的時間呢?

遲早我們會需要四個以上的副本,我們是否真的需要等待好幾分鐘,隨后才能創建新的Pod?

簡單來說:是的!Linode必須從頭開始創建和配置新虛擬機,隨后將其連接到集群。這個過程經常會超過兩分鐘。

但其實還有替代方案:我們可以在需要時主動創建已經配置好的節點。

例如:我們可以配置讓Autoscaler始終準備好一個備用節點。當Pod被部署到備用節點后,Autoscaler可以主動創建另一個備用節點。然而Autoscaler并沒有內置這樣的功能,但我們可以很容易地重新創建。

我們可以創建一個請求數與節點資源相等的Pod:

復制
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: overprovisioning
spec:
 replicas: 1
 selector:
 matchLabels:
 run: overprovisioning
 template:
 metadata:
 labels:
 run: overprovisioning
 spec:
 containers:
 - name: pause
 image: k8s.gcr.io/pause
 resources:
 requests:
 cpu: 900m
 memory: 3.8G
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
 

用下列命令將資源提交至集群:

復制
bash
kubectl apply -f placeholder.yaml
  • 1.
  • 2.
 

這個Pod完全不執行任何操作。

用占位Pod保護節點上的所有資源

該節點的作用只是確保節點能夠被充分使用起來。

隨后還需要確保當工作負載需要擴展時,這個占位Pod能夠被快速清除。為此我們可以使用Priority Class。

復制
yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
 name: overprovisioning
value: -1
globalDefault: false
description: "Priority class used by overprovisioning."
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: overprovisioning
spec:
 replicas: 1
 selector:
 matchLabels:
 run: overprovisioning
 template:
 metadata:
 labels:
 run: overprovisioning
 spec:
 priorityClassName: overprovisioning # <--
 containers:
 - name: pause
 image: k8s.gcr.io/pause
 resources:
 requests:
 cpu: 900m
 memory: 3.8G
用下列命令將其提交至集群:
bash
kubectl apply -f placeholder.yaml
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
 

至此,配置工作已全部完成。

我們可能需要等待一會讓Autoscaler創建節點,隨后我們將有兩個節點:

  1. 一個包含四個Pod的節點
  2. 一個包含一個占位Pod的節點

如果將部署擴展為5個副本會怎樣?是否要等待Autoscaler創建另一個新節點?

用下列命令測試看看吧:

復制
bash
kubectl scale deployment/podinfo --replicas=5
  • 1.
  • 2.
 

我們將會看到:

  1. 第五個Pod會立即創建出來,并在10秒內變為“正在運行”的狀態。
  2. 占位Pod會被清除,以便為第五個Pod騰出空間。

占位Pod會被清除,以便為常規Pod騰出空間

隨后:

  1. Cluster autoscaler會注意到未決的占位Pod并配置一個新的節點。
  2. 占位Pod會被部署到新創建的節點中。

未決的Pod觸發了Cluster autoscaler新建節點

在可以有更多節點時,為何又要主動創建出一個節點?

我們可以將占位Pod擴展到多個副本,每個副本都會預配置一個Kubernetes節點,準備接受標準工作負載。然而這些節點雖然是閑置的,但它們產生的費用依然會計入云服務賬單。因此一定要慎重,不要創建太多節點。

將Cluster Autoscaler與Horizontal Pod Autoscaler配合使用

為理解這項技術的含義,我們可以將Cluster autoscaler和Horizontal Pod Autoscaler(HPA)結合在一起來看。HPA可用于提高部署中的副本數量。

隨著應用程序收到越來越多流量,我們可以讓Autoscaler調整處理請求的副本數量。當Pod耗盡所有可用資源后,會觸發Cluster autoscaler新建一個節點,這樣HPA就可以繼續創建更多副本。

可以這樣新建一個集群來測試上述效果:

復制
bash
$ linode-cli lke cluster-create \
 --label learnk8s-hpa \
 --region eu-west \
 --k8s_version 1.23 \
 --node_pools.count 1 \
 --node_pools.type g6-standard-2 \
 --node_pools.autoscaler.enabled enabled \
 --node_pools.autoscaler.max 10 \
 --node_pools.autoscaler.min 3 \
$ linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig-hpa
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
 

用下列命令驗證安裝過程已成功完成:

復制
bash
$ kubectl get pods -A --kubecnotallow=kubeconfig-hpa
  • 1.
  • 2.
 

使用環境變量導出kubeconfig文件是一種方便的做法,為此我們可以運行:

復制
bash
$ export KUBECONFIG=${PWD}/kubeconfig-hpa
$ kubectl get pods
  • 1.
  • 2.
  • 3.
 

接下來使用Helm安裝Prometheus并查看該部署的相關指標。我們可以在官網上了解安裝Helm的詳細方法。

復制
bash
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm install prometheus prometheus-community/prometheus
Kubernetes為HPA提供了一個控制器,借此可以動態增減副本數量。然
  • 1.
  • 2.
  • 3.
  • 4.
 

而HPA也有一些局限性:

  1. 無法拆箱即用。需要安裝Metrics Server來匯總并暴露出指標。
  2. PromQL查詢無法做到拆箱即用。

好在我們可以使用KEDA,它通過一些實用功能(包括從Prometheus讀取指標)擴展了HPA控制器的用法。KEDA是一種Autoscaler,可適用于下列三個組件:

  1. Scaler
  2. Metrics Adapter
  3. Controller

 

KEDA架構

我們可以通過Helm安裝KEDA:

復制
bash
$ helm repo add kedacore https://kedacore.github.io/charts
$ helm install keda kedacore/keda
  • 1.
  • 2.
  • 3.
 

安裝好Prometheus和KEDA之后,來創建一個部署吧。

在這個實驗中,我們將使用一個每秒可以處理固定數量請求的應用。每個Pod每秒最多可以處理十個請求,如果Pod收到第11個請求,會將請求掛起,稍后再處理。

復制
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: podinfo
spec:
 replicas: 4
 selector:
 matchLabels:
 app: podinfo
 template:
 metadata:
 labels:
 app: podinfo
 annotations:
 prometheus.io/scrape: "true"
 spec:
 containers:
 - name: podinfo
 image: learnk8s/rate-limiter:1.0.0
 imagePullPolicy: Always
 args: ["/app/index.js", "10"]
 ports:
 - containerPort: 8080
 resources:
 requests:
 memory: 0.9G
---
apiVersion: v1
kind: Service
metadata:
 name: podinfo
spec:
 ports:
 - port: 80
 targetPort: 8080
 selector:
 app: podinfo
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
 

使用下列命令將資源提交至集群:

復制
bash
$ kubectl apply -f rate-limiter.yaml
  • 1.
  • 2.
 

為了生成一些流量,我們可以使用Locust。下列YAML定義將創建一個分布式負載測試集群:

復制
yaml
apiVersion: v1
kind: ConfigMap
metadata:
 name: locust-script
data:
 locustfile.py: |-
 from locust import HttpUser, task, between
 class QuickstartUser(HttpUser):
 @task
 def hello_world(self):
 self.client.get("/", headers={"Host": "example.com"})
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: locust
spec:
 selector:
 matchLabels:
 app: locust-primary
 template:
 metadata:
 labels:
 app: locust-primary
 spec:
 containers:
 - name: locust
 image: locustio/locust
 args: ["--master"]
 ports:
 - containerPort: 5557
 name: comm
 - containerPort: 5558
 name: comm-plus-1
 - containerPort: 8089
 name: web-ui
 volumeMounts:
 - mountPath: /home/locust
 name: locust-script
 volumes:
 - name: locust-script
 configMap:
 name: locust-script
---
apiVersion: v1
kind: Service
metadata:
 name: locust
spec:
 ports:
 - port: 5557
 name: communication
 - port: 5558
 name: communication-plus-1
 - port: 80
 targetPort: 8089
 name: web-ui
 selector:
 app: locust-primary
 type: LoadBalancer
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
 name: locust
spec:
 selector:
 matchLabels:
 app: locust-worker
 template:
 metadata:
 labels:
 app: locust-worker
 spec:
 containers:
 - name: locust
 image: locustio/locust
 args: ["--worker", "--master-host=locust"]
 volumeMounts:
 - mountPath: /home/locust
 name: locust-script
 volumes:
 - name: locust-script
 configMap:
 name: locust-script
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
 

運行下列命令將其提交至集群:

復制
bash
$ kubectl locust.yaml
Locust會讀取下列locustfile.py文件,該文件存儲在一個ConfigMap中:
py
from locust import HttpUser, task, between
class QuickstartUser(HttpUser):
 @task
 def hello_world(self):
 self.client.get("/")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
 

該文件并沒有什么特別的作用,只是向一個URL發出請求。若要連接至Locust儀表板,我們需要提供其負載均衡器的IP地址。為此可使用下列命令獲取地址:

復制
bash
$ kubectl get service locust -o jsnotallow='{.status.loadBalancer.ingress[0].ip}'
  • 1.
  • 2.
 

隨后打開瀏覽器并訪問該IP地址即可。

此外還需要注意一個問題:Horizontal Pod Autoscaler。KEDA autoscaler會用一個名為ScaledObject的特殊對象來封裝Horizontal Autoscaler。

復制
yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: podinfo
spec:
scaleTargetRef:
 kind: Deployment
 name: podinfo
minReplicaCount: 1
maxReplicaCount: 30
cooldownPeriod: 30
pollingInterval: 1
triggers:
- type: prometheus
 metadata:
 serverAddress: http://prometheus-server
 metricName: connections_active_keda
 query: |
 sum(increase(http_requests_total{app="podinfo"}[60s]))
 threshold: "480" # 8rps * 60s
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
 

KEDA可以連接由Prometheus收集的指標,并將其發送給Kubernetes。最后,它還將使用這些指標創建一個Horizontal Pod Autoscaler (HPA)。

我們可以用下列命令手工檢查HPA:

復制
bash
$ kubectl get hpa
$ kubectl describe hpa keda-hpa-podinfo
  • 1.
  • 2.
  • 3.
 

并使用下列命令提交該對象:

復制
bash
$ kubectl apply -f scaled-object.yaml
  • 1.
  • 2.
 

接下來可以測試擴展效果了。請在Locust儀表板中用下列設置啟動一項實驗:

  1. Number of users:300
  2. Spawn rate:0.4
  3. Host:http://podinfo

 

集群和Horizontal pod autoscaler的結合

可以看到,副本的數量增加了!

效果不錯,但有個問題不知道你是否注意到。

當該部署擴展到8個Pod后,需要等待幾分鐘,隨后才能在新節點中創建新的Pod。在這段時間里,每秒處理的請求數量也不再增加了,因為當前的8個副本每個都只能處理10個請求。

讓我們試試看收縮容量并重復該實驗:

復制
bash
kubectl scale deployment/podinfo --replicas=4 # or wait for the autoscaler to remove pods
  • 1.
  • 2.
 

這次,我們將用一個占位Pod實現超量配置(Overprovision):

復制
yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
 name: overprovisioning
value: -1
globalDefault: false
description: "Priority class used by overprovisioning."
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: overprovisioning
spec:
 replicas: 1
 selector:
 matchLabels:
 run: overprovisioning
 template:
 metadata:
 labels:
 run: overprovisioning
 spec:
 priorityClassName: overprovisioning
 containers:
 - name: pause
 image: k8s.gcr.io/pause
 resources:
 requests:
 cpu: 900m
 memory: 3.9G
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
 

運行下列命令將其提交至集群:

復制
bash
kubectl apply -f placeholder.yaml
  • 1.
  • 2.
 

打開Locust儀表板并用下列設置重復實驗:

  1. Number of users:300
  2. Spawn rate:0.4
  3. Host:http://podinfo

 

在超量配置的情況下進行集群和Horizontal pod autoscaler的結合

這一次,新節點將在后臺創建,每秒請求數量將持續增減,不會原地踏步。很棒!

總結

本文介紹了下列內容:

  1. Cluster autoscaler并不追蹤CPU或內存用量,而是會監控未決的Pod。
  2. 我們可以用可用內存和CPU的總量來創建一個Pod,從而主動配置Kubernetes節點。
  3. Kubernetes節點會為Kubelet、操作系統以及排空閾值保留一定的資源。
  4. 我們可以結合使用Prometheus和KEDA,從而通過PromQL查詢擴展自己的Pod。

這篇文章的內容感覺還行吧?有沒有想要立即在Linode平臺上親自嘗試一下?別忘了,現在注冊可以免費獲得價值100美元的使用額度,快點自己動手體驗本文介紹的功能和服務吧↓↓↓

進一步了解Akamai Linode云計算服務與能力!

歡迎關注Akamai知乎機構號 ,第一時間了解高可用的MySQL/MariaDB參考架構,以及豐富的應用程序示例。

相關文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感興趣
推薦閱讀 更多>
推薦商標

{{ v.name }}

{{ v.cls }}類

立即購買 聯系客服
主站蜘蛛池模板: 国产精品亚洲αv天堂无码| 亚洲av成人无码网站…| 亚洲人成影院在线无码观看| 国产成人无码精品久久久露脸| 亚洲国产精品无码久久久秋霞1| 国产丰满乱子伦无码专| 精品无码免费专区毛片| 成人无码WWW免费视频| 特级毛片内射www无码| 无码人妻AV一二区二区三区| 精品无人区无码乱码毛片国产| 亚洲日韩中文无码久久| 成年午夜无码av片在线观看| 亚洲精品一级无码鲁丝片| 在人线av无码免费高潮喷水| 久久青草亚洲AV无码麻豆| 亚洲A∨无码一区二区三区| 无码日韩人妻AV一区二区三区| 亚洲aⅴ无码专区在线观看| 久久精品岛国av一区二区无码| 国产高清无码毛片| 2020无码专区人妻系列日韩| 亚洲熟妇无码爱v在线观看| 无套内射在线无码播放| 在线高清无码A.| 亚洲桃色AV无码| 伊人久久精品无码av一区| 久久亚洲av无码精品浪潮| 无码精品蜜桃一区二区三区WW| 日日摸日日碰人妻无码| 无码办公室丝袜OL中文字幕| 东京热av人妻无码| 国产裸模视频免费区无码| 久久久久久久久免费看无码| 精品人妻无码一区二区三区蜜桃一 | 日韩无码系列综合区| 特级毛片内射www无码| 日韩AV片无码一区二区不卡| 亚洲成a人在线看天堂无码| 精品久久久久久无码人妻热 | 国产高清无码二区 |