精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Istio多集群實(shí)踐,你都學(xué)會(huì)了嗎?

開(kāi)發(fā) 前端
Istio 多集群網(wǎng)格有多種模型,在網(wǎng)絡(luò)拓?fù)渖戏譃楸馄骄W(wǎng)絡(luò)和非扁平網(wǎng)絡(luò),在控制面上分為單一控制平面和多控制平面。

為了實(shí)現(xiàn)應(yīng)用高并發(fā)和高可用,企業(yè)通常會(huì)選擇將應(yīng)用部署在多個(gè)地域的多個(gè)集群,甚至多云、混合云環(huán)境中。在這種情況下,如何在多個(gè)集群中部署和管理應(yīng)用,成為了一個(gè)挑戰(zhàn),當(dāng)然多集群方案也逐步成為了企業(yè)應(yīng)用部署的最佳選擇了。同樣對(duì)多云、混合云、虛擬機(jī)等異構(gòu)基礎(chǔ)設(shè)施的服務(wù)治理也是 Istio 重點(diǎn)支持的場(chǎng)景之一,Istio 從 v1.0 版本開(kāi)始支持一些多集群功能,并在之后的版本中添加了新功能。

多集群服務(wù)網(wǎng)格的好處是所有服務(wù)對(duì)客戶(hù)端看起來(lái)都一樣,不管工作負(fù)載實(shí)際上運(yùn)行在哪里,無(wú)論是部署在單個(gè)還是多個(gè)網(wǎng)格中,它對(duì)應(yīng)用程序都是透明的。要實(shí)現(xiàn)此行為,需要使用單個(gè)邏輯控制平面管理所有服務(wù)。但是,單個(gè)邏輯控制平面不一定需要是單個(gè)物理 Istio 控制平面。

多集群模型

Istio 多集群網(wǎng)格有多種模型,在網(wǎng)絡(luò)拓?fù)渖戏譃楸馄骄W(wǎng)絡(luò)和非扁平網(wǎng)絡(luò),在控制面上分為單一控制平面和多控制平面。

  • 扁平網(wǎng)絡(luò):所有集群都在同一個(gè)網(wǎng)絡(luò)中,可以直接訪(fǎng)問(wèn)到其他集群的服務(wù),不需要通過(guò)網(wǎng)關(guān)。
  • 優(yōu)點(diǎn): 跨集群訪(fǎng)問(wèn)不經(jīng)過(guò)東西向網(wǎng)關(guān),延遲低
  • 缺點(diǎn):組網(wǎng)較為復(fù)雜,Service、Pod 網(wǎng)段不能重疊,借助 VPN 等技術(shù)將所有集群的 Pod 網(wǎng)絡(luò)打通,需要考慮網(wǎng)絡(luò)安全問(wèn)題
  • 非扁平網(wǎng)絡(luò):集群之間的網(wǎng)絡(luò)是隔離的,需要通過(guò)網(wǎng)關(guān)訪(fǎng)問(wèn)其他集群的服務(wù)。
  • 優(yōu)點(diǎn):不同集群的網(wǎng)絡(luò)是互相隔離的,安全性更高,不需要打通不同集群的容器網(wǎng)絡(luò),不用提前規(guī)劃集群的網(wǎng)段

  • 缺點(diǎn):跨集群訪(fǎng)問(wèn)依賴(lài)東西向網(wǎng)關(guān),延遲高。東西向網(wǎng)關(guān)工作模式是 TLS AUTO_PASSTHROUGH,不支持 HTTP 路由策略。

  • 單控制面:所有集群共用一個(gè)控制平面,所有集群的配置都在同一個(gè)控制平面中。

  • 優(yōu)點(diǎn):所有集群的配置都在同一個(gè)控制平面中,集群之間的配置可以共享,部署運(yùn)維更簡(jiǎn)單

  • 缺點(diǎn):控制平面的性能和可用性會(huì)受到影響,不適合大規(guī)模集群

  • 多控制面:每個(gè)集群都有一個(gè)獨(dú)立的控制平面,集群之間的配置不共享。

  • 優(yōu)點(diǎn):控制平面的性能和可用性不會(huì)受到影響,適合大規(guī)模集群

  • 缺點(diǎn):集群之間的配置不共享,部署運(yùn)維較為復(fù)雜

總體來(lái)說(shuō) Istio 目前支持 4 種多集群模型:扁平網(wǎng)絡(luò)單控制面、扁平網(wǎng)絡(luò)多控制面、非扁平網(wǎng)絡(luò)單控制面、非扁平網(wǎng)絡(luò)多控制面。其中扁平網(wǎng)絡(luò)單控制面是最簡(jiǎn)單的模型,非扁平網(wǎng)絡(luò)多控制面是最復(fù)雜的模型。

扁平網(wǎng)絡(luò)單控制面

該模型下只需要將 Istio 控制面組件部署在主集群中,然后可以通過(guò)這個(gè)控制面來(lái)管理所有集群的 Service 和 Endpoint,其他的 Istio 相關(guān)的 API 比如 VirtualService、DestinationRule 等也只需要在主集群中配置即可,其他集群不需要部署 Istio 控制面組件。

控制平面的 Istiod 核心組件負(fù)責(zé)連接所有集群的 kube-apiserver,獲取每個(gè)集群的 Service、Endpoint、Pod 等信息,所有集群的 Sidecar 均連接到這個(gè)中心控制面,由這個(gè)中心控制面負(fù)責(zé)所有的 Envoy Sidecar 的配置生成和分發(fā)。

扁平網(wǎng)絡(luò)單控制面

多集群扁平網(wǎng)絡(luò)模型和單一集群的服務(wù)網(wǎng)格在訪(fǎng)問(wèn)方式上幾乎沒(méi)什么區(qū)別,但是需要注意不同集群的 Service IP 和 Pod 的 IP 不能重疊,否則會(huì)導(dǎo)致集群之間的服務(wù)發(fā)現(xiàn)出現(xiàn)問(wèn)題,這也是扁平網(wǎng)絡(luò)模型的一個(gè)缺點(diǎn),需要提前規(guī)劃好集群的網(wǎng)段。

非扁平網(wǎng)絡(luò)單控制面

在很多場(chǎng)景下我們多個(gè)集群并不在同一個(gè)網(wǎng)絡(luò)中,為滿(mǎn)足這個(gè)場(chǎng)景 Istio 又提出了一種更加靈活的網(wǎng)絡(luò)方案,即非扁平網(wǎng)絡(luò)。在非扁平網(wǎng)絡(luò)中,我們可以通過(guò)配置東西向網(wǎng)關(guān)來(lái)轉(zhuǎn)發(fā)跨集群的訪(fǎng)問(wèn)流量。和扁平網(wǎng)絡(luò)的方案一樣,Istio 控制面一樣需要連接所有 Kubernetes 集群的 kube-apiserver,訂閱所有集群的 Service、Endpoint 等資源,所有集群的 Envoy Sidecar 都被連接到同一控制平面。

