国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

利用 CRD 實(shí)現(xiàn)一個(gè) mini-k8s-proxy

共 26142字,需瀏覽 53分鐘

 ·

2021-09-08 08:21

前言

進(jìn)入正文前,需要熟悉以下幾個(gè)概念定義:

  • Custom Resources: 資源(Resource) 是 Kubernetes API 中的一個(gè)端點(diǎn), 其中存儲的是某個(gè)類別的 API 對象(Objects)的一個(gè)集合。例如內(nèi)置的 pods 資源包含一組 Pod 對象。定制資源(Custom Resources)是對 Kubernetes API 的擴(kuò)展,可以動態(tài)的在集群內(nèi)安裝刪除,對用戶而言,如同使用 pods 這種內(nèi)置資源方式一樣,可以使用 kubectl 來創(chuàng)建和訪問定制資源里面的定制對象(Custom Objects)。

  • CustomResourceDefinition(CRD): CRD 定制資源定義是 Kubernetes 提供的向集群中添加定制資源(Custom Resources)的一種方式,允許用戶定義定制資源。

  • Custom Controllers: 定制資源只能存取結(jié)構(gòu)化的數(shù)據(jù),而定制控制器(Custom Controllers)可以通過觀測分析將結(jié)構(gòu)化的數(shù)據(jù)解釋為用戶所期望狀態(tài)的記錄,并持續(xù)地維護(hù)該狀態(tài)。它可以用于任何類別的資源,若定制資源與定制控制器相結(jié)合,定制資源就能夠提供真正的聲明式 API(Declarative API)。例如,Traefik 的 IngressRoute,apache apisix 的 apisix-ingress-controller ,以及本文接下來的示例等,都是通過編寫 CRD 創(chuàng)建定制資源 + 使用 k8s.io/code-generator 實(shí)現(xiàn)定制控制器完成的。

  • Operator: Operator 是 Kubernetes 的擴(kuò)展軟件,可以理解為一種特殊的 Controller ,旨在捕獲(正在管理一個(gè)或一組服務(wù)的)運(yùn)維人員的關(guān)鍵目標(biāo)。原理和 Controller 一樣,都是通過編寫 CRD 創(chuàng)建定制資源然后監(jiān)聽 CRD 相關(guān)變化并作出響應(yīng)。區(qū)別就在于 Operator 可能會結(jié)合原生的 Controller(Deployment/Replicas),或者 Kubernetes 的網(wǎng)絡(luò),存儲等來控制應(yīng)用程序的狀態(tài)。通俗點(diǎn)講就是,Operator 是一個(gè)功能更強(qiáng)大,封裝了對于特定應(yīng)用程序的運(yùn)維經(jīng)驗(yàn)的 Controller 。例如,etcd operator,prometheus operator 等。

如果覺得上面的定義太枯燥了,那就由我來簡單的總結(jié)一遍吧:

  • Kubernetes 里面呢,有很多內(nèi)置的資源,資源中包括對象,例如 pods 資源包含著一組 Pod 對象

  • Kubernetes 為了方便用戶,還允許用戶創(chuàng)建自定義資源,用戶創(chuàng)建出來的資源就取了個(gè)高大上的名字叫定制資源,同理,定制資源里有定制對象,例如 Traefik 里面的 ingressroutes 定制資源中包含著一組 IngressRoute 對象

  • 用戶想要?jiǎng)?chuàng)建定制資源,可以通過編寫 CustomResourceDefinition(CRD,定制資源定義)來實(shí)現(xiàn)

  • 用戶創(chuàng)建完定制資源后,還可以編寫代碼來監(jiān)聽資源的創(chuàng)建、刪除、更新動作,這就是一個(gè) Controller 控制器了

  • 用戶編寫的控制器如果是專注于某個(gè)特定的應(yīng)用程序,并賦予了特定的領(lǐng)域知識,就形成了一個(gè) Operator

目標(biāo)

實(shí)現(xiàn)一個(gè)可以通過配置 host 攔截到匹配的請求域名,將流量代理轉(zhuǎn)發(fā)到具體的 service 中(通過配置 serviceName,namespace,port,scheme)的極簡網(wǎng)絡(luò)代理工具。其中,配置通過 CRD 創(chuàng)建,代理程序可以通過控制器監(jiān)聽配置變化,動態(tài)更新,無需重啟。(PS:其實(shí)就是簡單模擬了 Traefik IngressRoute 的實(shí)現(xiàn))

創(chuàng)建 CRD

將下面的 CustomResourceDefinition 保存為 crd.yaml 文件

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # 名字必需與下面的 spec 字段匹配,并且格式為 '<名稱的復(fù)數(shù)形式>.<組名>'
  name: proxyroutes.miniproxy.togettoyou.com
spec:
  # 組名
  group: miniproxy.togettoyou.com
  names:
    # kind 通常是單數(shù)形式的駝峰編碼(CamelCased)形式。你的資源清單會使用這一形式。
    kind: ProxyRoute
    # shortNames 允許你在命令行使用較短的字符串來匹配資源
    shortNames:
      - pr
    # 名稱的復(fù)數(shù)形式,用于 URL:/apis/<組>/<版本>/<名稱的復(fù)數(shù)形式>
    plural: proxyroutes
    # 名稱的單數(shù)形式,作為命令行使用時(shí)和顯示時(shí)的別名
    singular: proxyroute
  # 可以是 Namespaced 或 Cluster
  scope: Namespaced
  # 列舉此 CustomResourceDefinition 所支持的版本
  versions:
    - name: v1alpha1
      # 每個(gè)版本都可以通過 served 標(biāo)志來獨(dú)立啟用或禁止
      served: true
      # 其中一個(gè)且只有一個(gè)版本必需被標(biāo)記為存儲版本
      storage: true
      # schema 是必需字段
      schema:
        # openAPIV3Schema 是用來檢查定制對象的模式定義
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                # 定義我們需要的幾個(gè)配置項(xiàng)
                host:
                  type: string
                serviceName:
                  type: string
                namespace:
                  type: string
                port:
                  type: integer
                scheme:
                  type: boolean

