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

API Server源碼分析之入口點(diǎn)解析

云計(jì)算 云原生
從本文開始,我們將對 K8s API Server 的代碼進(jìn)行詳細(xì)分析,并探討其應(yīng)用入口點(diǎn)、框架以及與 etcd 的通信。


Kubernetes(K8s)集群中最關(guān)鍵的組件之一是 API Server,它是所有集群管理活動的入口點(diǎn)。從本文開始,我們將對 K8s API Server 的代碼進(jìn)行詳細(xì)分析,并探討其應(yīng)用入口點(diǎn)、框架以及與 etcd 的通信。

應(yīng)用入口點(diǎn)

K8s API Server 的主要入口點(diǎn)位于 cmd/kube-apiserver/apiserver.go 文件的。

// cmd/kube-apiserver/apiserver.go 

// apiserver is the main api server and master for the cluster.
// it is responsible for serving the cluster management API.
package main

import (
"os"

"k8s.io/component-base/cli"
_ "k8s.io/component-base/logs/json/register" // 用于JSON日志格式注冊
_ "k8s.io/component-base/metrics/prometheus/clientgo" // 加載所有的 prometheus client-go 插件
_ "k8s.io/component-base/metrics/prometheus/version" // 用于版本指標(biāo)注冊
"k8s.io/kubernetes/cmd/kube-apiserver/app"
)

func main() {
command := app.NewAPIServerCommand()
code := cli.Run(command)
os.Exit(code)
}

其中的 app.NewAPIServerCommand() 是構(gòu)建的一個(gè) cobra 的命令對象,cli.Run 然后執(zhí)行該命令即可,所以我們直接查看 NewAPIServerCommand 函數(shù)是如果構(gòu)造 cobra.Command 對象的:

// cmd/kube-apiserver/app/server.go

// NewAPIServerCommand 使用默認(rèn)參數(shù)創(chuàng)建一個(gè) *cobra.Command 對象
func NewAPIServerCommand() *cobra.Command {
// NewServerRunOptions 使用默認(rèn)參數(shù)創(chuàng)建一個(gè)新的 ServerRunOptions 對象。
// ServerRunOption 對象是運(yùn)行 apiserver 需要的對象
s := options.NewServerRunOptions()
cmd := &cobra.Command{
Use: "kube-apiserver",
Long: `The Kubernetes API server validates and configures data
for the api objects which include pods, services, replicationcontrollers, and
others. The API Server services REST operations and provides the frontend to the
cluster's shared state through which all other components interact.`,

// ......
RunE: func(cmd *cobra.Command, args []string) error {
verflag.PrintAndExitIfRequested()
fs := cmd.Flags()

if err := s.Logs.ValidateAndApply(); err != nil {
return err
}
cliflag.PrintFlags(fs)

err := checkNonZeroInsecurePort(fs)
if err != nil {
return err
}
// 設(shè)置默認(rèn)選項(xiàng)
completedOptions, err := Complete(s)
if err != nil {
return err
}
// 校驗(yàn)選項(xiàng)
if errs := completedOptions.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs)
}
return Run(completedOptions, genericapiserver.SetupSignalHandler())
},
}

// ......

return cmd
}

該函數(shù)最核心的功能就是使用 Complete(s) 函數(shù)來生成 apiserver 啟動需要的默認(rèn)參數(shù),然后將默認(rèn)參數(shù)傳遞給 Run 函數(shù)進(jìn)行啟動。

// cmd/kube-apiserver/app/server.go
// Run 運(yùn)行指定的 APIServer,不能退出.
func Run(completeOptions completedServerRunOptions, stopCh <-chan struct{}) error {

// 創(chuàng)建服務(wù)鏈(包含的3個(gè)server組件)
server, err := CreateServerChain(completeOptions, stopCh)


// 服務(wù)啟動前的準(zhǔn)備工作,包括健康檢查、存活檢查、OpenAPI路由注冊等
prepared, err := server.PrepareRun()

// 正式啟動運(yùn)行
return prepared.Run(stopCh)
}

在 Run 函數(shù)中首先會通過 CreateServerChain 函數(shù)通過委托創(chuàng)建連接的 APIServer 對象。

// cmd/kube-apiserver/app/server.go