非扁平網(wǎng)絡(luò)單控制面

非扁平網(wǎng)絡(luò)單控制面模型在同一集群內(nèi)部的服務(wù)訪(fǎng)問(wèn)和單集群模型還是一樣的,但是如果有一個(gè)目標(biāo)服務(wù)實(shí)例運(yùn)行在另外一個(gè)集群中,那么這個(gè)時(shí)候就需要目標(biāo)集群的東西向網(wǎng)關(guān)來(lái)轉(zhuǎn)發(fā)跨集群的服務(wù)請(qǐng)求。

扁平網(wǎng)絡(luò)多控制面

多控制面模型是每個(gè)集群都使用自己的 Istio 控制面,但是每個(gè) Istio 控制面仍然要感知所有集群中的 Service、Endpoint 等資源,并控制集群內(nèi)或者跨集群的服務(wù)間訪(fǎng)問(wèn)。對(duì)于多控制面模型來(lái)說(shuō),相同的 Istio 配置需要被復(fù)制下發(fā)到多個(gè)集群中,否則不同集群的 Sidecar 訂閱到的 xDS 配置可能會(huì)存在不一致,導(dǎo)致不同集群的服務(wù)訪(fǎng)問(wèn)行為不一致的情況。多控制面模型還有以下的一些特點(diǎn):

  • 共享根 CA:為了支持跨集群的 mTLS 通信,多控制面模型要求每個(gè)集群的控制面 Istiod 都是有相同 CA 機(jī)構(gòu)頒發(fā)的中間 CA 證書(shū),供 Citadel 簽發(fā)證書(shū)使用,以支持跨集群的 TLS 雙向認(rèn)證通信。
  • Sidecar 與本集群的 Istiod 控制面連接訂閱 xDS,xDS 通信的可靠性相對(duì)更高。
  • 與單控制面模型相比,多控制面模型的控制面性能和可用性更好,適合大規(guī)模集群。

扁平網(wǎng)絡(luò)多控制面

這種模型適用于控制面可用性和控制面時(shí)延要求較高的場(chǎng)景,但是由于每個(gè)集群都需要部署 Istio 控制面,所以部署和運(yùn)維的成本也會(huì)相應(yīng)增加,同一配置規(guī)則需要重復(fù)創(chuàng)建多份,存在資源冗余的問(wèn)題。

非扁平網(wǎng)絡(luò)多控制面

非扁平網(wǎng)絡(luò)多控制面模型與扁平網(wǎng)絡(luò)多控制面模型類(lèi)似,它們?cè)诳刂泼娣矫嫱耆嗤總€(gè) Kubernetes 集群分別部署獨(dú)立的 Istio 控制面,并且每個(gè)控制面都監(jiān)聽(tīng)所有 Kubernetes 集群的 Service、Endpoint 等資源。

非扁平網(wǎng)絡(luò)多控制面

因?yàn)槭欠潜馄骄W(wǎng)絡(luò)模型,所以不同的集群不需要三層打通,跨集群的服務(wù)訪(fǎng)問(wèn)通過(guò) Istio 的東西向網(wǎng)關(guān)來(lái)轉(zhuǎn)發(fā)。每個(gè)集群的 Pod 地址范圍與服務(wù)地址可以與其他集群重疊,不同的集群之間互不干擾。另外集群的 Sidecar 只連接到本集群的 Istio 控制面,通信效率更高。

多集群安裝

在選擇 Istio 多集群模型時(shí),當(dāng)然需要結(jié)合自己的實(shí)際場(chǎng)景來(lái)決定。如果集群之間的網(wǎng)絡(luò)是扁平的,那么可以選擇扁平網(wǎng)絡(luò)模型,如果集群之間的網(wǎng)絡(luò)是隔離的,那么可以選擇非扁平網(wǎng)絡(luò)模型。如果集群規(guī)模較小,那么可以選擇單控制面模型,如果集群規(guī)模較大,那么可以選擇多控制面模型。

接下來(lái)我們這里選擇跨網(wǎng)絡(luò)多主架構(gòu)的模型來(lái)進(jìn)行安裝說(shuō)明,即非扁平網(wǎng)絡(luò)多控制面模型。這里我們將在 cluster1 和 cluster2 兩個(gè)集群上,分別安裝 Istio 控制平面, 且將兩者均設(shè)置為主集群(primary cluster)。 集群 cluster1 在 network1 網(wǎng)絡(luò)上,而集群 cluster2 在 network2 網(wǎng)絡(luò)上,這意味著這些跨集群邊界的 Pod 之間,網(wǎng)絡(luò)不能直接連通。

為了方便測(cè)試,我們這里使用 kind 來(lái)測(cè)試多集群,先保證已經(jīng)安裝了 Docker 和 KinD:

$ docker version
Client:
 Cloud integration: v1.0.29
 Version:           20.10.21
 API version:       1.41
 Go version:        go1.18.7
 Git commit:        baeda1f
 Built:             Tue Oct 25 18:01:18 2022
 OS/Arch:           darwin/arm64
 Context:           orbstack
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       311b9ff
  Built:            Thu Oct 26 09:08:17 2023
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          v1.7.7
  GitCommit:        8c087663b0233f6e6e2f4515cee61d49f14746a8
 runc:
  Version:          1.1.9
  GitCommit:        82f18fe0e44a59034f3e1f45e475fa5636e539aa
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ kind version
kind v0.20.0 go1.20.4 darwin/arm64

這里我們將安裝多集群的相關(guān)腳本放在了 github.com/cnych/multi-cluster-istio-kind 倉(cāng)庫(kù)中,先將這個(gè)倉(cāng)庫(kù)克隆到本地,然后進(jìn)入到 multi-cluster-istio-kind 目錄,在 kind-create 目錄下面是我們定義了一個(gè) create-cluster.sh 腳本,用于創(chuàng)建多個(gè) K8s 集群:

# This script handles the creation of multiple clusters using kind and the
# ability to create and configure an insecure container registry.

set -o xtrace
set -o errexit
set -o nounset
set -o pipefail