之后創(chuàng)建它:

kubectl apply -f crd.yaml

現(xiàn)在,就可以創(chuàng)建定制對象啦,將下面的 YAML 保存為 example.yaml

apiVersion: miniproxy.togettoyou.com/v1alpha1
kind: ProxyRoute
metadata:
  name: example-proxyroute
spec:
  # 監(jiān)聽域名
  host: whoami.togettoyou.com
  # 假設(shè)你有一個(gè) whomai 的 service,位于 default 命名空間,容器內(nèi)部端口為 80 ,http 協(xié)議
  serviceName: whoami
  namespace: default
  port: 80
  scheme: false

并執(zhí)行創(chuàng)建命令:

kubectl apply -f example.yaml

結(jié)合上文的定義介紹,復(fù)習(xí)一遍,在這里 proxyroutes 就是我們通過 CRD 創(chuàng)建的定制資源,其中包含著一組 ProxyRoute 對象。

現(xiàn)在可以使用 kubectl 來查看我們剛才創(chuàng)建的定制對象:

$ kubectl get proxyroute
NAME                 AGE
example-proxyroute   49s

$ kubectl get pr
NAME                 AGE
example-proxyroute   50s

實(shí)現(xiàn)控制器

創(chuàng)建項(xiàng)目目錄如下:

├─pkg
│  └─apis
│      └─miniproxy
│          └─v1alpha1
│              └─doc.go
│              └─register.go
│              └─types.go
│          └─register.go
├─script
│  └─boilerplate.go.txt
│  └─code-gen.sh
│  └─codegen.Dockerfile

doc.go 代碼:

// +k8s:deepcopy-gen=package
// +groupName=miniproxy.togettoyou.com

// Package v1alpha1 is the v1alpha1 version of the API.
package v1alpha1

register.go 代碼:

package v1alpha1

import (
 "mini-k8s-proxy/pkg/apis/miniproxy"

 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 "k8s.io/apimachinery/pkg/runtime"
 "k8s.io/apimachinery/pkg/runtime/schema"
)

// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: miniproxy.GroupName, Version: "v1alpha1"}

var (
 // SchemeBuilder initializes a scheme builder
 SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
 // AddToScheme is a global function that registers this API group & version to a scheme
 AddToScheme = SchemeBuilder.AddToScheme
)

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
 return SchemeGroupVersion.WithKind(kind).GroupKind()
}

// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
 return SchemeGroupVersion.WithResource(resource).GroupResource()
}

// Adds the list of known types to Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
 scheme.AddKnownTypes(SchemeGroupVersion,
  // 主要在這里導(dǎo)入我們的定制資源對象
  &ProxyRoute{},
  &ProxyRouteList{},
 )
 metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 return nil
}

types.go 代碼:

package v1alpha1