// CreateServerChain 通過委托創(chuàng)建連接的APIServer
func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan struct{}) (*aggregatorapiserver.APIAggregator, error) {
// CreateKubeAPIServerConfig 創(chuàng)建用于運(yùn)行 APIServer 的所有配置資源,但不運(yùn)行任何資源
kubeAPIServerConfig, serviceResolver, pluginInitializer, err := CreateKubeAPIServerConfig(completedOptions)

// // 創(chuàng)建 APIExtensionsServer 配置
apiExtensionsConfig, err := createAPIExtensionsConfig(*kubeAPIServerConfig.GenericConfig, kubeAPIServerConfig.ExtraConfig.VersionedInformers, pluginInitializer, completedOptions.ServerRunOptions, completedOptions.MasterCount,
serviceResolver, webhook.NewDefaultAuthenticationInfoResolverWrapper(kubeAPIServerConfig.ExtraConfig.ProxyTransport, kubeAPIServerConfig.GenericConfig.EgressSelector, kubeAPIServerConfig.GenericConfig.LoopbackClientConfig, kubeAPIServerConfig.GenericConfig.TracerProvider))

// 創(chuàng)建APIExtensionsServer并注冊路由
apiExtensionsServer, err := createAPIExtensionsServer(apiExtensionsConfig, genericapiserver.NewEmptyDelegateWithCustomHandler(notFoundHandler))

// 創(chuàng)建KubeAPIServer并注冊路由
kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer)

// // 創(chuàng)建 aggregatorServer 配置
aggregatorConfig, err := createAggregatorConfig(*kubeAPIServerConfig.GenericConfig, completedOptions.ServerRunOptions, kubeAPIServerConfig.ExtraConfig.VersionedInformers, serviceResolver, kubeAPIServerConfig.ExtraConfig.ProxyTransport, pluginInitializer)

// 創(chuàng)建aggregatorServer并注冊路由
aggregatorServer, err := createAggregatorServer(aggregatorConfig, kubeAPIServer.GenericAPIServer, apiExtensionsServer.Informers)

return aggregatorServer, nil
}

上面的函數(shù)中可以看到 CreateServerChain 會創(chuàng)建3個(gè) server:APIExtensionServer、KubeAPIServer、AggregratorServer,APIServer 就是依靠這3個(gè)組件來對不同類型的請求進(jìn)行處理的:

  • APIExtensionServer: 主要負(fù)責(zé)處理 CustomResourceDefinition(CRD)方面的請求。
  • KubeAPIServer: 主要負(fù)責(zé)處理 K8s 內(nèi)置資源的請求,此外還會包括通用處理、認(rèn)證、鑒權(quán)等。
  • AggregratorServer: 主要負(fù)責(zé)聚合器方面的處理,它充當(dāng)一個(gè)代理服務(wù)器,將請求轉(zhuǎn)發(fā)到聚合進(jìn)來的 K8s service 中。

圖片

創(chuàng)建每個(gè) server 都有對應(yīng)的 config,可以看出上面函數(shù)中的 apiExtensionServer 和 aggregatorServer 的 Config 需要依賴 kubeAPIServerConfig,而這幾個(gè) ServerConfig 都需要依賴 GenericConfig,CreateKubeAPIServerConfig 函數(shù)創(chuàng)建 kubeAPIServerConfig ,在該函數(shù)中通過調(diào)用 buildGenericConfig 來創(chuàng)建 GenericConfig 對象,如下代碼所示。

// cmd/kube-apiserver/app/server.go
// CreateKubeAPIServerConfig 創(chuàng)建用于運(yùn)行 APIServer 的所有配置資源
func CreateKubeAPIServerConfig(s completedServerRunOptions) (
*controlplane.Config,
aggregatorapiserver.ServiceResolver,
[]admission.PluginInitializer,
error,
) {
proxyTransport := CreateProxyTransport()
// 構(gòu)建通用配置
genericConfig, versionedInformers, serviceResolver, pluginInitializers, admissionPostStartHook, storageFactory, err := buildGenericConfig(s.ServerRunOptions, proxyTransport)

// ......

config := &controlplane.Config{
GenericConfig: genericConfig,
ExtraConfig: controlplane.ExtraConfig{
APIResourceConfigSource: storageFactory.APIResourceConfigSource,
StorageFactory: storageFactory,
EventTTL: s.EventTTL,
KubeletClientConfig: s.KubeletConfig,
EnableLogsSupport: s.EnableLogsHandler,
ProxyTransport: proxyTransport,

ServiceIPRange: s.PrimaryServiceClusterIPRange,
APIServerServiceIP: s.APIServerServiceIP,
SecondaryServiceIPRange: s.SecondaryServiceClusterIPRange,

APIServerServicePort: 443,

ServiceNodePortRange: s.ServiceNodePortRange,
KubernetesServiceNodePort: s.KubernetesServiceNodePort,

EndpointReconcilerType: reconcilers.Type(s.EndpointReconcilerType),
MasterCount: s.MasterCount,

ServiceAccountIssuer: s.ServiceAccountIssuer,
ServiceAccountMaxExpiration: s.ServiceAccountTokenMaxExpiration,
ExtendExpiration: s.Authentication.ServiceAccounts.ExtendExpiration,

VersionedInformers: versionedInformers,

IdentityLeaseDurationSeconds: s.IdentityLeaseDurationSeconds,
IdentityLeaseRenewIntervalSeconds: s.IdentityLeaseRenewIntervalSeconds,
},
}

// ......

return config, serviceResolver, pluginInitializers, nil
}