# shellcheck source=util.sh
NUM_CLUSTERS="${NUM_CLUSTERS:-2}"
KIND_IMAGE="${KIND_IMAGE:-}"
KIND_TAG="${KIND_TAG:-v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72}"
OS="$(uname)"
function create-clusters() {
  local num_clusters=${1}

  local image_arg=""
  if [[ "${KIND_IMAGE}" ]]; then
    image_arg="--image=${KIND_IMAGE}"
  elif [[ "${KIND_TAG}" ]]; then
    image_arg="--image=kindest/node:${KIND_TAG}"
  fi
  for i in $(seq "${num_clusters}"); do
    kind create cluster --name "cluster${i}" "${image_arg}"
    fixup-cluster "${i}"
    echo

  done
}
function fixup-cluster() {
  local i=${1} # cluster num

  if [ "$OS" != "Darwin" ];then
    # Set container IP address as kube API endpoint in order for clusters to reach kube API servers in other clusters.
    local docker_ip
    docker_ip=$(docker inspect --format='{{range .NetworkSettingkc s.Networks}}{{.IPAddress}}{{end}}' "cluster${i}-control-plane")
    kubectl config set-cluster "kind-cluster${i}" --server="https://${docker_ip}:6443"
  fi

  # Simplify context name
  kubectl config rename-context "kind-cluster${i}" "cluster${i}"
}
echo "Creating ${NUM_CLUSTERS} clusters"
create-clusters "${NUM_CLUSTERS}"
kubectl config use-context cluster1

echo "Kind CIDR is $(docker network inspect -f '{{$map := index .IPAM.Config 0}}{{index $map "Subnet"}}' kind)"

echo "Complete"

上面的腳本默認(rèn)會(huì)創(chuàng)建兩個(gè) v1.27.3 版本的 K8s 集群,這里需要注意的是我們安裝的每個(gè)集群的 APIServer 必須能被網(wǎng)格中其他集群訪(fǎng)問(wèn),很多云服務(wù)商通過(guò)網(wǎng)絡(luò)負(fù)載均衡器(NLB)開(kāi)放 APIServer 的公網(wǎng)訪(fǎng)問(wèn)。如果 APIServer 不能被直接訪(fǎng)問(wèn),則需要調(diào)整安裝流程以放開(kāi)訪(fǎng)問(wèn),我們這里容器的 IP 地址設(shè)置為 kube API 端點(diǎn)地址,以便集群可以訪(fǎng)問(wèn)其他集群中的 kube API 服務(wù)器。

直接運(yùn)行上面的腳本即可創(chuàng)建兩個(gè) K8s 集群:

cd kind-create
bash ./create-cluster.sh

可以安裝一個(gè) kubectx 工具來(lái)方便切換集群。

另外 istio 創(chuàng)建的入口和出口網(wǎng)關(guān)都需要外部 IP,我們可以使用 MetalLB 來(lái)進(jìn)行分配。

# install-metallb.sh
#!/usr/bin/env bash

set -o xtrace
set -o errexit
set -o nounset
set -o pipefail
NUM_CLUSTERS="${NUM_CLUSTERS:-2}"

for i in $(seq "${NUM_CLUSTERS}"); do
  echo "Starting metallb deployment in cluster${i}"
  kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/master/manifests/namespace.yaml --context "cluster${i}"
  kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)" --context "cluster${i}"
  kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/master/manifests/metallb.yaml --context "cluster${i}"
  kubectl apply -f ./metallb-configmap-${i}.yaml --context "cluster${i}"
  echo "----"
done

kind 集群控制的 IP 地址范圍可以通過(guò) docker network inspect -f '{{$map := index .IPAM.Config 0}}{{index $map "Subnet"}}' kind 獲取。比如我們這里上述命令的輸出是 192.168.247.0/24,我們已經(jīng)創(chuàng)建了 metallb-configmap-1.yaml 和 metallb-configmap-2.yaml,這會(huì)將 192.168.247.225-192.168.247.250 和 192.168.247.200-192.168.247.224 IP 范圍分別分配給 cluster1 和 cluster2。

應(yīng)用上面的腳本安裝 metallb:

cd kind-create
bash ./install-metallb.sh

多集群服務(wù)網(wǎng)格部署要求我們?cè)诰W(wǎng)格中的所有集群之間建立信任,我們需要使用一個(gè)公共的根 CA 來(lái)為每個(gè)集群生成中間證書(shū),在 kind-create 目錄中同樣我們定義了一個(gè)安裝 CA 的腳本:

cd kind-create
bash ./install-cacerts.sh

在 tools/certs 目錄下面包含兩個(gè)用于生成新根證書(shū)、中間證書(shū)和工作負(fù)載證書(shū)的 Makefile:

  • Makefile.k8s.mk:基于 k8s 集群中的 root-ca 創(chuàng)建證書(shū)。默認(rèn) kubeconfig 中的當(dāng)前上下文用于訪(fǎng)問(wèn)集群。
  • Makefile.selfsigned.mk:根據(jù)生成的自簽名根創(chuàng)建證書(shū)。

執(zhí)行上面的腳本后會(huì)生成一個(gè)公共的根 CA 證書(shū),然后會(huì)使用這個(gè)證書(shū)為 cluster1 和 cluster2 集群生成中間證書(shū),而且在這個(gè)腳本中,我們將 istio 命名空間添加了一個(gè) topology.istio.io/network=network${i} 標(biāo)簽。

Root CA

接下來(lái)就可以安裝 Istio 集群了,在 istio-create 目錄下面我們定義了一個(gè) install-istio.sh 腳本,用于安裝 Istio 集群:

#!/usr/bin/env bash

set -o xtrace
set -o errexit
set -o nounset
set -o pipefail

OS="$(uname)"
NUM_CLUSTERS="${NUM_CLUSTERS:-2}"

for i in $(seq "${NUM_CLUSTERS}"); do
echo "Starting istio deployment in cluster${i}"

kubectl --cnotallow="cluster${i}" get namespace istio-system && \
kubectl --cnotallow="cluster${i}" label namespace istio-system topology.istio.io/network="network${i}"

sed -e "s/{i}/${i}/" cluster.yaml > "cluster${i}.yaml"
istioctl install --force --cnotallow="cluster${i}" -f "cluster${i}.yaml"

echo
done

其中有一個(gè)比較重要的是 cluster.yaml 文件,這個(gè)文件定義了 Istio 的安裝配置,由于我們這里使用的是非扁平網(wǎng)絡(luò)多控制面模型,所以我們需要在這個(gè)文件中定義 network 和 clusterName 用來(lái)標(biāo)識(shí)不同的 Istio 集群,這里我們將 network 設(shè)置為 network${i},將 clusterName 設(shè)置為 cluster${i}。

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    global:
      meshID: mesh{i}
      multiCluster:
        clusterName: cluster{i}
      network: network{i}

直接運(yùn)行上面的腳本即可在兩個(gè) Kubernetes 集群中分別安裝 Istio 集群:

cd istio-create
bash ./install-istio.yaml