import (
 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ProxyRoute is a specification for a ProxyRoute resource
type ProxyRoute struct {
 metav1.TypeMeta   `json:",inline"`
 metav1.ObjectMeta `json:"metadata,omitempty"`

 Spec ProxyRouteSpec `json:"spec"`
}

// ProxyRouteSpec is the spec for a ProxyRoute resource
type ProxyRouteSpec struct {
 Host        string `json:"host"`
 ServiceName string `json:"serviceName"`
 Namespace   string `json:"namespace,omitempty"`
 Port        int32  `json:"port,omitempty"`
 Scheme      bool   `json:"scheme,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ProxyRouteList is a list of ProxyRoute resources
type ProxyRouteList struct {
 metav1.TypeMeta `json:",inline"`
 metav1.ListMeta `json:"metadata"`

 Items []ProxyRoute `json:"items"`
}

register.go 代碼:

package miniproxy

// GroupName is the group name used in this package
const (
 GroupName = "miniproxy.togettoyou.com"
)

代碼編寫完成后,就可以使用 k8s.io/code-generator 來生成控制器相關(guān)代碼了,腳本定義在 script 文件夾下,其中 boilerplate.go.txt 為生成的代碼頭部協(xié)議注釋,codegen.Dockerfile 內(nèi)容為:

FROM golang:1.16

ARG KUBE_VERSION

ENV GO111MODULE=on
ENV GOPROXY https://goproxy.cn,direct

RUN go get k8s.io/code-generator@$KUBE_VERSIONexit 0
RUN go get k8s.io/apimachinery@$KUBE_VERSIONexit 0

RUN mkdir -p $GOPATH/src/k8s.io/{code-generator,apimachinery}
RUN cp -R $GOPATH/pkg/mod/k8s.io/code-generator@$KUBE_VERSION $GOPATH/src/k8s.io/code-generator
RUN cp -R $GOPATH/pkg/mod/k8s.io/apimachinery@$KUBE_VERSION $GOPATH/src/k8s.io/apimachinery
RUN chmod +x $GOPATH/src/k8s.io/code-generator/generate-groups.sh

WORKDIR $GOPATH/src/k8s.io/code-generator

code-gen.sh 腳本內(nèi)容如下:

#!/bin/bash -e

set -e -o pipefail

PROJECT_MODULE="mini-k8s-proxy"
IMAGE_NAME="kubernetes-codegen:latest"

echo "Building codegen Docker image..."
docker build --build-arg KUBE_VERSION=v0.20.2 -f "./script/codegen.Dockerfile" \
            -t "${IMAGE_NAME}" \
            "."

cmd="/go/src/k8s.io/code-generator/generate-groups.sh all \
    ${PROJECT_MODULE}/pkg/generated \
    ${PROJECT_MODULE}/pkg/apis \
    miniproxy:v1alpha1 \
    --go-header-file=/go/src/${PROJECT_MODULE}/script/boilerplate.go.txt"


echo "Generating clientSet code ..."
docker run --rm \
           -v "$(pwd):/go/src/${PROJECT_MODULE}" \
           -w "/go/src/${PROJECT_MODULE}" \
           "${IMAGE_NAME}" $cmd

執(zhí)行腳本生成相關(guān)代碼:

$ ./script/code-gen.sh

......
Generating clientSet code ...
Generating deepcopy funcs
Generating clientset for miniproxy:v1alpha1 at mini-k8s-proxy/pkg/generated/clientset
Generating listers for miniproxy:v1alpha1 at mini-k8s-proxy/pkg/generated/listers
Generating informers for miniproxy:v1alpha1 at mini-k8s-proxy/pkg/generated/informers

實(shí)現(xiàn)業(yè)務(wù)邏輯

由于業(yè)務(wù)較簡單,我們直接在 main.go 完成業(yè)務(wù)邏輯,貼上代碼:

type ProxyRouteSpec struct {
 V map[string]v1alpha1.ProxyRouteSpec
 sync.RWMutex
}

var prs = &ProxyRouteSpec{
 V: make(map[string]v1alpha1.ProxyRouteSpec, 0),
}

type resourceEventHandler struct {
 Ev chan<- interface{}
}

func (reh *resourceEventHandler) OnAdd(obj interface{}) {
 eventHandlerFunc(reh.Ev, obj)
}

func (reh *resourceEventHandler) OnUpdate(oldObj, newObj interface{}) {
 eventHandlerFunc(reh.Ev, newObj)
}

func (reh *resourceEventHandler) OnDelete(obj interface{}) {
 eventHandlerFunc(reh.Ev, obj)
}

func eventHandlerFunc(events chan<- interface{}, obj interface{}) {
 select {
 case events <- obj:
 default:
 }
}

func main() {
 ctx := context.Background()

 eventCh := make(chan interface{}, 1)
 // 采用緩沖大小為 1 的通道方式來處理 CRD 事件
 eventHandler := &resourceEventHandler{Ev: eventCh}

 // 作為測試,可以直接使用 kubeconfig 連接 k8s,實(shí)際部署使用 InClusterConfig 模式
 //cfg, err := clientcmd.BuildConfigFromFlags("", "tmp/config")
 cfg, err := rest.InClusterConfig()
 if err != nil {
  panic(err)
 }
 client, err := clientset.NewForConfig(cfg)
 if err != nil {
  panic(err)
 }
 // 構(gòu)建 k8s Crd Informer 實(shí)例
 factoryCrd := externalversions.NewSharedInformerFactoryWithOptions(
  client,
  10*time.Minute,
 )
 // 注冊 Informer 事件處理
 factoryCrd.Miniproxy().V1alpha1().ProxyRoutes().Informer().AddEventHandler(eventHandler)
 // 啟動 Informer
 factoryCrd.Start(ctx.Done())
 // 等待首次緩存同步
 for t, ok := range factoryCrd.WaitForCacheSync(ctx.Done()) {
  if !ok {
   panic(fmt.Errorf("timed out waiting for controller caches to sync %s", t.String()))
  }
 }
 go startServer()

 for {
  select {
  case _, ok := <-eventCh:
   if !ok {
    continue
   }
   // 從 Lister 緩存獲取 CRD 資源對象
   proxyRoutes, err := factoryCrd.Miniproxy().V1alpha1().ProxyRoutes().Lister().List(labels.Everything())
   if err != nil {
    log.Println(err.Error())
    continue
   }
   // 清空本地緩存并重新放入
   prs.Lock()
   prs.V = make(map[string]v1alpha1.ProxyRouteSpec, 0)
   for _, proxyRoute := range proxyRoutes {
    fmt.Printf("%+v\n", proxyRoute)
    prs.V[proxyRoute.Spec.Host] = proxyRoute.Spec
   }
   prs.Unlock()
  }
 }
}

原理比較粗暴,通過 Informer — Lister 機(jī)制監(jiān)聽 CRD 資源的變化,并將資源對象存入本地 map 緩存中。

繼續(xù)添加代理轉(zhuǎn)發(fā)邏輯:

func startServer() {
 gin.SetMode(gin.ReleaseMode)
 r := gin.Default()
 r.Any("/*any", handler)
 log.Fatalln(r.Run(":80"))
}

func handler(c *gin.Context) {
 prs.RLock()
 defer prs.RUnlock()
 if proxyRouteSpec, ok := prs.V[c.Request.Host]; ok {
  u := ""
  if proxyRouteSpec.Scheme {
   u += "https://"
  } else {
   u += "http://"
  }
  if proxyRouteSpec.Namespace != "" {
   u += proxyRouteSpec.ServiceName + "." + proxyRouteSpec.Namespace
  } else {
   u += proxyRouteSpec.ServiceName
  }
  if proxyRouteSpec.Port != 0 {
   u += fmt.Sprintf(":%d", proxyRouteSpec.Port)
  }
  log.Println("代理地址: ", u)
  proxyUrl, err := url.Parse(u)
  if err != nil {
   c.AbortWithStatus(http.StatusInternalServerError)
  }
  proxyServer(c, proxyUrl)
 } else {
  c.String(http.StatusNotFound, "404")
 }
}

// 代理轉(zhuǎn)發(fā)
func proxyServer(c *gin.Context, proxyUrl *url.URL) {
 proxy := &httputil.ReverseProxy{
  Director: func(outReq *http.Request) {
   u := outReq.URL
   outReq.URL = proxyUrl
   if outReq.RequestURI != "" {
    parsedURL, err := url.ParseRequestURI(outReq.RequestURI)
    if err == nil {
     u = parsedURL
    }
   }

   outReq.URL.Path = u.Path
   outReq.URL.RawPath = u.RawPath
   outReq.URL.RawQuery = u.RawQuery
   outReq.RequestURI = "" // Outgoing request should not have RequestURI

   outReq.Proto = "HTTP/1.1"
   outReq.ProtoMajor = 1
   outReq.ProtoMinor = 1

   if _, ok := outReq.Header["User-Agent"]; !ok {
    outReq.Header.Set("User-Agent""")
   }

   // Even if the websocket RFC says that headers should be case-insensitive,
   // some servers need Sec-WebSocket-Key, Sec-WebSocket-Extensions, Sec-WebSocket-Accept,
   // Sec-WebSocket-Protocol and Sec-WebSocket-Version to be case-sensitive.
   // https://tools.ietf.org/html/rfc6455#page-20
   outReq.Header["Sec-WebSocket-Key"] = outReq.Header["Sec-Websocket-Key"]
   outReq.Header["Sec-WebSocket-Extensions"] = outReq.Header["Sec-Websocket-Extensions"]
   outReq.Header["Sec-WebSocket-Accept"] = outReq.Header["Sec-Websocket-Accept"]
   outReq.Header["Sec-WebSocket-Protocol"] = outReq.Header["Sec-Websocket-Protocol"]
   outReq.Header["Sec-WebSocket-Version"] = outReq.Header["Sec-Websocket-Version"]
   delete(outReq.Header, "Sec-Websocket-Key")
   delete(outReq.Header, "Sec-Websocket-Extensions")
   delete(outReq.Header, "Sec-Websocket-Accept")
   delete(outReq.Header, "Sec-Websocket-Protocol")
   delete(outReq.Header, "Sec-Websocket-Version")
  },
  Transport: &http.Transport{
   TLSClientConfig: &tls.Config{
    InsecureSkipVerify: true,
   },
  },
  ErrorHandler: func(w http.ResponseWriter, request *http.Request, err error) {
   statusCode := http.StatusInternalServerError
   w.WriteHeader(statusCode)
   w.Write([]byte(http.StatusText(statusCode)))
  },
 }
 proxy.ServeHTTP(c.Writer, c.Request)
}

每次請求連接會從本地緩存讀取配置,判斷是否匹配,若匹配則轉(zhuǎn)發(fā)代理到配置的服務(wù)中去。

部署

為了方便測試,我已經(jīng)編譯好鏡像上傳到 Docker Hub 上,所以大家可以直接使用下面的 yaml 部署:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: proxyroutes.miniproxy.togettoyou.com
spec:
  group: miniproxy.togettoyou.com
  names:
    kind: ProxyRoute
    shortNames:
      - pr
    plural: proxyroutes
    singular: proxyroute
  scope: Namespaced
  versions:
    - name: v1alpha1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                host:
                  type: string
                serviceName:
                  type: string
                namespace:
                  type: string
                port:
                  type: integer
                scheme:
                  type: boolean
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mini-k8s-proxy
spec:
  selector:
    matchLabels:
      app: mini-k8s-proxy
  replicas: 1
  template:
    metadata:
      labels:
        app: mini-k8s-proxy
    spec:
      containers:
        - name: mini-k8s-proxy
          image: togettoyou/mini-k8s-proxy:latest
          ports:
            - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: mini-k8s-proxy-service
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: mini-k8s-proxy
  type: NodePort

部署:

$ kubectl apply -f mini-k8s-proxy.yaml
customresourcedefinition.apiextensions.k8s.io/proxyroutes.miniproxy.togettoyou.com created
deployment.apps/mini-k8s-proxy created
service/mini-k8s-proxy-service created

$ kubectl get svc
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
mini-k8s-proxy-service   NodePort    10.111.139.14   <none>        80:32112/TCP   32s

訪問集群域名:32112 ,看到 404 的話,恭喜部署成功。

驗(yàn)證使用 ProxyRoute

現(xiàn)在我有一個(gè)名稱為 test-service 的 service 處于 testns 命名空間下,容器內(nèi)部端口為 80(是一個(gè) nginx 服務(wù))

$ kubectl get svc -n testns
NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
test-service   ClusterIP   10.97.89.250   <none>        80/TCP    2s

我想要當(dāng)請求 host 為 test.togettoyou.com:32112 的流量請求過來時(shí),可以代理轉(zhuǎn)發(fā)到 test-service 上,怎么做呢

按照心里預(yù)期,創(chuàng)建一個(gè) ProxyRoute 資源對象:

apiVersion: miniproxy.togettoyou.com/v1alpha1
kind: ProxyRoute
metadata:
  name: test-proxyroute
spec:
  host: test.togettoyou.com:32112
  serviceName: test-service
  namespace: testns
  port: 80
  scheme: false

瀏覽器訪問 test.togettoyou.com:32112 ,神奇的事情就會發(fā)生了

image.png

總結(jié)

本文通過 CRD + Controller 實(shí)現(xiàn)了一個(gè)簡易的 K8S 代理轉(zhuǎn)發(fā)工具,相關(guān)代碼均上傳到了 Github(https://github.com/togettoyou/mini-k8s-proxy)

實(shí)現(xiàn)思路來自 Traefik,強(qiáng)烈推薦

最后,感謝您的閱讀!


瀏覽 67
點(diǎn)贊
評論
收藏
分享

手機(jī)掃一掃分享

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

手機(jī)掃一掃分享

分享
舉報(bào)

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 四虎影院色| 日韩精品人妻中文字幕蜜乳| 久久女女| 在线观看黄A片免费网站| 黑人毛片91久久久久久| 中文字幕亚洲中文字幕| 亚洲成人性爱av| 国产一级在线| 国产精品美女毛片真酒店| 中文无码一区二区三区| 亚洲中文字幕视频在线| 大香蕉久久伊人| 不卡无码免费视频| 人人干人| 久久嫩草精品久久久久精| 丁香激情五月| 免费a在线观看| www中文字幕| 无码骚逼| 欧美久久视频| 天天天天天天天天操| 国产麻豆传媒| 玖玖婷婷| 夜夜bb| 精品少妇3p| 日本一级一片免费视频| 九九在线视频| 亚洲免费在线播放| 超碰在线看| 精品视频91| 99看片| 久久不射网站| 一级a免一级a做免费线看内裤| 热久久最新地址| 亚洲影音先锋资源| 无码啪啪| 国产一区二区做爱| 无码免费观看| 波多野结衣无码高清| 广东BBW搡BBBB搡| 国产精品无码专区| 黄色成人视频在线免费观看| 精品一区二区三区四区视频| 久久这里都是精品| 被黑人猛躁10次高潮视频| A片动漫| 天堂a在线| 国产毛片一区| 成人免费A片在线观看直播96| 国产又爽又黄视频| 99三级片| 男女一区二区三区| 熟女人妻人妻の视频| 一级黄A片| 欧美精品毛片| 狠狠躁日日躁夜夜躁A片视频| 欧美黄色站| 搡BBB搡BBBB搡BBBB| 一级AA片| 免费爱爱视频| 国产亚洲av| 日韩无码精品视频| 日本三级视频| 波多野结衣AV无码| 国产成人三级| 欧美在线不卡| 黄色成人视频在线观看| 高清无码在线免费观看| 色播五月天| 精品无码一区二区三区四区| www.狠狠操| 欧美日韩成人在线| 91啦丨露脸丨熟女| 九九99久久| 人操人| 亚洲av电影在线观看| 91你懂的| 青青草原亚洲| 成人在线乱码视频| 欧美精品A级片| 99久久免费网| 成人黄色大香蕉| 精品欧美片在线观看步骤| 日韩无码砖区| 天堂黄片| 四虎在线观看视频| 一本色道久久88综合无码| 欧美日韩中文在线视频| 人人人人摸| 91精品国产乱码久久久久| 91精品久久久久久综合五月天| 大香蕉综合闲人| 午夜福利av电影| 北条麻妃九九九在线视频| 激情五月天开心网| 欧美在线亚洲| 强伦轩一区二区三区在线观看| a片视频免费| 影音先锋在线视频观看| 日本成人A片| 上床视频网站| 成年人在线观看视频网站| www.婷婷六月天| 蜜桃视频一区二区三区四区使用方法| 69视频国产| 久大香蕉| 人人摸人人干人人操| 強姧伦一区二区三区在线播放| 亚洲无码视频免费看| 嫩BBB槡BBBB槡BBB| www久久久| 国产在线不卡年轻点的| 丁香五香天堂| 久久露脸国语精品国产91| 色综合九九| 国产精品国产三级国产AⅤ| 日韩国产免费| H片免费在线观看| 操逼操逼视频| 色婷婷日韩精品一区二区三区 | 麻豆av人人乐| 国产乱码精品一区二区三区的特点| AV1区二区| 日逼老女人| 亚洲天堂一区在线观看| 老熟女伦一区二区三区| 国产成人AV在线观看| 三级片网站在线播放| 99热在线观看精品免费| 人妻骚逼| 99热这里只有精品9| 三级片AAA成人免费| 51XX嘿嘿午夜| 精品国产AV鲁一鲁一区| 无码人妻一区二区三一区免费n狂飙 | 久久97人妻AⅤ无码一区| 亚洲男人的天堂av| 久热青草| 性无码一区二区| 在线看黄片| 91嫖妓站街按摩店老熟女| 波多野结衣一区二区三区| 国产日韩性爱视频| 尤物看片| 精品一区二区三区四区五区| 九九精品在线视频| 黄片免费播放| 超碰操逼| 欧美黄网站| 国产偷拍精品视频| 日韩欧美a片| 亚洲AV无码乱码国产精品黑人| 久草视频福利在线| 亚洲黄色视频在线| 欧美日韩中文字幕在线| 欧美一区二区三区视频| 少妇激情网站| 夜夜夜夜撸| 中文字幕第23页| 黄色片在线观看视频| 欧美亚洲日韩中文字幕| 狠狠操av| 欧美在线观看一区| 亚洲三级片免费观看| 99热精品免费| 我和岳m愉情XXXⅩ视频| 国产午夜成人| 在线天堂网| 欧美日韩群交| 久久综合伊人7777777| 蜜臀久久99精品| 91夜夜| 欧美日韩高清无码| 亚洲在线视频观看| 日韩激情无码视频精选| 色综合99久久久无码国产精品| 亚洲AV无码久久寂寞少妇多毛 | 男人的天堂视频| 国产视频久久| 最新av网| 无码导航| 天天插天天狠天天透| 最新国产av| 蜜桔视频嫩草蜜桃| 三级成人av| 熟女人妻在线| 国产看片网站| 亚洲日韩中文字幕在线观看| AV青草| 精品人妻在线| 色婷婷五月天在线观看| 人人妻人人爽人人精品| 欧美一级a| 草av| 天堂婷婷| www.91n| 欧美成人综合| 欧美成人一级a片| 国产精品一色哟哟哟| 午夜福利黄| 高清无码视频免费观看| 亚洲国产精品一区二区三区| 欧美AⅤ视频| 97人妻精品一区二区三区图片| 无码一区二区三区四| 另类av| 中日韩精品A片中文字幕| 怡春院视频| a视频免费观看| 免费黄片在线看| 蜜芽人妻在线| 亚洲精品无码在线播放| 91香蕉视频免费| 色老久久| 熟女啪啪| 中文字幕免费无码| 色五月av| 亚洲一区av| 亚洲色视频在线| 色悠悠久久综合| 丁香五月天网站| 91视频网站| 国产丝袜久久| 北条麻妃毛片| 亚洲欧美视频在线观看| 麻豆黄片| 吹潮喷水高潮HD| 中文字幕精品在线观看| 动图综合亚洲综合欧美男男| 亚洲福利在线免费观看| 免费日本黄色| 超碰在线观看97| 青草成人在线| 亚洲精品视频免费观看| 爱射综合| 天堂8在线19| 永久m3u8在线观看| 中文字幕无码高清| 青榴视频免费观看| 免费人成在线观看视频播放| 国产精品乱子伦视频一区二区| 中文字幕在线观看网站| 日韩bbbb| 国产一区二区免费| www.麻豆网91成人久久久| 久久成人一区| 伊人精品A片一区二区三区| 日本无码一区二区三区| 一级成人视频| 欧美在线免费视频| 日韩欧美在线视频观看| 国产AV美女| 草草影院国产第一页| 大香蕉人人| 无码精品人妻一区二区欧美| 欧美黄页| 亚洲精品秘一区二区三线观看| 99资源站| 亚洲激情五月| 欧美成人黄色电影| 欧美一区在线视频| 青娱乐自拍偷拍| 国产一级a片| 亚洲一区二区免费视频| 亚洲在线视频免费观看| 日本成人午夜福利| 亚洲视频福利| 国产一级a毛一级做a爱| 国产三级高清无码| 翔田千里在线播放| 9I成人免费版| 日本少妇BBw| 日韩黄色视频网站| AV天堂影视在线观看| 四房五月婷婷| 日韩视频无码| 久热这里| 天天日夜夜草| 黄色操逼视频| 国产乱╳╳AⅤ毛片| www.91n| 久久无码免费| 国产精品91在线| 91日韩| 91免费观看网站| 操日本逼| www,操逼| 亚洲欧美第一页| a片免费在线观看| 欧美一级黃色A片免费看蜜桃熟了| 91人人妻人人澡人人爽人人| 996热久久| 国产午夜精品一区二区| 香蕉成人网| 中文字幕国产在线观看| av天堂亚洲| 国产精品51麻豆cm传媒| sm在线| 欧美日韩中文字幕| 久久人人操人人| jizzjizzjizzjizz| 噼里啪啦免费观看视频大全| 日韩免费观看视频| 手机在线成人视频| 一级片免费网站| 澳门黄片| 日韩毛片在线看| 俺去日| 天天日天天操天天爽| www.俺来也| 色五月视频在线| 黄片免费播放| 日韩无码砖区| 久久久久久久免费| 日皮做爱视频网站| 大伊香蕉在线| 欧美日韩一区二区三区| 爱爱免费不卡视频| 欧美一级黄色电影| 一级黄色片免费观看| 狠狠干影院| 乱人伦欲国语对白| 久久一二三区| 抠逼网站| 日本翔田千里奶水| 五月激情黄色| 激情亚洲婷婷| 麻豆91久久久| 亚洲区欧美区| 欧美A视频在线观看| 色婷婷国产精品| 日韩女人性爱| 在线观看黄A片免费网站| 免费黄色在线观看| 91人人人人| 日韩国产欧美| 免费成人高清视频| 国产精品久久777777是什么意思| 欧美熟妇搡BBBB搡BBBBB| 69超碰| www.AV在线| 大香蕉人妻| 日本亲子乱婬一级A片| 国产性爱在线| 国产一级片免费| 成人自拍偷拍视频| 免费看的操逼视频| 国产精品一区在线观看| 婷婷五月天色播| 国产一级内射| 日韩图色| 91视频在线观看18| 亚洲天堂男人的天堂| 少妇被躁到高潮无码| 国产AV无码高清| 色欧美大香蕉| 国产第一页在线播放| 欧美一级夜夜爽| 四虎成人网址| 在线看黄网| 欧美日本国产| 日韩蜜桃视频| www.插插插| 免费日B视频| 高潮喷水在线观看| 国产成人精品一区二区三区视频 | 中国女人操逼视频| 九一成人电影| 亚洲五月婷婷| 一二区免费视频| 狠狠狠久久久| 精品成人无码| 久久艹骚逼| 一级片无码| 欧美日韩高清丝袜| 国产成人精品一区二区| 国内精品内射| 成人片天天看片欧美一级| 亚洲人成色777777无码| 亚洲国产A片| 丁香五月影院| 国产精品人妻无码一区牛牛影视| 日韩一级特黄A片免费观| 另类欧美| 日韩精品在线播放| 国内精品一区二区三区| 国产另类自拍| 亚洲青青草| 亚洲成人高清在线| 露脸丨91丨九色露脸| 十八女人高潮A片免费| 思思久久高颜值| 国产不卡视频| 人妻人人妻| AA片免费网站| 亚洲热视频在线观看| 嫩草在线观看| 97香蕉网| 欧美精品欧美精品系列| 黄片视频网站| 日韩日韩日韩| 无码一区精品久久久成人| 国产精品视频网站| 无码人妻免费视频| 日韩无码一级片| 亚洲黄色免费观看| 撸撸操在线视频观看只有精品| 真实野外打野视频| 影音先锋AV天堂| 天天做天天爱| 亚洲精品久久久久久久久蜜桃| 18SAV| 狠狠穞A片一區二區三區| 在线观看操逼| 网址你懂的| 欧美偷拍精品| 日少妇视频| 加勒比无码在线| 天天天天天天天天操| 日韩成人片无码| 三级a片| 国产亚洲精品成人a| 亚州AV操屄| 91蝌蚪视频在线观看| 日韩综合区| 97国产视频| 91探花秘在线播放偷拍| 成人精品二区| 国内精品无码| 青娱乐Av| 天天干在线观看视频| 欧美在线一区二区三区| 亚洲AV秘成人久久无码海归| 欧美精品18videosex性欧美| 日本黄色中文字幕| 新中文字幕| 精品欧美片在线观看步骤| 午夜高清无码视频| 四川少妇搡bbw搡bbbb| 久久嫩草精品久久久久精| 欧美日本国产| 国产高清a| 日本精品久久| 99热在线看| 日韩在线一区二区三区四区| 亚洲色视频在线观看| 婷婷色小说| 亚洲乱伦小说网| 日本亚洲欧洲免费| 五月综合色| 人人射人人爱| 亚洲中文无码在线观看| 国产在线观看免费视频| 日韩欧美精品18| 色欲一区二区三区| 97爱爱| 国产主播在线播放| 亚洲高清视频在线播放| 国产精品免费av在线| 日韩熟妇无码中文字幕| 黄色小说视频| JlZZJLZZJlZZ亚洲女人17| 偷拍综合网| 亚洲激情在线观看| 四川BBB操BBB| 中文字幕免费在线观看| 夜夜夜操| 人妻少妇精品无码| 5252a我爱haose01我愿| 久久国产免费| 在线观看日韩AV| 波多野结衣AV在线观看| 国产激情免费| 国产成人av在线播放| 成人性爱在线播放| 日韩一区二区在线看在线看| 99性爱视频| 91人人妻人人澡人人爽人人 | 日韩日批视频| 精品国产乱子伦一区二区三区,小小扐 | 亚洲欧美另类图片| 亚洲AⅤ| 亚洲色一区二区| 国产精品色情| 亚洲三级片免费观看| 国产av大全| 青青草激情| 国产手机拍视频推荐2023| 怡红院麻豆| 免费爱爱视频| 国产成人A| 国产精品视频99| 国产91嫩草乱婬A片2蜜臀| 另类老妇性BBwBBw| 五十路av| 先锋资源在线视频| 中文字幕无码播放| 婷婷国产成人精品| 国产成人在线免费观看| 国产中文视频| 2025中文字幕在线| 小黄片在线免费观看| 日本无码在线| 久久国产精品久久| 国产一区二区免费| 亚洲视频在线观看网站| 两根茎一起进去好爽A片在线观看| 欧美成人久久| 91人人视频| 中文字幕无码在线观看视频| 国产精品精品| 亚洲成人精品| 4438成人网| 91中文视频| 欧美内射在线| 91麻豆一区二区| 乱伦无码| AV天堂亚洲| 婷婷五月一区| 亚洲乱码一区二区三区| 国产又粗又猛又黄又爽无遮挡| 亚洲133| 国产精品福利视频| 小泬BBBBBB免费看| 国产一在线| 日韩蜜桃视频| 亚洲av性爱| 国产福利视频在线| 色片视频| 中文字幕无码人妻在线视频| 性欧美欧美巨大69| 操逼操逼操逼操逼操逼操逼| 日韩中文性受视频| 国产av影视| 久草香蕉视频| 大地资源38页| 精品色哟哟| 成人黄色在线观看视频| 朝鲜性感AV在线| 久久yzy| 欧美操逼视频网站| 自拍偷拍综合网| 五月六月婷婷| 西西人体444www| 大香焦草久| 亚洲国产三级| 日韩欧美色图| 午夜福利在线视频| 国产卡一卡二| 色色三区| 久操久操久操| 欧美久久国产精品| 日韩无码免费视频| 99久久精品国产一区色| 国产一级A片久久久免费看快餐 | 神马久久午夜| 欧美插逼视频| 上床视频网站| 日韩中文字幕视频在线观看| 日韩在线视频二区| 天天谢天天干| 欧美中文字幕| 久操精品| 日本精品国产| 天天干人妻| 免费在线黄色视频| 亚洲A片电影| 五月婷婷五月丁香| 色情片在线播放| 一起操逼| 国产在线不卡年轻点的| 高清无码视频网站| 激情五月丁香婷婷| 你懂的在线观看视频| 人人干人人干人人干| 亚洲视频www| 翔田千里无码免费播放| 国产精品精品| 人人爽亚洲AV人人爽AV人人片| 91超碰在线| 欧美色图在线视频| 在线无码人妻| 成人毛片| 三级黄色毛片| 三级午夜在线无码| 91精品国产一区二区| 波多野结衣视频免费在线观看| 久久视频这里有精品| 在线视频三区| 国产老熟女高潮毛片A片仙踪林| 久操视频在线| 在线视频中文字幕| 首页-91n| 成人黄片18| www中文字幕| 蜜桃AV在线播放| 91久久爱| 蜜桃91精品入口| 久久久高清无码| 天天精品视频| 黄片网站免费在线观看| 国产成人久久777777| 成人五月天黄色电影| 三级网址大全| 最新中文字幕观看| 怡红影院美乳| 无码天堂| 久草视频免费在线观看| 操逼网页| 爱草视频| 最新国产AV| 精品无码免费| 黄色A片在线观看| 欧美女人操逼| 爱搞搞网| 天天拍天天操| 91久久精品一区二区三| 五月丁香六月婷婷综合| 国产第一精品| 日韩欧美中文字幕在线视频| 亚洲AV无码专区在线播放中文 | 亚洲成人免费在线| 新中文字幕| 欧美日韩久久久| 天天日少妇| 黄片网站在线免费观看| 俺去也俺去啦| 99热精品2| 亚洲国产精品尤物yw在线观看 | 日韩高清无码三级片| 免费在线观看无码视频| 亚洲无码免费播放| 青久久久| 午夜天堂精品久久久久9| 亚洲日韩欧美一厂二区入| 国产毛片精品一区二区色欲黄A片| eeuss在线| 亚洲午夜无码久久久| 久草视频在线免费看| 夜操操| 色综合色综合色综合| 国产黄片在线视频| 在线观看日本黄| 中文字幕国产在线观看| 色资源在线观看| 国产www视频| 综合合一品道| 99久久精品国产成人一区二区| 国产又爽又黄免费观看| 日韩一级片在线| 成人影视在线免费观看| 亚洲偷拍视频| 黄片高清无码在线观看| 91无码人妻精品1国产四虎| 51精品日本| 成人做爰黄A片免费| 91精品成人电影| 婷婷激情视频| 成人无码免费一区二区中文| 十八禁视频在线观看网站.www| 欧美日P| 香蕉AV777XXX色综合一区| 91免费成人电影| 成人伊人综合| 国产精品无码7777777| 人妻人人澡| 无码AV大香线蕉伊人| 无码视频观看| 欧美操逼图片| 天堂资源网| 日韩人妻丰满无码区A片| 91探花足浴店按摩店| 超级碰碰碰碰碰碰碰碰碰| 91激情电影| 亚洲无码在线观看免费| 国际精品久久久| 色五月视频在线| 欧美三级欧美一级| 四虎成人精品永久免费AV九九 | 中文字幕高清AⅤ| 韩国中文字幕HD久久精品| 在线成人小视频| WW免费视频| 中文色片| 欧美大黄视频| 亚洲精品乱码久久久久久久| 97人妻人人澡人人爽人人| 一区二区三区免费播放| 青青视频网| 超碰一级片| 中文在线观看视频| 无码免费婬AV片在线观看| 东京热综合网| 久久三级片| 无码在线视频免费观看| 欧美男人天堂网| 性爱AV网| 一级黄色电影免费在线观看| 九色PORNY国产成人| 亚洲中文字幕2019| 午夜福利影视| 影音先锋日韩精品| 亚洲欧美日韩国产| 亚洲日韩视频在线观看| 国产又爽又黄A片免费观看| 综合站欧美精品| 中字av| 在线视频观看一区| 暖暖av| 日本中文视频| 一区二区三区四区视频在线| 久久大| 大香蕉日韩| 免费av在线| 亚州一级成人片| 亚洲一道本在线| 9I成人免费版视频| 日韩毛片在线看| 亚洲精品人人| 日韩精品成人无码免费| 国产成人精品无码免费| 国产乱妇乱子伦视频免费观看| 亚洲福利女神成人福利| 久久久久久一| 成年视频在线观看| 天天日天天色天天干| 男人资源网| 99在线精品视频免费观看20| 午夜精品18| 97无码| 污导航在线| 国产日日日| 91豆花成人社区| 亚洲久久在线| 在线免费观看一区| 特级黄色毛片| 欧美激情色色| 中文字幕亚洲中文字幕| 日本亚洲国产| 成人无码免费看| 国产一级片视频| 青青草无码成人天堂免费| 伊人成人在线| www99| 黄色片视频日韩| 久久免费视频6| 91在线无码精品秘入口三人| 成人精品久久久| 久热久热| 久久99无码| 无码在线专区| 欧美人人爱| 日本三级中文字幕| 成人香蕉网| 国产精品视频一区二区三| 影音先锋女人资源| 91精品国产一区三一| 日韩视频中文| 内射极品美女| 亚洲无码视频免费观看| 国产综合色婷婷精品久久| 国产三级图片| h片在线免费观看视频| 爱爱视频欧美| xxx综合网| 欧美激情内射| 免费爱爱视频网站| 国产动态图| 国产色哟哟| 丁香激情五月| 蜜桃网一区二区| 国产精品资源在线观看| 成人免费激情视频| 欧一美一婬一伦一区二区三区黑人 | 91久久国产综合久久91| 俺去了无码| 色色网的五月天| 狠狠操天天干| 91久久国产综合| 一区二区三区四区视频| 日本操屄视频| 大帝av| 99在线精品视频免费观看20 | 天天噜天天操| 操操操综合| 国产一区二区三区四区五区在线| 无码精品一区二区| 色视频在线观看| 91人人妻人人做人人爽| 特级西西444www无码视频免费看| 亚洲涩情91日韩一区二区| 在线观看91| 天堂亚洲精品| 动漫无码视频| 成人小说一区二区三区| 天天摸天天操| 久久舔| 成人做爰100片免费视频| 亚洲中文久久| 超碰97人人操| 国产精品久久久久久久免牛肉蒲 | 亚洲免费视频播放| 欧美日韩视频在线| 色情片在线播放| 精品人妻一区二区三区阅读全文| 91人人妻人人澡| 一级片免费在线观看| 夜夜嗨AV一区二区三区啊| 日韩毛片在线看| 欧美视频第一页| 色婷婷在线播放| 午夜福利AV电影| 国产做爱视频| 逼网站| 女人自慰网站在线观看| yjizz视频网| 午夜精品视频在线观看| 日本无码中文字幕| 德国肥妇熟妇BBwBBw| 一级片黄片| 翔田AV无码秘三区| 亚洲午夜福利视频| 四虎无码视频| 成人精品视频在线| 国产精品成人无码免费| 国产美女18毛片水真多| 影音先锋国产av| 午夜爱爱免费视频| 男男做受A片AAAA| 国产啊啊啊| 伊人色色色| 高清无码网址| 99在线视频免费观看| 久久无码免费| 国产精品日韩高清北条麻衣| 精品乱子伦一区二区三区免费播放 | 麻豆成人无码| 无码人妻一区二区三区在线视频不卡| 蜜桃av秘无码一区三区四| 韩国无码专区| 日木毛片| 国产免费一区二区三区| 日本家庭乱伦视频| 日韩无码中文字幕视频| 日韩欧美在线免费观看| 親子亂子倫XXXX| 日韩精品视频免费在线观看| 蝌蚪窝视频在线| 亚洲欧洲久久电影| 秋霞丝鲁片一区二区三区手机在绒免| 操碰视频在线| 午夜精品一区二区三区在线视频| 四虎无码视频| 北条麻妃av在线播放| 精品三区| 91AV一区二区三区| 亚洲va在线| 国产日韩一区二区| 豆花成人视频| 在线看V片| 亚洲.无码.制服.日韩.中文字幕 | 99热播在线| 亚洲V国产v欧美v久久久久久| 蜜臀AV在线| 午夜在线观看视频18| 男人av网站| 日韩无码精品一区| 69精品无码成人久久久久久| 精品视频一区二区三区四区| 先锋成人电影| 2018人人操| 黄色免费网站| 91免费观看网站| 97播播| AV色站| 人人操碰成人网| 91无码人妻精品1国产四虎| 午夜福利成人视频| 18成人毛片| 国产三级麻豆| 成人黄色电影在线观看| 小小拗女BBw搡BBBB搡| 亚洲第一色图| 一级片在线播放| 99精品视频免费在线观看| 欧美成人版| 日韩插插| 自拍偷拍影音先锋| 东京热综合网| 欧美一级高清片免费一级a| 国产三级国产三级国产| 巨い巨乳の少妇あジed2k| 中文字幕在线成人| 欧美sese| 黄色视频在线| 波多野结衣日韩| 91白浆| 91爱搞在线| 亚洲AV无码电影| 91精品国产人妻|