精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

欧美成人免费高清视频| 国产精品日韩av| 永久免费看片在线观看| 国产原创视频在线观看| 国模无码大尺度一区二区三区| 北条麻妃99精品青青久久| 免费不卡av网站| 国产社区精品视频| 国产校园另类小说区| 91免费欧美精品| 日本少妇性高潮| 久久99国产精一区二区三区| 欧美剧情片在线观看| 国产乱人伦精品一区二区三区| 免费观看成年人视频| 亚洲一卡久久| 日韩中文视频免费在线观看| 中国男女全黄大片| 成人看片网站| 亚洲另类在线一区| 久久精品aaaaaa毛片| 国产又粗又黄视频| 亚洲综合国产| 久久亚洲精品国产亚洲老地址| 日韩在线一区视频| 交100部在线观看| 中文字幕一区在线观看视频| 国产九色91| 伊人久久亚洲综合| 日韩一级网站| 久久精品视频免费播放| 人妻熟女aⅴ一区二区三区汇编| 播放一区二区| 亚洲狠狠爱一区二区三区| 亚洲 日韩 国产第一区| 俄罗斯嫩小性bbwbbw| 奇米色一区二区三区四区| 中国av一区二区三区| 国产精品午夜在线观看| 无码av免费一区二区三区试看| 欧美13一14另类| www.久久久久久| 日本91福利区| 欧美激情videos| 欧美性猛交xxxx乱大交少妇| 外国成人在线视频| 日韩免费看网站| av动漫免费看| www555久久| 亚洲免费资源在线播放| 亚洲精品中文字幕在线| 免费毛片在线| 99久久国产综合精品麻豆| 亚洲最大av网站| 一区二区三区免费观看视频| 媚黑女一区二区| 久久久亚洲福利精品午夜| 国产wwwwxxxx| 色婷婷亚洲mv天堂mv在影片| 亚洲精品日韩久久久| 国产人妻黑人一区二区三区| 136国产福利精品导航网址应用| 欧美日韩国产123区| 看欧美ab黄色大片视频免费| 一个人看的www视频在线免费观看 一个人www视频在线免费观看 | 精品在线一区二区三区| 国产成人精品久久二区二区91| 日本一级淫片免费放| 在线播放一区| 久久久久久12| 国产精品999久久久| 欧美精品国产| 欧美激情区在线播放| 久久成人在线观看| 亚洲第一黄色| 4438全国成人免费| 在线视频一区二区三区四区| 久久亚洲欧洲| 国产精品日韩欧美| 91九色蝌蚪91por成人| 美女视频免费一区| 成人在线视频网| 国产夫妻自拍av| 国产成人在线视频播放| 亚洲free性xxxx护士hd| 国产又黄又粗又猛又爽| 国产精品一区二区免费不卡 | 色综合视频一区二区三区44| 欧美福利电影网| 嫩草av久久伊人妇女超级a| 日韩一区二区三区在线免费观看| 欧美性大战久久久久久久| 九色porny自拍| 国产亚洲高清一区| 欧美精品一区二区三| v8888av| 精品久久不卡| 久久不射电影网| 精品久久免费视频| 性色一区二区| 国产噜噜噜噜噜久久久久久久久| а√天堂资源在线| 99国产欧美久久久精品| 性高潮久久久久久久久| 伊人春色在线观看| 欧美性xxxxxx| 天堂av手机在线| 任我爽精品视频在线播放| 国产亚洲欧美日韩精品| 中文字幕在线2021| 99精品视频免费全部在线| 日韩美女视频免费在线观看| 国产精品久久久久久在线| 99视频一区二区三区| 日韩欧美视频一区二区三区四区 | 亚洲色图15p| 精品国产视频在线观看| 999亚洲国产精| 成人福利视频在线观看| 天天操天天插天天射| 国产精品国产三级国产普通话99| 2022中文字幕| 在线看的毛片| 日韩欧美色综合| 日本一二三不卡视频| 欧美日韩伊人| 91超碰caoporn97人人| 在线播放国产一区| av激情亚洲男人天堂| 一区不卡字幕| 国产精品专区免费| 精品噜噜噜噜久久久久久久久试看| www.av欧美| 99精品国产在热久久| 成人写真福利网| 每日更新在线观看av| 一区二区三区不卡视频在线观看| 我看黄色一级片| 亚洲8888| 午夜精品国产精品大乳美女| 99精品视频网站| 中文字幕在线视频第一页| 成人精品电影在线观看| 宅男av一区二区三区| 免费看av不卡| 亚洲精品美女在线| 久久久久香蕉视频| 国产综合一区二区| 亚洲午夜精品一区二区三区| 欧美大片免费观看网址| 日韩精品在线视频美女| 免费在线观看亚洲| 国产麻豆视频一区| 四虎影院一区二区| 日本中文字幕视频一区| 亚洲精品视频久久| 97久久久久久久| 成人av网站在线观看免费| 欧洲精品视频在线| 日韩区欧美区| 久久国产精品久久久久久| 色婷婷久久综合中文久久蜜桃av| www国产亚洲精品久久麻豆| 日韩美女爱爱视频| 澳门成人av| 欧美激情xxxxx| 亚洲精品第五页| 亚洲精品免费看| 丰满人妻一区二区三区53视频| 欧美色婷婷久久99精品红桃| 国产精国产精品| 国产二区视频在线观看| 在线一区二区三区做爰视频网站| 亚洲av无码一区二区三区人| 免费精品视频| 日本一区视频在线播放| 亚洲天堂1区| 丝袜亚洲欧美日韩综合| 国产一区二区三区三州| 亚洲精品福利视频网站| 国产ts在线观看| 亚洲第一区色| 色婷婷综合久久久| 99日在线视频| 亚洲色图二区| 国产超碰91| 国产美女高潮在线观看| 亚洲欧美日韩天堂| 中文字幕第315页| 日韩美女视频一区| 久久无码专区国产精品s| 亚洲视频观看| 蜜桃在线一区二区三区精品| 黄色成人在线视频| 美女av一区二区三区| 婷婷丁香一区二区三区| 欧美日韩高清一区二区| 97超碰蝌蚪网人人做人人爽| 婷婷在线观看视频| 在线视频欧美精品| 中文字幕在线有码| 91亚洲精品久久久蜜桃网站| 可以免费在线看黄的网站| 天天综合网91| 另类小说综合网| 成人乱码手机视频| 日本精品一区二区三区在线播放视频 | 国产精品国产三级国产专播品爱网 | 国产成人精品免费在线| 88av.com| 亚洲精品色图| 日日噜噜夜夜狠狠久久丁香五月| 色哟哟精品丝袜一区二区| 亚洲va电影大全| 日韩经典一区| 欧美一级片久久久久久久| 五月婷婷视频在线观看| 国产午夜精品视频免费不卡69堂| 空姐吹箫视频大全| 欧美肥胖老妇做爰| 亚洲图片欧美日韩| 精品久久久久久中文字幕一区奶水 | 波多野结衣三级视频| 欧美aaa在线| 激情婷婷综合网| 99av国产精品欲麻豆| 隔壁人妻偷人bd中字| 亚洲h色精品| 一区二区三区四区视频在线| 奇米色欧美一区二区三区| 国产视频在线观看一区| 伊人www22综合色| 亚洲a∨日韩av高清在线观看| 成人在线观看免费播放| 日本欧美黄网站| 户外露出一区二区三区| 欧美怡春院一区二区三区| 123区在线| 久久久亚洲成人| 91av久久| 欧美亚洲视频在线观看| 国产精品迅雷| 国产99久久精品一区二区| 亚洲精品中文字幕| 欧美在线欧美在线| 91av亚洲| 国产精品第一第二| 电影一区电影二区| 国产欧美在线视频| 91成人app| 成人动漫视频在线观看完整版| 中文字幕一区二区三区四区久久| 91久久极品少妇xxxxⅹ软件| a级日韩大片| 久久草.com| 精品一区三区| 久中文字幕一区| 欧美日韩播放| 婷婷精品国产一区二区三区日韩| 99精品视频在线| 一级黄色片播放| 亚洲精品乱码久久久久久蜜桃麻豆| 黄页网站在线观看视频| 亚洲少妇自拍| 国产自偷自偷免费一区 | 九一在线视频| 中文字幕久热精品视频在线| 国产激情视频在线| 久久久久久久久国产精品| 日韩伦理福利| 国产精品自拍视频| 亚洲精品a区| 欧美高清一区二区| 国产精品久久久久久| 日本熟妇人妻xxxx| 日韩精品91亚洲二区在线观看| 加勒比av中文字幕| 99在线精品观看| 国精产品视频一二二区| 一区二区高清视频在线观看| 中文字幕激情小说| 欧美高清精品3d| 色香蕉在线视频| 日韩一中文字幕| sm捆绑调教国产免费网站在线观看| 国产成人在线视频| 国产高清日韩| 欧美国产视频在线观看| 亚洲五月综合| 最近免费中文字幕中文高清百度| 国内精品不卡在线| 日韩av一二区| 亚洲黄色尤物视频| 懂色av蜜臀av粉嫩av喷吹| 日韩午夜电影av| 成年人视频免费在线观看| 欧美日韩成人在线观看| 福利一区二区| 激情小说网站亚洲综合网 | 美女999久久久精品视频| 蜜桃视频在线网站| 91夜夜未满十八勿入爽爽影院| 日日狠狠久久偷偷综合色| 欧美性受黑人性爽| 久久久xxx| 91丨porny丨对白| 中文字幕在线不卡一区二区三区| 国产精品人人人人| 欧美一二三四在线| 91这里只有精品| 国产91九色视频| 美女av一区| 老司机午夜免费福利视频| 麻豆国产一区二区| 欧美另类z0zx974| 欧美日韩免费区域视频在线观看| 国产乱叫456在线| 色悠悠久久88| 欧美日韩成人影院| 久久综合九色欧美狠狠| 国产精品地址| 中文字幕1区2区| 自拍偷拍国产精品| 在线视频你懂得| 亚洲人成在线观| 肉色欧美久久久久久久免费看| 国产二区不卡| 欧美午夜不卡影院在线观看完整版免费| www.天天射.com| 久久久久久久性| www欧美在线| 日韩av中文在线| a'aaa级片在线观看| 91超碰在线免费观看| 天天色天天射综合网| 中文字幕66页| 国产精品久久三| 在线观看中文字幕2021| 伊人伊人伊人久久| 久久天天久久| 一级日韩一区在线观看| 久久国产精品免费| 手机免费观看av| 欧美精品在线观看播放| 免费黄色电影在线观看| 91夜夜揉人人捏人人添红杏| 亚洲影视一区| 免费观看一区二区三区| 亚洲一区在线视频| 亚洲欧美激情国产综合久久久| 欧美精品国产精品日韩精品| 我要色综合中文字幕| 欧美成人精品免费| 99久久久免费精品国产一区二区| 亚洲第一在线播放| 国产一区二区三区在线视频| 福利一区二区| 夜夜嗨av一区二区三区四季av| 欧美精品亚洲精品日韩精品| 精品性高朝久久久久久久| 欧美二三四区| 一本色道久久综合亚洲精品婷婷| 精品一区精品二区高清| 欧美成人精品欧美一级私黄| 亚洲国产古装精品网站| 惠美惠精品网| 在线视频不卡国产| 粉嫩av一区二区三区| 国产精品人人人人| 日韩一区二区三区在线播放| 99亚洲乱人伦aⅴ精品| 少妇无码av无码专区在线观看| 国产偷国产偷精品高清尤物| 99riav国产| 77777少妇光屁股久久一区| 国产尤物久久久| 性鲍视频在线观看| 精品福利免费观看| 在线免费av电影| 国产精选在线观看91| 日本成人在线一区| 久久99久久98精品免观看软件| 亚洲裸体xxxx| 精品午夜av| 国产精品欧美激情在线观看| 亚洲三级小视频| 欧美偷拍视频| 亚洲va久久久噜噜噜久久天堂| 亚洲专区一区| 青娱乐在线视频免费观看| 亚洲深夜福利网站| 日韩精品一区二区三区中文在线 | 欧洲av一区| 国产精品一区二区不卡| 亚洲欧美一二三区| 欧美黑人一级爽快片淫片高清| 精品视频亚洲| 亚洲精品中文字幕在线播放| 欧美日韩综合在线| 国产高清中文字幕在线|