在安裝過(guò)程需要手動(dòng)確認(rèn)是否安裝 Istio,輸入 y 即可。默認(rèn)安裝完成后會(huì)有 istiod、istio-ingressgateway 以及 istio-eastwestgateway 三個(gè)組件:

# 兩個(gè) kubernetes 集群都有這三個(gè)組件
$ kubectl get pods -n istio-system
NAME                                     READY   STATUS    RESTARTS   AGE
istio-eastwestgateway-66758cf789-dztsz   1/1     Running   0          23m
istio-ingressgateway-6d4bc4cc8f-ppdjx    1/1     Running   0          2m6s
istiod-79d66c57dd-gmx76                  1/1     Running   0          2m8s
$ kubectl get svc -n istio-system
NAME                    TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                                                           AGE
istio-eastwestgateway   LoadBalancer   10.96.251.150   192.168.247.226   15021:31106/TCP,15443:30675/TCP,15012:30483/TCP,15017:30517/TCP   24m
istio-ingressgateway    LoadBalancer   10.96.111.72    192.168.247.225   15021:30540/TCP,80:31137/TCP,443:32705/TCP                        47m
istiod                  ClusterIP      10.96.45.118    <none>            15010/TCP,15012/TCP,443/TCP,15014/TCP                             47m

由于我們?cè)?Kubernetes 集群中安裝了 metallb,所以我們可以看到 istio-ingressgateway 服務(wù)的 EXTERNAL-IP 被分配了一個(gè) IP 地址,這個(gè)地址是我們?cè)?nbsp;metallb-configmap-1.yaml 和 metallb-configmap-2.yaml 中定義的范圍內(nèi)。

前面我們提到過(guò)非扁平網(wǎng)絡(luò)多控制面模型的場(chǎng)景下需要一個(gè)專(zhuān)用于東西向流量的網(wǎng)關(guān),所有配置都依賴(lài)于專(zhuān)用于東西向流量的單獨(dú)網(wǎng)關(guān)部署。這樣做是為了避免東西向流量淹沒(méi)默認(rèn)的南北向入口網(wǎng)關(guān)。上面的腳本中同樣也包括生成東西向網(wǎng)關(guān)的配置。

到這里 istio 集群和專(zhuān)用于東西向流量的網(wǎng)關(guān)都安裝成功了。因?yàn)榧何挥诓煌木W(wǎng)絡(luò)中,所以我們需要在兩個(gè)集群東西向網(wǎng)關(guān)上開(kāi)放所有服務(wù)(*.local)。雖然此網(wǎng)關(guān)在互聯(lián)網(wǎng)上是公開(kāi)的,但它背后的服務(wù)只能被擁有可信 mTLS 證書(shū)、工作負(fù)載 ID 的服務(wù)訪(fǎng)問(wèn), 就像它們處于同一網(wǎng)絡(luò)一樣。執(zhí)行下面的命令在兩個(gè)集群中暴露服務(wù):

NUM_CLUSTERS="${NUM_CLUSTERS:-2}"

for i in $(seq "${NUM_CLUSTERS}"); do
  echo "Expose services in cluster${i}"
  kubectl --cnotallow="cluster${i}" apply -n istio-system -f samples/multicluster/expose-services.yaml

  echo
done

上面的命令其實(shí)就是在兩個(gè)集群中創(chuàng)建如下所示的 Gateway 對(duì)象,用來(lái)暴露所有的服務(wù):

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: cross-network-gateway
spec:
  selector:
    istio: eastwestgateway # 專(zhuān)用于東西向流量的網(wǎng)關(guān)
  servers:
    - port:
        number: 15443 # 已經(jīng)聲明了
        name: tls
        protocol: TLS
      tls:
        mode: AUTO_PASSTHROUGH # 東西向網(wǎng)關(guān)工作模式是 TLS AUTO_PASSTHROUGH,不支持 HTTP 路由策略
      hosts:
        - "*.local" # 暴露所有的服務(wù)

最后我們還需要配置每個(gè) istiod 來(lái) watch 其他集群的 APIServer,我們使用 K8s 集群的憑據(jù)來(lái)創(chuàng)建 Secret 對(duì)象,以允許 Istio 訪(fǎng)問(wèn)其他 (n-1) 個(gè)遠(yuǎn)程 kubernetes apiserver。

cd istio-setup
bash ./enable-endpoint-discovery.sh

在上面的腳本中我們將使用 istioctl create-remote-secret 命令來(lái)使用 K8s 集群的憑據(jù)來(lái)創(chuàng)建 Secret 對(duì)象,以允許 Istio 訪(fǎng)問(wèn)遠(yuǎn)程的 Kubernetes apiservers。

docker_ip=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "cluster${i}-control-plane")
istioctl create-remote-secret \
--cnotallow="cluster${i}" \
--server="https://${docker_ip}:6443" \
--name="cluster${i}" | \
    kubectl apply --validate=false --cnotallow="cluster${j}" -f -

這樣 cluster1 和 cluster2 均可以監(jiān)測(cè)兩個(gè)集群 API Server 的服務(wù)端點(diǎn)了,我們的非扁平網(wǎng)絡(luò)多控制面模型的 Istio 集群就安裝完成了。

多集群應(yīng)用測(cè)試

接下來(lái)我們可以部署一個(gè)簡(jiǎn)單的示例來(lái)驗(yàn)證下我們的多集群服務(wù)網(wǎng)格是否安裝成功了。

這里我們將在所有集群中創(chuàng)建名為 sample 的命名空間,然后在所有集群中創(chuàng)建 helloworld 的 Service,并在每個(gè)集群中交替部署 helloworld 的 v1 和 v2 兩個(gè)版本。

cd testing
bash ./deploy-app.sh

部署完成后在 cluster1 集群中將運(yùn)行 v2 版本,在 cluster2 集群中將運(yùn)行 v1 版本:

# cluster1 集群
$ kubectl get pods -n sample
NAME                             READY   STATUS    RESTARTS   AGE
helloworld-v2-79d5467d55-7k2hv   2/2     Running   0          3m57s
# cluster2 集群
$ kubectl get pods -n sample
NAME                           READY   STATUS    RESTARTS   AGE
helloworld-v1-b6c45f55-8lw2j   2/2     Running   0          4m25s

此外我們還在 sample 命名空間下面部署了一個(gè)用于測(cè)試的 sleep 應(yīng)用,我們可以到 sleep Pod 中進(jìn)行測(cè)試,如下的命令:

while true; do curl -s "helloworld.sample:5000/hello"; done

正常會(huì)輸出如下所示的內(nèi)容:

Hello version: v1, instance: helloworld-v1-776f57d5f6-znwk5
Hello version: v2, instance: helloworld-v2-54df5f84b-qmg8t..
...