func buildGenericConfig(
s *options.ServerRunOptions,
proxyTransport *http.Transport,
)(...){
//創(chuàng)建一個(gè)通用配置對象
genericConfig = genericapiserver.NewConfig(legacyscheme.Codecs)

// ......

//創(chuàng)建認(rèn)證實(shí)例
if lastErr = s.Authentication.ApplyTo(&genericConfig.Authentication, genericConfig.SecureServing, genericConfig.EgressSelector, genericConfig.OpenAPIConfig, clientgoExternalClient, versionedInformers); lastErr != nil {
return
}

// ...
// openapi/swagger配置,OpenAPIConfig 用于生成 OpenAPI 規(guī)范
getOpenAPIDefinitions := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(getOpenAPIDefinitions, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme))
genericConfig.OpenAPIConfig.Info.Title = "Kubernetes"
genericConfig.LongRunningFunc = filters.BasicLongRunningRequestCheck(
sets.NewString("watch", "proxy"),
sets.NewString("attach", "exec", "proxy", "log", "portforward"),
)

// storageFactoryConfig 對象定義了 kube-apiserver 與 etcd 的交互方式,如:etcd認(rèn)證、地址、存儲前綴等
// 該對象也定義了資源存儲方式,如:資源信息、資源編碼信息、資源狀態(tài)等
storageFactoryConfig := kubeapiserver.NewStorageFactoryConfig()
storageFactoryConfig.APIResourceConfig = genericConfig.MergedResourceConfig
completedStorageFactoryConfig, err := storageFactoryConfig.Complete(s.Etcd)

storageFactory, lastErr = completedStorageFactoryConfig.New()

if lastErr = s.Etcd.ApplyWithStorageFactoryTo(storageFactory, genericConfig); lastErr != nil {
return
}

// ......

// 初始化 SharedInformerFactory
kubeClientConfig := genericConfig.LoopbackClientConfig
clientgoExternalClient, err := clientgoclientset.NewForConfig(kubeClientConfig)
versionedInformers = clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute)

// 認(rèn)證配置,內(nèi)部調(diào)用 authenticatorConfig.New()
// K8s提供了9種認(rèn)證機(jī)制,每種認(rèn)證機(jī)制被實(shí)例化后都成為認(rèn)證器
if lastErr = s.Authentication.ApplyTo(&genericConfig.Authentication, genericConfig.SecureServing, genericConfig.EgressSelector, genericConfig.OpenAPIConfig, clientgoExternalClient, versionedInformers); lastErr != nil {
return
}

// 創(chuàng)建鑒權(quán)實(shí)例,K8s也提供了6種授權(quán)機(jī)制,每種授權(quán)機(jī)制被實(shí)例化后都成為授權(quán)器
genericConfig.Authorization.Authorizer, genericConfig.RuleResolver, err = BuildAuthorizer(s, genericConfig.EgressSelector, versionedInformers)

// ...
// 審計(jì)
lastErr = s.Audit.ApplyTo(genericConfig)

// 準(zhǔn)入控制器
// k8s資源在認(rèn)證和授權(quán)通過,被持久化到etcd之前進(jìn)入準(zhǔn)入控制邏輯
// 準(zhǔn)入控制包括:對請求的資源進(jìn)行自定義操作(校驗(yàn)、修改、拒絕)
// 準(zhǔn)入控制器通過 Plugins 數(shù)據(jù)結(jié)構(gòu)統(tǒng)一注冊、存放、管理
admissionConfig := &kubeapiserveradmission.Config{
ExternalInformers: versionedInformers,
LoopbackClientConfig: genericConfig.LoopbackClientConfig,
CloudConfigFile: s.CloudProvider.CloudConfigFile,
}
serviceResolver = buildServiceResolver(s.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, versionedInformers)
pluginInitializers, admissionPostStartHook, err = admissionConfig.New(proxyTransport, genericConfig.EgressSelector, serviceResolver, genericConfig.TracerProvider)