同樣我們換另外一個(gè)集群的 sleep Pod 重復(fù)上面的命令,重復(fù)幾次這個(gè)請(qǐng)求,驗(yàn)證 HelloWorld 的版本在 v1 和 v2 之間切換:

Hello version: v1, instance: helloworld-v1-776f57d5f6-znwk5
Hello version: v2, instance: helloworld-v2-54df5f84b-qmg8t..
...

到這里我們就成功在多集群環(huán)境中安裝、并驗(yàn)證了 Istio!

地域負(fù)載均衡

接下來(lái)我們來(lái)了解下如何在 Istio 中配置地域負(fù)載均衡。

一個(gè)地域定義了 workload instance 在網(wǎng)格中的地理位置。這三個(gè)元素定義了一個(gè)地域:

  • Region:代表較大的地理區(qū)域,例如 us-east,一個(gè)地區(qū)通常包含許多可用區(qū)。在 Kubernetes 中,標(biāo)簽 topology.kubernetes.io/region 決定了節(jié)點(diǎn)所在的地區(qū)。
  • Zone:區(qū)域內(nèi)的一組計(jì)算資源。通過(guò)在地區(qū)內(nèi)的多個(gè)區(qū)域中運(yùn)行服務(wù),可以在地區(qū)內(nèi)的區(qū)域之間進(jìn)行故障轉(zhuǎn)移,同時(shí)保持最終用戶(hù)的數(shù)據(jù)地域性。在 Kubernetes 中,標(biāo)簽 topology.kubernetes.io/zone 決定了節(jié)點(diǎn)所在的區(qū)域。
  • Sub-zone:分區(qū),允許管理員進(jìn)一步細(xì)分區(qū)域,以實(shí)現(xiàn)更細(xì)粒度的控制。Kubernetes 中不存在分區(qū)的概念,在 Istio 中引入了自定義節(jié)點(diǎn)標(biāo)簽 topology.istio.io/subzone 來(lái)定義分區(qū)。

如果你使用托管的 Kubernetes 服務(wù),則云提供商會(huì)為你配置地區(qū)和區(qū)域標(biāo)簽。如果你正在運(yùn)行自己的 Kubernetes 集群,則需要將這些標(biāo)簽添加到自己的節(jié)點(diǎn)上。比如前面我們使用 Kind 搭建的兩個(gè)集群已經(jīng)添加上了相應(yīng)的標(biāo)簽:

$ kubectl get nodes --show-labels --context cluster1
NAME                     STATUS   ROLES           AGE   VERSION   LABELS
cluster1-control-plane   Ready    control-plane   38h   v1.27.3   beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux,kubernetes.io/arch=arm64,kubernetes.io/hostname=cluster1-control-plane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=,topology.kubernetes.io/reginotallow=region1,topology.kubernetes.io/znotallow=zone1
$ kubectl get nodes --show-labels --context cluster2
NAME                     STATUS   ROLES           AGE   VERSION   LABELS
cluster2-control-plane   Ready    control-plane   38h   v1.27.3   beta.kubernetes.io/arch=arm64,beta.kubernetes.io/os=linux,kubernetes.io/arch=arm64,kubernetes.io/hostname=cluster2-control-plane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=,topology.kubernetes.io/reginotallow=region2,topology.kubernetes.io/znotallow=zone2

地域是分層的,按匹配順序排列:Region -> Zone -> Sub-zone。這意味著,在 foo 地區(qū)的 bar 區(qū)域中運(yùn)行 Pod 不會(huì)被視為在 baz 地區(qū)的 bar 區(qū)域中運(yùn)行的 Pod。

配置權(quán)重分布

現(xiàn)在我們有兩個(gè) Istio 集群,接下來(lái)我們來(lái)配置下權(quán)重分布。權(quán)重分布是一種流量管理策略,它允許您將流量分配到不同的地區(qū)。這里我們配置 region1 -> zone1 和 region1 -> zone2 兩個(gè)地區(qū)的權(quán)重分別為 80% 和 20%。

首先為 helloworld 服務(wù)創(chuàng)建一個(gè)專(zhuān)用的 Gateway 和 VirtualService 對(duì)象:

# helloworld-gateway.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: helloworld-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
    - "*"
  gateways:
    - helloworld-gateway
  http:
    - match:
        - uri:
            exact: /hello
      route:
        - destination:
            host: helloworld
            port:
              number: 5000

在兩個(gè)集群中都需要部署這個(gè) Gateway 和 VirtualService 對(duì)象:

kubectl apply -f samples/helloworld/helloworld-gateway.yaml -n sample --context cluster1
kubectl apply -f samples/helloworld/helloworld-gateway.yaml -n sample --context cluster2

接下來(lái)我們就可以分別通過(guò) cluster1 和 cluster2 集群的 Gateway 來(lái)訪(fǎng)問(wèn) helloworld 服務(wù)了:

# 集群 1
$ kubectl get svc istio-ingressgateway -n istio-system --context cluster1
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                                      AGE
istio-ingressgateway   LoadBalancer   10.96.199.106   192.168.247.225   15021:31651/TCP,80:32531/TCP,443:32631/TCP   38h
$ while true; do curl -s "http://192.168.247.225/hello"; done
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
# 集群 2
$ kubectl get svc istio-ingressgateway -n istio-system --context cluster2
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)                                      AGE
istio-ingressgateway   LoadBalancer   10.96.149.60   192.168.247.175   15021:31057/TCP,80:30392/TCP,443:32610/TCP   38h
$ while true; do curl -s "http://192.168.247.175/hello"; done
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69

從上面結(jié)果可以看出來(lái)無(wú)論我們?cè)L問(wèn)哪個(gè)集群的 Gateway,都會(huì)將流量負(fù)載到兩個(gè)集群中的 helloworld 服務(wù)上,當(dāng)然如果是在線(xiàn)上環(huán)境,我們?cè)谧钋懊婵梢约由弦粋€(gè)統(tǒng)一的 LB 入口,這樣就可以將流量負(fù)載到不同地區(qū)/區(qū)域的集群中了。

如果我們想對(duì)流量進(jìn)行更精細(xì)的控制,比如我們想將 region1 -> zone1 和 region1 -> zone2 兩個(gè)地區(qū)的權(quán)重分別為 80% 和 20%,那么我們可以使用 DestinationRule 來(lái)配置權(quán)重分布了。

創(chuàng)建如下所示的 DestinationRule 對(duì)象:

# locality-lb-weight.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld
  namespace: sample
spec:
  host: helloworld.sample.svc.cluster.local
  trafficPolicy:
    connectionPool:
      http:
        maxRequestsPerConnection: 1
    loadBalancer:
      simple: ROUND_ROBIN
      localityLbSetting:
        enabled: true
        distribute:
          - from: region1/*
            to:
              "region1/*": 80
              "region2/*": 20
          - from: region2/*
            to:
              "region2/*": 80
              "region1/*": 20
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s
      baseEjectionTime: 1m

在上面的 DestinationRule 對(duì)象中我們指定了流量策略,其中最重要的是 localityLbSetting,它定義了流量按地區(qū)的分布策略,如果流量請(qǐng)求來(lái)自 region1 地區(qū),那么將有 80% 的流量被負(fù)載到 region1,有 20% 的流量被負(fù)載到 region2,反之亦然,這樣就實(shí)現(xiàn)了地區(qū)的按權(quán)重的負(fù)載均衡。最后通過(guò) outlierDetection 配置了故障檢測(cè)。

在兩個(gè)集群中都需要部署這個(gè) DestinationRule 對(duì)象:

kubectl apply -f samples/helloworld/locality-lb-weight.yaml -n sample --context cluster1
kubectl apply -f samples/helloworld/locality-lb-weight.yaml -n sample --context cluster2

創(chuàng)建過(guò)后當(dāng)我們?cè)俅卧L(fǎng)問(wèn) helloworld 服務(wù)時(shí),就會(huì)按照我們配置的權(quán)重分布來(lái)負(fù)載流量了:

# 集群1
$ while true; do curl -s "http://192.168.247.225/hello"; done
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
# 集群2
$ while true; do curl -s "http://192.168.247.175/hello"; done
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v2, instance: helloworld-v2-79d5467d55-mvgms

到這里我們就成功的在 Istio 中配置了按權(quán)重的地域負(fù)載均衡了。

配置地域故障轉(zhuǎn)移

我們知道當(dāng)我們?cè)诙鄠€(gè)地區(qū)/區(qū)域部署多個(gè)服務(wù)實(shí)例時(shí),如果某個(gè)地區(qū)/區(qū)域的服務(wù)實(shí)例不可用,那么我們可以將流量轉(zhuǎn)移到其他地區(qū)/區(qū)域的服務(wù)實(shí)例上,實(shí)現(xiàn)地域故障轉(zhuǎn)移,這樣就可以保證服務(wù)的高可用性。

同樣在 Istio 中要實(shí)現(xiàn)地域故障轉(zhuǎn)移,我們需要使用 DestinationRule 對(duì)象來(lái)配置故障轉(zhuǎn)移策略,比如我們將 region1 故障轉(zhuǎn)移到 region2,region2 故障轉(zhuǎn)移到 region1。創(chuàng)建如下所示的 DestinationRule 對(duì)象:

# locality-lb-failover.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld
  namespace: sample
spec:
  host: helloworld.sample.svc.cluster.local
  trafficPolicy:
    connectionPool:
      http:
        maxRequestsPerConnection: 1 # 關(guān)閉 HTTP Keep-Alive,強(qiáng)制每個(gè)HTTP請(qǐng)求使用一個(gè)新連接的策略
    loadBalancer:
      simple: ROUND_ROBIN
      localityLbSetting:
        enabled: true
        failover:
          - from: region1
            to: region2
          - from: region2
            to: region1
    outlierDetection:
      consecutive5xxErrors: 1 # 連續(xù) 1 次 5xx 錯(cuò)誤
      interval: 1s # 檢測(cè)間隔 1s
      baseEjectionTime: 1m # 基礎(chǔ)驅(qū)逐時(shí)間 1m

要實(shí)現(xiàn)故障轉(zhuǎn)移非常簡(jiǎn)單,只需要在 localityLbSetting 中配置 failover,這里我們將 region1 故障轉(zhuǎn)移到 region2,region2 故障轉(zhuǎn)移到 region1。

在兩個(gè)集群中都需要部署這個(gè) DestinationRule 對(duì)象:

kubectl apply -f samples/helloworld/locality-lb-failover.yaml -n sample --context cluster1
kubectl apply -f samples/helloworld/locality-lb-failover.yaml -n sample --context cluster2

創(chuàng)建完成后我們先訪(fǎng)問(wèn)從集群 1 訪(fǎng)問(wèn) helloworld 服務(wù):

# 集群1
$ while true; do curl -s "http://192.168.247.225/hello"; done
Hello version: v2, instance: helloworld-v2-79d5467d55-m7sp9
Hello version: v2, instance: helloworld-v2-79d5467d55-m7sp9
Hello version: v2, instance: helloworld-v2-79d5467d55-m7sp9
Hello version: v2, instance: helloworld-v2-79d5467d55-m7sp9
Hello version: v2, instance: helloworld-v2-79d5467d55-m7sp9

驗(yàn)證響應(yīng)中的 version 是 v2,也就是說(shuō)我們?cè)L問(wèn)的是 region1 的 helloworld 服務(wù)。重復(fù)幾次,驗(yàn)證響應(yīng)總是相同的,因?yàn)楝F(xiàn)在沒(méi)有任何故障,所以只訪(fǎng)問(wèn)本區(qū)域的實(shí)例。

接下來(lái),觸發(fā)故障轉(zhuǎn)移到 region2。這里我們將 region1 中 HelloWorld 逐出 Envoy Sidecar 代理:

$ kubectl --cnotallow=cluster1 exec \
  "$(kubectl get pod --cnotallow=cluster1 -n sample -l app=helloworld \
  -l versinotallow=v2 -o jsnotallow='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

再次訪(fǎng)問(wèn) helloworld 服務(wù):

$ while true; do curl -s "http://192.168.247.225/hello"; done
upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: delayed connect error: 111
upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: delayed connect error: 111
# ......
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69
Hello version: v1, instance: helloworld-v1-b6c45f55-r2l69

前面幾次調(diào)用將會(huì)失敗,差不多一分鐘后故障檢測(cè)生效,這將觸發(fā)故障轉(zhuǎn)移,多次重復(fù)該命令,并驗(yàn)證響應(yīng)中的 version 始終為 v1,也就是說(shuō)我們?cè)L問(wèn)的是 region2 的 helloworld 服務(wù),這樣就實(shí)現(xiàn)了地域故障轉(zhuǎn)移。

責(zé)任編輯:姜華 來(lái)源: k8s技術(shù)圈
相關(guān)推薦

2024-04-28 08:24:27

分布式架構(gòu)Istio

2023-06-12 07:41:16

dockerspark集群

2023-06-27 08:00:35

2022-11-03 08:16:33

MySQL·窗口函數(shù)

2024-01-19 08:25:38

死鎖Java通信

2023-01-10 08:43:15

定義DDD架構(gòu)

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-07-26 13:11:21

ChatGPT平臺(tái)工具

2024-01-02 12:05:26

Java并發(fā)編程

2023-08-01 12:51:18

WebGPT機(jī)器學(xué)習(xí)模型

2023-04-10 09:31:00

路由技術(shù)廠商

2024-04-09 13:16:21

Rust命名規(guī)范

2022-06-21 07:51:15

云原生應(yīng)用鏈路

2023-01-30 09:01:54

圖表指南圖形化

2024-08-06 09:47:57

2022-07-08 09:27:48

CSSIFC模型

2023-10-10 11:04:11

Rust難點(diǎn)內(nèi)存

2024-07-31 08:39:45

Git命令暫存區(qū)

2023-12-12 08:02:10

2024-05-06 00:00:00

InnoDBView隔離
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

99久久精品费精品国产一区二区 | 国产一区二中文字幕在线看| 91成人精品一区二区| 国产精品亚洲四区在线观看| 亚洲第一成年网| 日韩wuma| 少妇高潮久久久| 麻豆成人免费电影| 97香蕉超级碰碰久久免费软件 | 激情久久综合网| 九色porny自拍视频在线观看| 国产精品久久久久久久第一福利 | 国产成人精品久久亚洲高清不卡| 侵犯稚嫩小箩莉h文系列小说| 亚洲动漫精品| 欧美白人最猛性xxxxx69交| 无码少妇一区二区三区芒果| wwwww亚洲| 中文字幕一区二区三区四区不卡| 久久久久久草| 国产成人无码www免费视频播放| 欧美aaaaaa午夜精品| 91成人在线视频| 丰满少妇被猛烈进入一区二区| 九九久久婷婷| 亚洲国产一区自拍| 一个人看的视频www| 成人在线免费| 欧美午夜性色大片在线观看| 成人免费视频91| av网站大全在线| 国产精品大尺度| 日本一区二区高清视频| 深爱五月激情五月| 粉嫩绯色av一区二区在线观看| 国产综合香蕉五月婷在线| 日韩免费av网站| 国产精品久久久久9999高清| 久久久久久久网站| 丁香花五月激情| **女人18毛片一区二区| 色吧影院999| 男人的天堂官网| 视频一区在线观看| 国产视频丨精品|在线观看| 日本三级日本三级日本三级极| 91蜜桃臀久久一区二区| 欧美一级片免费看| 国产在线视频三区| 日韩精品一区二区三区中文字幕| 这里只有精品电影| 午夜xxxxx| 国产激情综合| 日韩欧美激情四射| 欧美一区二区三区影院| 久久天堂久久| 精品国产乱码久久久久久影片| 国产精品99精品无码视亚| 日韩有吗在线观看| 精品va天堂亚洲国产| 国产在线观看免费播放| 女一区二区三区| 日韩精品极品在线观看| 一本加勒比北条麻妃| 精品国产一区二区三区av片| 在线色欧美三级视频| 日韩精品一区二区三区在线视频| 91tv官网精品成人亚洲| 色综合久久精品亚洲国产| 精品无码久久久久久久久| 亚洲久久成人| 国产精品极品美女粉嫩高清在线| 夜夜躁很很躁日日躁麻豆| 国内国产精品久久| 国产精品免费看一区二区三区| 欧美一区,二区| 久久综合久色欧美综合狠狠| 午夜视频久久久| 综合久久2o19| 精品久久久久久亚洲精品| 国产成人手机视频| 国产亚洲观看| 日韩精品免费观看| 美女福利视频网| 亚洲电影在线| 国产精品女视频| www.久久成人| 久久久久久久久久久黄色| 亚洲视频在线观看日本a| 亚洲小说区图片| 色综合久久88色综合天天| 成人综合久久网| 日韩激情网站| 久久亚洲精品成人| 日本中文字幕在线| 国产尤物一区二区| 美乳视频一区二区| 蜜桃视频在线观看www社区| 亚洲综合另类小说| 国产一区二区在线免费播放| caoporn成人| 日韩在线观看免费av| 亚洲视频免费播放| 激情六月婷婷久久| 日本福利一区二区三区| 手机在线免费av| 欧美视频你懂的| 少妇精品无码一区二区三区| 91精品蜜臀一区二区三区在线| 91tv亚洲精品香蕉国产一区7ujn| 国产美女精品视频国产| 久久你懂得1024| 97干在线视频| 999精品视频在线观看| 亚洲免费av网址| 国产精品a成v人在线播放| 久久av中文字幕片| 日本亚洲欧洲精品| 中文字幕一区久| 精品久久国产老人久久综合| 国产稀缺精品盗摄盗拍| 日韩精品视频网站| 久久久久九九九| av男人的天堂在线观看| 日韩精品一区二区三区蜜臀| 四虎884aa成人精品| 麻豆久久久久久| 日韩国产在线一区| 欧美人与性动交xxⅹxx| 日韩精品免费在线视频观看| 国产精彩视频在线观看| 国产麻豆视频一区二区| 国产免费色视频| 日韩精品一级毛片在线播放| 在线日韩第一页| 国产亚洲久一区二区| 国产日韩在线不卡| 18禁免费无码无遮挡不卡网站| 伊色综合久久之综合久久| 久久国产精品首页| 国产色片在线观看| 国产精品国产自产拍高清av | av在线日韩| 亚洲区免费影片| 波多野结衣理论片| 国产欧美日产一区| 男人插女人下面免费视频| 国产精品一区高清| 国产成人精品视频在线观看| 精品美女视频在线观看免费软件| 欧美性极品少妇精品网站| 久久人妻少妇嫩草av无码专区| 亚洲欧洲综合| 久久久久久久久久久久久9999| 在线观看特色大片免费视频| 亚洲男人7777| 亚洲av人无码激艳猛片服务器| 国产精品青草综合久久久久99| 91小视频网站| 一区二区三区四区电影| 成人欧美一区二区三区视频| eeuss鲁一区二区三区| 精品亚洲永久免费精品| 婷婷激情五月综合| 国产精品视频你懂的| 亚洲 国产 图片| 亚洲女同中文字幕| 国产精品视频入口| 碰碰在线视频| 一道本无吗dⅴd在线播放一区| 在线观看毛片视频| 亚洲色大成网站www久久九九| 韩国三级与黑人| 国产精品亚洲欧美| 亚洲国产欧美不卡在线观看| 精品国产亚洲一区二区三区大结局| 欧美精品videofree1080p| 少妇性bbb搡bbb爽爽爽欧美| 欧美羞羞免费网站| 日韩女优一区二区| 99热这里都是精品| 天天干天天爽天天射| 欧美精品播放| 日韩av一区二区三区在线观看| 成人网av.com/| 91精品国产亚洲| 婷婷免费在线视频| 亚洲精品wwwww| 国产精品久久久久久久久久久久久久久久久久| 一区二区三区四区视频精品免费| 国产制服丝袜在线| 精品一二三四区| 免费在线激情视频| 91精品国产自产在线观看永久∴| 久久99九九| 精品国产乱码久久久久久樱花| 欧美亚洲国产精品| 黄色动漫在线观看| 亚洲女人天堂成人av在线| 国产特级黄色片| 日本韩国视频一区二区| 久久综合亚洲色hezyo国产| 国产亚洲欧洲一区高清在线观看| 黑人无套内谢中国美女| 日本不卡的三区四区五区| 国产www免费| 香蕉av一区二区| 日本在线成人一区二区| 国产成人av毛片| 91香蕉国产在线观看| 欧美最新精品| 欧美一二三视频| 日韩影视在线| 久久成人人人人精品欧| 不卡在线视频| 亚洲少妇中文在线| 天天色综合av| 亚洲第一级黄色片| www.四虎在线观看| 欧美剧情片在线观看| 精人妻无码一区二区三区| 精品久久久久久久久久久| 久久久久黄色片| 亚洲男人的天堂在线观看| 国产破处视频在线观看| 久久久久青草大香线综合精品| 三级视频网站在线观看| 国产69精品久久久久毛片 | 在线观看日本视频| 亚洲一区二区美女| 久久久久久久久久一区二区三区| 亚洲人成影院在线观看| 永久久久久久久| 综合久久综合久久| 亚洲毛片亚洲毛片亚洲毛片| 国产偷国产偷亚洲高清人白洁| 精品人妻一区二区三区香蕉| 99精品久久免费看蜜臀剧情介绍| 日韩女优在线视频| 国产suv精品一区二区6| 少妇欧美激情一区二区三区| 国产成人免费视频| 精产国品一区二区三区| 国内精品国产成人| aaaaa黄色片| 懂色av一区二区三区免费看| 老熟女高潮一区二区三区| 国产精品18久久久| 精品人妻在线视频| 99精品视频在线观看| 给我看免费高清在线观看| 久久综合久久综合亚洲| 日本乱子伦xxxx| 国产精品国产三级国产有无不卡 | 老**午夜毛片一区二区三区| 免费激情视频在线观看| 奇米777欧美一区二区| 亚洲精品性视频| 国产一区二区三区蝌蚪| www日本在线观看| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 麻豆成人久久精品二区三区红 | 久本草在线中文字幕亚洲| 精品欧美一区二区在线观看视频| 妖精视频一区二区三区| 亚洲精品一区二区三| 亚洲色图国产| 国产一区二区三区乱码| 噜噜噜91成人网| 亚洲娇小娇小娇小| 国产成a人无v码亚洲福利| 国产精品第七页| 国产精品美女久久久久久2018 | 日韩欧美精品网址| 中文字幕精品一区二区精| 日韩情涩欧美日韩视频| 日漫免费在线观看网站| 日韩中文字幕亚洲| 蜜臀av国内免费精品久久久夜夜| 欧洲亚洲在线视频| 日韩五码电影| 国产一区二区在线网站| 久久综合99| 日本丰满少妇xxxx| 蜜桃久久精品一区二区| 稀缺呦国内精品呦| 欧美国产日韩在线观看| 欧美三级免费看| 色狠狠色狠狠综合| www.色婷婷.com| 一区二区福利视频| 久操av在线| 国产久一一精品| 欧美中文一区| 91九色国产ts另类人妖| 久久久久久一区二区| 日本成人在线免费观看| 久久久综合精品| 国产一级二级毛片| 欧美久久久一区| 免费在线高清av| 欧美极品少妇xxxxx| 超碰国产精品一区二页| 久久久久久精| 亚洲国产一区二区三区高清| 午夜免费看毛片| 久久精品欧美一区二区三区不卡| 国产精品1000| 日韩免费看网站| 亚乱亚乱亚洲乱妇| 日本高清久久天堂| 国产精品久av福利在线观看| 中文字幕精品在线播放| 日韩—二三区免费观看av| 亚洲精品乱码久久| 亚洲高清中文字幕| 国产a级免费视频| 精品国产一区二区三区久久久狼| 不卡福利视频| 国产日韩欧美精品| 欧美日韩亚洲三区| 激情成人在线观看| 自拍偷拍亚洲激情| 最近中文字幕在线视频| 亚洲欧美一区二区三区在线| 55av亚洲| 精品久久久久久乱码天堂| 欧美视频成人| 日本女人性视频| 亚洲三级电影网站| 国产又粗又大又爽| 日韩小视频在线观看| jizz亚洲女人高潮大叫| 日韩一本精品| 青青草成人在线观看| 国产美女永久免费无遮挡| 色婷婷亚洲精品| 韩国中文免费在线视频| 国产91露脸中文字幕在线| 伊人成综合网yiren22| 美女福利视频在线| 久久久99免费| 免费黄色小视频在线观看| 亚洲午夜av久久乱码| 97人人做人人爽香蕉精品| 日韩成人av电影在线| 麻豆一区二区三| 免费三级在线观看| 日韩精品一区二区三区在线观看| 手机av在线播放| 精品国产乱码一区二区三区四区| 一本不卡影院| 婷婷色一区二区三区| 欧美三电影在线| av中文字幕在线播放| 翡翠波斯猫1977年美国| 伊人久久大香线蕉综合热线| 中文字幕精品久久久| 色偷偷久久一区二区三区| 97人人在线| 91亚洲国产精品| 好看的亚洲午夜视频在线| 国产精品无码网站| 精品视频资源站| av免费在线观看网站| 国产另类自拍| 日韩精品一区第一页| 国产精品精品软件男同| 欧美va亚洲va香蕉在线| 精品91久久| 熟妇熟女乱妇乱女网站| 高清国产午夜精品久久久久久| 亚洲伊人成人网| 少妇高潮 亚洲精品| 在线日韩成人| 男女无套免费视频网站动漫| 亚洲精品五月天| 久草视频在线看| 亚洲一区二区三区在线视频| 国产亚洲精品v| 欧美风情第一页| 日韩成人免费视频| 欧美高清你懂的| 久久这里只有精品23| 国产欧美日韩激情| 蜜桃av中文字幕| 国产精品色午夜在线观看| 国产精品vip| 美女网站视频色| 亚洲激情视频在线播放| 亚洲精品伦理| 欧美日韩亚洲一| 亚洲欧美精品午睡沙发| 日本护士...精品国| 95av在线视频| 日韩精品乱码免费| 久久精品视频8| 久久久精品国产亚洲| 蜜桃一区二区三区| 韩国三级在线看|