err = s.Admission.ApplyTo(
genericConfig,
versionedInformers,
kubeClientConfig,
feature.DefaultFeatureGate,
pluginInitializers...)

// ...

}

然后我們再來分別看看這3個(gè) Server 是如何構(gòu)建的。

go-restful框架

這里我們就不得不先了解下 go-restful 這個(gè)框架了,因?yàn)?APIServer 就使用的這個(gè)框架。下面的代碼是 go-restful 官方的一個(gè)示例,這個(gè) demo 了解后基本上就知道 go-restful 框架是如何使用的了:

package main

import (
"log"
"net/http"

restfulspec "github.com/emicklei/go-restful-openapi/v2"
restful "github.com/emicklei/go-restful/v3"
"github.com/go-openapi/spec"
)

// UserResource is the REST layer to the User domain
type UserResource struct {
// normally one would use DAO (data access object)
users map[string]User
}

// WebService creates a new service that can handle REST requests for User resources.
func (u UserResource) WebService() *restful.WebService {
ws := new(restful.WebService)
ws.
Path("/users").
Consumes(restful.MIME_XML, restful.MIME_JSON).
Produces(restful.MIME_JSON, restful.MIME_XML) // you can specify this per route as well

tags := []string{"users"}

ws.Route(ws.GET("/").To(u.findAllUsers).
// docs
Doc("get all users").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes([]User{}).
Returns(200, "OK", []User{}))

ws.Route(ws.GET("/{user-id}").To(u.findUser).
// docs
Doc("get a user").
Param(ws.PathParameter("user-id", "identifier of the user").DataType("integer").DefaultValue("1")).
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(User{}). // on the response
Returns(200, "OK", User{}).
Returns(404, "Not Found", nil))

ws.Route(ws.PUT("/{user-id}").To(u.updateUser).
// docs
Doc("update a user").
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
Metadata(restfulspec.KeyOpenAPITags, tags).
Reads(User{})) // from the request

ws.Route(ws.PUT("").To(u.createUser).
// docs
Doc("create a user").
Metadata(restfulspec.KeyOpenAPITags, tags).
Reads(User{})) // from the request

ws.Route(ws.DELETE("/{user-id}").To(u.removeUser).
// docs
Doc("delete a user").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")))

return ws
}

// GET http://localhost:8080/users
//
func (u UserResource) findAllUsers(request *restful.Request, response *restful.Response) {
list := []User{}
for _, each := range u.users {
list = append(list, each)
}
response.WriteEntity(list)
}

// GET http://localhost:8080/users/1
//
func (u UserResource) findUser(request *restful.Request, response *restful.Response) {
id := request.PathParameter("user-id")
usr := u.users[id]
if len(usr.ID) == 0 {
response.WriteErrorString(http.StatusNotFound, "User could not be found.")
} else {
response.WriteEntity(usr)
}
}

// PUT http://localhost:8080/users/1
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
//
func (u *UserResource) updateUser(request *restful.Request, response *restful.Response) {
usr := new(User)
err := request.ReadEntity(&usr)
if err == nil {
u.users[usr.ID] = *usr
response.WriteEntity(usr)
} else {
response.WriteError(http.StatusInternalServerError, err)
}
}

// PUT http://localhost:8080/users/1
// <User><Id>1</Id><Name>Melissa</Name></User>
//
func (u *UserResource) createUser(request *restful.Request, response *restful.Response) {
usr := User{ID: request.PathParameter("user-id")}
err := request.ReadEntity(&usr)
if err == nil {
u.users[usr.ID] = usr
response.WriteHeaderAndEntity(http.StatusCreated, usr)
} else {
response.WriteError(http.StatusInternalServerError, err)
}
}

// DELETE http://localhost:8080/users/1
//
func (u *UserResource) removeUser(request *restful.Request, response *restful.Response) {
id := request.PathParameter("user-id")
delete(u.users, id)
}

func main() {
u := UserResource{map[string]User{}}
restful.DefaultContainer.Add(u.WebService())

config := restfulspec.Config{
WebServices: restful.RegisteredWebServices(), // you control what services are visible
APIPath: "/apidocs.json",
PostBuildSwaggerObjectHandler: enrichSwaggerObject}
restful.DefaultContainer.Add(restfulspec.NewOpenAPIService(config))

// Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
// Open http://localhost:8080/apidocs/?url=http://localhost:8080/apidocs.json
http.Handle("/apidocs/", http.StripPrefix("/apidocs/", http.FileServer(http.Dir("/Users/emicklei/Projects/swagger-ui/dist"))))

log.Printf("start listening on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}

func enrichSwaggerObject(swo *spec.Swagger) {
swo.Info = &spec.Info{
InfoProps: spec.InfoProps{
Title: "UserService",
Description: "Resource for managing Users",
Contact: &spec.ContactInfo{
ContactInfoProps: spec.ContactInfoProps{
Name: "john",
Email: "john@doe.rp",
URL: "http://johndoe.org",
},
},
License: &spec.License{
LicenseProps: spec.LicenseProps{
Name: "MIT",
URL: "http://mit.org",
},
},
Version: "1.0.0",
},
}
swo.Tags = []spec.Tag{spec.Tag{TagProps: spec.TagProps{
Name: "users",
Description: "Managing users"}}}
}

// User is just a sample type
type User struct {
ID string `json:"id" description:"identifier of the user"`
Name string `json:"name" description:"name of the user" default:"john"`
Age int `json:"age" description:"age of the user" default:"21"`
}

這個(gè)示例代碼,就是使用 go-restful 的核心功能實(shí)現(xiàn)了一個(gè)簡單的 RESTful 的 API,實(shí)現(xiàn)了對 User 的增刪查改,其中有這么幾個(gè)核心概念:Container、WebService、Route。

  • Container:服務(wù)器容器,包含多個(gè) WebService 和一個(gè) http.ServerMux。
  • WebService:服務(wù),由多個(gè) Route 組成,一個(gè) WebService 其實(shí)代表某一個(gè)對象相關(guān)的服務(wù),如上例中的 /users,針對該 /users 要實(shí)現(xiàn)RESTful API,那么需要向其添加增刪查改的路由,即 Route,它是 Route 的集合。
  • Route:路由,包含了 url,http 方法,接收和響應(yīng)的媒體類型以及處理函數(shù)。每一個(gè) Route,根據(jù) Method 和 Path,映射到對應(yīng)的方法中,即是 Method/Path 到 Function 映射關(guān)系的抽象,如上例中的 ws.Route(ws.GET("/{user-id}").To(u.findUser)),就是針對 /users/{user-id}該路徑的GET請求,則被路由到 findUser 方法中進(jìn)行處理。
  • Container 是 WebService 的集合,可以向 Container 中添加多個(gè) WebService,而 Container 因?yàn)閷?shí)現(xiàn)了 ServeHTTP() 方法,其本質(zhì)上還是一個(gè)http Handler,可以直接用在 http Server 中。

Kubernetes 中對 go-restful 的使用比較基礎(chǔ),就使用到了其最基礎(chǔ)的路由功能,由于 K8s 有很多內(nèi)置的資源對象,也包括 CRD 這種自定義資源對象,所以一開始并不是直接將這些資源對應(yīng)對應(yīng)的接口硬編碼的,而是通過一系列代碼動態(tài)注冊的,所以接下來我們分析的其實(shí)就是想辦法讓 APIServer 能夠提供如下所示的路由處理出來:

GET   /apis/apps/v1/namespaces/{namespace}/deployments/{name}
POST /apis/apps/v1/namespaces/{namespace}/deployments

GET /apis/apps/v1/namespaces/{namespace}/daemonsets/{name}
POST /apis/apps/v1/namespaces/{namespace}/daemonsets

對 go-restful 有一個(gè)基礎(chǔ)了解后,后面就可以去了解下這3個(gè) Server 具體是如何實(shí)例化的了。

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

2022-01-06 07:06:52

KubernetesResourceAPI

2021-11-25 09:54:54

鴻蒙HarmonyOS應(yīng)用

2021-09-16 15:08:08

鴻蒙HarmonyOS應(yīng)用

2022-07-19 20:04:31

NAPI模塊鴻蒙

2010-08-03 12:53:51

FlexBuilder

2009-12-10 13:43:08

使用PHPExcel

2023-11-19 20:16:43

RESTAPIPOST

2011-05-26 10:05:48

MongoDB

2021-02-20 06:09:46

libtask協(xié)程鎖機(jī)制

2010-06-17 15:54:24

UML總結(jié)

2021-05-20 11:13:22

Linux紅外文件

2009-12-29 16:36:47

Silverlight

2021-07-06 09:29:38

Cobar源碼AST

2024-06-13 07:55:19

2021-03-23 09:17:58

SpringMVCHttpServletJavaEE

2023-02-26 08:42:10

源碼demouseEffect

2012-09-20 10:07:29

Nginx源碼分析Web服務(wù)器

2011-05-26 16:18:51

Mongodb

2022-02-14 14:47:11

SystemUIOpenHarmon鴻蒙

2022-12-07 08:02:43

Spring流程IOC
點(diǎn)贊
收藏

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

午夜婷婷在线观看| 欧美性猛交xxxxx水多| 欧美一区二区啪啪| 欧美日韩亚洲在线| 精品视频久久久久| www.成人| 奇米777欧美一区二区| 欧美精品一区二区精品网| 影音先锋欧美在线| 午夜一级黄色片| 亚洲区小说区图片区qvod| 一区二区三区欧美激情| 欧美亚洲国产视频| 欧美xxxxx精品| 色图在线观看| 午夜精品久久久久99热蜜桃导演| 欧美性猛交一区二区三区精品 | 国产日产精品一区二区三区| 欧美裸体在线版观看完整版| 五月激情综合色| 国产高清精品一区二区三区| 少妇aaaaa| 久久精品一级| 亚洲国产一区二区三区青草影视| 岛国视频一区免费观看| 免费黄色片视频| 精品国产精品国产偷麻豆| 在线成人av网站| avove在线观看| 精品久久国产视频| 精品电影一区| 日韩精品视频免费在线观看| 久草资源站在线观看| 久久久久久女乱国产| 久久精品国产清高在天天线| 亚洲深夜福利视频| 欧美 日韩 国产 激情| 成人午夜电影在线观看| 麻豆一区二区在线| 久久亚洲精品国产亚洲老地址| 涩涩网站在线看| 性欧美1819sex性高清大胸| 国产三级精品视频| 91精品国产综合久久香蕉922| 中文字幕五月天| 青青草91久久久久久久久| 7777精品伊人久久久大香线蕉经典版下载 | 大桥未久一区二区三区| 春暖花开成人亚洲区| 久久综合成人精品亚洲另类欧美 | 高清日韩电视剧大全免费| 欧美国产精品va在线观看| 日韩精品人妻中文字幕有码| 日韩亚洲精品在线观看| 精品日韩中文字幕| 久久综合一区二区三区| 中文字幕观看在线| 女同性一区二区三区人了人一| 中文字幕av一区中文字幕天堂| 五月六月丁香婷婷| 久草在线资源站手机版| 国产欧美一区二区三区在线老狼 | 日韩伦理一区二区| 亚洲激情男女视频| 99热都是精品| 综合久久2o19| av在线这里只有精品| 国产成人97精品免费看片| 国产精品视频一区二区在线观看| 亚洲成人影音| 精品国产伦一区二区三区观看方式| 捷克做爰xxxⅹ性视频| 日韩一区二区三区在线看| 日韩欧美国产精品一区| 毛片av免费在线观看| 成人免费网站在线观看视频| 97se亚洲国产综合自在线观| 国产在线精品播放| 99国产精品欲| 日本不卡视频一二三区| 91精品国产自产在线| 午夜精品小视频| 99国产精品久久| 日韩av电影免费播放| 蜜臀av午夜精品| 国产一区在线看| 国产精品久久久久久久久久新婚| 青青草av在线播放| 欧美不卡高清| 97在线观看免费高清| 青青青在线免费观看| 国产一区日韩一区| 久久成人av网站| 日韩成人一区二区三区| 午夜日韩激情| 欧美资源在线观看| 精品美女久久久久| 韩国av一区| 日本aⅴ大伊香蕉精品视频| 91久久久久国产一区二区| 久久亚洲欧美| 欧美性资源免费| 亚洲香蕉在线视频| 秋霞成人午夜伦在线观看| 91久久在线播放| 一级黄色大片免费| k8久久久一区二区三区| 日本在线免费观看一区| 欧美人体视频xxxxx| 亚洲精品国产第一综合99久久| 一女被多男玩喷潮视频| a天堂资源在线| 亚洲一区自拍偷拍| 午夜精品在线免费观看| 久久久久久久| 色综合天天性综合| 日韩av一二三四| 亚洲精品在线a| 日韩欧美不卡在线观看视频| 97超碰在线免费观看| 亚洲理论电影| 色综合久久中文字幕综合网小说| 搜索黄色一级片| 在线免费观看日本欧美爱情大片| 美日韩在线视频| 日本妇女毛茸茸| 在线免费高清一区二区三区| 国产精品一二区| 国产老女人乱淫免费| 国产成人啪午夜精品网站男同| 亚洲自拍偷拍福利| 亚洲精品网站在线| 91免费视频大全| 午夜精品区一区二区三| 日本蜜桃在线观看| 亚洲一区二区在线免费观看视频| 午夜宅男在线视频| 国产免费av国片精品草莓男男 | 国内精品国产成人国产三级| 国产盗摄一区二区三区| 亚洲综合视频一区| 色女人在线视频| 91麻豆精品国产91久久久久久 | 亚洲精品视频在线观看免费| 先锋影音男人资源| 精品国产黄a∨片高清在线| 欧美巨大另类极品videosbest | 狂野欧美一区| 欧美极品一区二区| 亚洲免费福利| 欧美日韩亚州综合| 国产高潮失禁喷水爽到抽搐| 五月综合久久| 久久精彩免费视频| 日本道在线观看| heyzo一本久久综合| 国产美女在线一区| 欧美日韩国产网站| 精品久久国产字幕高潮| 天天干天天操天天拍| 欧美视频二区| 国产精品亚洲片夜色在线| 精品视频一二三| 一区二区高清视频在线观看| 一区二区在线免费观看视频| 欧美日本成人| 色中色综合影院手机版在线观看| 精品人妻一区二区三区麻豆91| 亚洲男人的天堂一区二区| 手机在线播放av| 亚洲经典在线看| 成人激情视频在线观看| 日本一级在线观看| 亚洲久草在线视频| 久久久久无码国产精品一区李宗瑞| 综合五月婷婷| 国产视频一区二区不卡| 欧美成人二区| 91极品美女在线| 亚洲一区二区在线免费| 国产日韩欧美三级| 97久久天天综合色天天综合色hd | 99久久精品国产导航| 国产欧美高清在线| 天天综合一区| 国产精品高潮呻吟久久av无限| 黄色一级a毛片| 亚洲美女精品一区| 日本五十肥熟交尾| 欧美a级一区二区| 99在线影院| 超碰最新在线| 亚洲福利视频网| 免费无遮挡无码永久在线观看视频 | 国产精品tv| 久久精视频免费在线久久完整在线看| 国产高清精品软件丝瓜软件| 欧美日韩国产专区| 永久免费看mv网站入口| 91免费小视频| 1314成人网| 91精品国产91久久久久久密臀| 国产精品美女主播| 国产三线在线| 亚洲成成品网站| 中文字幕第31页| 精品福利在线视频| 天天综合天天做| 久久精品免视看| 天天躁日日躁狠狠躁av| 激情成人亚洲| 伊人狠狠色丁香综合尤物| 亚欧日韩另类中文欧美| 91视频免费在线观看| 亚洲wwww| 中文字幕日韩在线视频| 老司机午夜福利视频| 欧美性淫爽ww久久久久无| 色播视频在线播放| 一区二区成人在线观看| 欧美xxxooo| 狠狠网亚洲精品| 妞干网在线播放| 天海翼精品一区二区三区| 亚洲va男人天堂| 欧美黄色网络| 国产精品日韩在线观看| 欧美片第一页| 琪琪第一精品导航| 乱人伦视频在线| 久久人人爽国产| 久久久久久女乱国产| 精品1区2区在线观看| 国产色片在线观看| 欧美精品自拍偷拍动漫精品| av一级在线观看| 国产精品久线在线观看| 欧美性猛交乱大交| 韩国三级在线一区| 手机版av在线| 韩国av一区| 国产精品视频网站在线观看 | 2018国产在线| 亚洲欧洲一级| 久操网在线观看| 影音先锋久久资源网| 免费高清一区二区三区| 蜜乳av综合| 久久久久久久免费| 国产精品高潮久久| 久久久在线免费观看| 日本h片在线| 久久久久免费视频| 91社区在线观看| 精品国产欧美一区二区| 欧美 日韩 国产 成人 在线| 日韩精品在线看片z| 丰满人妻一区二区三区免费| 精品国产成人系列| 视频二区在线| 日韩一区二区电影| 精品一区二三区| 欧美日韩亚洲高清一区二区| 亚洲天堂视频网| 91精品国产综合久久蜜臀| 精品国产无码一区二区| 精品av久久707| 亚洲av成人精品毛片| 欧美一区二区三区四区视频| 国产人妻精品一区二区三区| 欧美成人乱码一区二区三区| 天堂av2024| 日韩欧美不卡在线观看视频| 蜜桃视频久久一区免费观看入口| 日韩极品精品视频免费观看| 国产香蕉在线| 日韩麻豆第一页| 亚洲国产精品久久久久久6q| 亚洲国产精品久久久久| 亚洲综合免费视频| 日韩丝袜美女视频| 日本a一级在线免费播放| 国产一区二区动漫| 日韩欧美电影在线观看| 中文字幕久久亚洲| 欧美草逼视频| 国产91免费看片| 九色porny丨入口在线| 国产99久久精品一区二区| 自拍偷拍亚洲图片| 久久综合一区二区三区| 国产精品videosex性欧美| 国产原创中文在线观看| 欧美体内she精视频在线观看| 成人黄色av片| 久久99精品久久只有精品| 男人舔女人下面高潮视频| 久久精品国产久精国产| 在线黄色免费网站| 亚洲色欲色欲www| 五月综合色婷婷| 欧美午夜丰满在线18影院| 国产精品天天操| 亚洲男人的天堂在线播放| 少妇性bbb搡bbb爽爽爽欧美| 久久精品小视频| 成人欧美大片| av日韩中文字幕| 欧美电影《轻佻寡妇》| 亚洲精品二区| 日韩综合在线| 日本丰满少妇黄大片在线观看| 一本色道88久久加勒比精品| 久久久久久www| 狠狠色丁香婷婷综合久久片| 国产精品无码一区二区三区| 26uuu欧美| 国产亚洲第一页| 在线播放视频一区| 国产精品秘入口| 欧美亚洲在线视频| 国产美女撒尿一区二区| 在线观看污视频| 国语精品一区| 樱花草www在线| 国产精品你懂的| 免费黄色一级大片| 亚洲乱码国产乱码精品精天堂 | 色小子综合网| 免费大片在线观看| 久久伊人中文字幕| 中文字幕日韩一级| 亚洲成人黄色网| xxx在线免费观看| 痴汉一区二区三区| 黄色精品免费| 精品人妻在线视频| 亚洲一本大道在线| 国产18精品乱码免费看| 欧美日本亚洲视频| 亚洲天堂中文字幕在线观看| 日本免费黄色小视频| 激情综合网天天干| 乱h高h女3p含苞待放| 欧美一区二区三区的| av官网在线播放| 99三级在线| 亚洲国产影院| 中文字幕一区二区人妻电影丶| 亚洲高清免费观看| 无码人妻丰满熟妇区bbbbxxxx| 精品视频偷偷看在线观看| 午夜影院在线播放| 欧美亚洲国产免费| 日本成人在线电影网| 欧美日韩生活片| 岛国视频午夜一区免费在线观看| 日本xxxx人| 日产精品99久久久久久| 国产一区二区三区四区大秀| 波多野结衣与黑人| 日本成人在线电影网| 人妻互换一区二区激情偷拍| 欧美精品少妇一区二区三区 | 亚洲另类春色国产| 亚洲精品18p| 欧美亚洲视频一区二区| 精品一区av| 特黄特黄一级片| 午夜欧美大尺度福利影院在线看| 中文字幕一区二区三区四区免费看 | 免费av在线网址| 99精品国产高清在线观看| 一本久道久久综合婷婷鲸鱼| 欧美熟妇激情一区二区三区| 亚洲一区二区视频| 亚洲色图 校园春色| 国产精品吴梦梦| 国产精品www994| 中文乱码人妻一区二区三区视频| 亚洲欧美日韩国产中文在线| 亚洲爱情岛论坛永久| 日韩av电影手机在线观看| 97精品在线| 国产精品一区二区人妻喷水| 日本高清成人免费播放| 美女写真理伦片在线看| 国产视频在线观看一区| 免费精品视频在线| 99免费在线观看| 色哟哟网站入口亚洲精品| 日韩不卡视频在线观看| 国产精品无码电影在线观看 | 日韩精品一区二区亚洲av性色| 精品久久久久久久久久久久久久久久久| 国产另类xxxxhd高清| 欧美大陆一区二区| 国产在线精品免费| 男人天堂视频网| 韩国三级电影久久久久久|