国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

告別配置復雜性:領域特定語言(DSL)能幫你嗎?

開發 前端
如果您讀到這里,您可能已經猜到我認為配置語言并不是解決配置復雜性的最佳方案。每種語言都有其優缺點,但沒有任何一種語言能帶來顯著的改變。

譯自:Can Configuration Languages (config DSLs) solve configuration complexity?[1]

作者:Brian Grant

配置語言能否顯著降低配置復雜性?

過去幾年涌現出大量旨在生成配置的領域特定語言 (DSL),即配置語言:HCL[2],Dhall[3],Jsonnet[4],Starlark[5],CUE[6],Nickel[7],KCL[8],Pkl[9],以及其他[10]。我敢肯定至少有15種[11]。我通過包含表達式、條件語句、變量和其他語法結構來區分這些語言和 JSON、XML、TOML、INI 等數據序列化語言,這些結構有助于根據輸入生成多個具體的配置作為輸出。我將 YAML 歸類為數據序列化類別。YAMLScript[12] 比較新,我還沒有看到任何使用案例,因此不會介紹它。有關不同類型語言的更詳細細分,請參閱KCL 項目的這篇文章[13],該文章還比較了 KCL 與許多這些語言[14]。

為什么有人會選擇使用配置語言來編寫配置生成器/模板,而不是通用語言或模板語言(例如,Go 模板、Jinja、Mustache)?

對于工具構建者而言,與通用語言相比,一個好處是這些語言(大多)是解釋型語言,并且可以嵌入到工具中,盡管模板語言也具有此特性。配置語言也可能比通用語言或模板語言更容易進行靜態分析,并且可以輕松地確保它們不會產生副作用[15]。

除了根據自己的喜好塑造語言[16]之外,創建新的配置語言的好處還在于它可以更好地控制包和注冊表系統以及標準庫。事實上,其中一些語言最初是為特定工具創建的[17],例如 Terraform 的 HCL,Bazel 的 Starlark Bazel[18],Nix 包管理器的 Nickel Nix 包管理器[19],以及 KusionStack 的 KCL KusionStack[20]。

對于用戶而言,語法可能比通用語言更簡潔。此外,我讀到一些非程序員發現 HCL 與腳本語言(如 shell、awk 和/或 perl?)足夠相似,與 Python 和 Typescript 等通用語言相比更容易上手。對于程序員而言,使用熟悉的通用語言[21] 是 Pulumi 等工具的一個賣點,但也許配置語言可以在多個通用語言用于應用程序的環境中提供一個中立的中間地帶。與模板語言相比,配置語言具有更強大的表達能力,并且通常具有更高的類型安全性和模式驗證能力。

當然,每位語言設計者在設計語言時都有一些具體目標。例如,CUE[22] 基于從 Google 內部配置語言中吸取的經驗教訓(Jsonnet[23] 也是如此),CUE 的一個目標是通過不允許覆蓋來更容易確定最終值設置的位置[24]。Dhall 的一個目標是使導入安全[25]。Starlark 是一種可嵌入的 Python 方言[26],對于熟悉 Python 的人來說很熟悉。Jsonnet 是JSON 的超集[27]。Nickel 中的類型是可選的[28]。Pkl[29]……等等。至少從編程語言設計的角度來看,它們很有趣。好的,這些語言看起來是什么樣的?由于我不精通大多數這些語言,我使用了Claude來生成每個語言的Kubernetes Deployment示例,其中資源名稱、標簽值和容器鏡像都是參數化的。我不得不說,我對Claude印象非常深刻。Claude包含了如何運行每個工具的說明,提到了每種語言的一些好處,并提供了使用特定語言功能進一步改進的建議。我將結果與我能找到的其他示例進行了比較,但沒有通過這些工具運行它們。這只是為了說明這些語言的特點。

以下是Deployment的YAML,其中包含一些屬性值,這些值是字符串、整數和布爾值,以及映射和數組/列表:

apiVersion: apps/v1
kind:Deployment
metadata:
labels:
    app:mydep
name:mydep
namespace:example
spec:
replicas:3
selector:
    matchLabels:
      app:mydep
template:
    metadata:
      labels:
        app:mydep
    spec:
      dnsPolicy:ClusterFirst
      containers:
      -image:nginx:latest
        name:nginx
        ports:
        -containerPort: 8080

使用Kubernetes 提供程序[30] 的HCL:

# Variables
variable "deployment_name" {
  description = "Name of the Kubernetes deployment"
  type = string
}

variable "container_image" {
  description = "Container image to deploy"
  type = string
}

# Deployment resource
resource "kubernetes_deployment" "deployment" {
  metadata {
    name      = var.deployment_name
    namespace = "example"
    labels = {
      app = var.deployment_name
    }
  }

  spec {
    replicas = 3
    selector {
      match_labels = {
        app = var.deployment_name
      }
    }
    template {
      metadata {
        labels = {
          app = var.deployment_name
        }
      }
      spec {
        dns_policy = "ClusterFirst"
        container {
          name  = "nginx"
          image = var.container_image
          port {
            container_port = 8080
          }
        }
      }
    }
  }
}

Dhall (官方示例[31]):

-- Type definitions for our configuration
let Kubernetes =
  https://raw.githubusercontent.com/dhall-lang/dhall-kubernetes/master/package.dhall
let deploymentName : Text = "mydep"
let containerImage : Text = "nginx:latest"
let deploymentLabels =
  toMap { app = deploymentName }
let containerPort =
  Kubernetes.ContainerPort::{
    , containerPort = 8080
  }
let container =
  Kubernetes.Container::{
    , name = "nginx"
    , image = Some containerImage
    , ports = Some [ containerPort ]
  }
let podTemplateSpec =
  Kubernetes.PodTemplateSpec::{
    , metadata = Some Kubernetes.ObjectMeta::{ labels = Some deploymentLabels }
    , spec = Some Kubernetes.PodSpec::{
      , containers = [ container ]
      , dnsPolicy = Some "ClusterFirst"
    }
  }
let deploymentSpec =
  Kubernetes.DeploymentSpec::{
    , replicas = Some 3
    , selector = Kubernetes.LabelSelector::{ matchLabels = Some deploymentLabels }
    , template = podTemplateSpec
  }
in Kubernetes.Deployment::{
  , metadata = Kubernetes.ObjectMeta::{
    , name = Some deploymentName
    , namespace = Some "example"
    , labels = Some deploymentLabels
  }
  , spec = Some deploymentSpec
}

Jsonnet (更多Kubernetes示例[32]):

// Input parameters
local params = {
  deploymentName: 'mydep',
  containerImage: 'nginx:latest',
};

// Helper to generate consistent labels
local labels = {
  app: params.deploymentName,
};

// Main deployment definition
{
  apiVersion: 'apps/v1',
  kind: 'Deployment',
  metadata: {
    name: params.deploymentName,
    namespace: 'example',
    labels: labels,
  },
  spec: {
    replicas: 3,
    selector: {
      matchLabels: labels,
    },
    template: {
      metadata: {
        labels: labels,
      },
      spec: {
        dnsPolicy: 'ClusterFirst',
        containers: [
          {
            name: 'nginx',
            image: params.containerImage,
            ports: [
              {
                containerPort: 8080,
              },
            ],
          },
        ],
      },
    },
  },
}

CUE (Kubernetes 教程[33]) — 我刪除了模式,因為它可能已被導入:

// Input parameters
params: {
  deploymentName: string
  containerImage: string
}

// Default values
params: {
  deploymentName: "mydep"
  containerImage: "nginx:latest"
}

// Deployment configuration
deployment: #Deployment & {
  metadata: {
    name: params.deploymentName
    namespace: "example"
    labels: {
      app: params.deploymentName
    }
  }
  spec: {
    replicas: 3
    selector: {
      matchLabels: {
        app: params.deploymentName
      }
    }
    template: {
      metadata: {
        labels: {
          app: params.deploymentName
        }
      }
      spec: {
        containers: [{
          name: "nginx"
          image: params.containerImage
          ports: [{
            containerPort: 8080
          }]
        }]
      }
    }
  }
}

// Output the deployment
deployment

Pkl (示例[34]):

module deployment

import "package://pkg.pkl-lang.org/k8s/apps/v1/1.27" as apps
import "package://pkg.pkl-lang.org/k8s/core/v1/1.27" as core

// Input parameters
deployCfg {
  name: String = "mydep"
  image: String = "nginx:latest"
}

// Create deployment using official K8s types
output = new apps.Deployment {
  metadata {
    name = deployCfg.name
    namespace = "example"
    labels = new {
      app = deployCfg.name
    }
  }

  spec {
    replicas = 3
    
    selector {
      matchLabels = new {
        app = deployCfg.name
      }
    }
    
    template {
      metadata {
        labels = new {
          app = deployCfg.name
        }
      }
      
      spec {
        dnsPolicy = "ClusterFirst"
        
        containers = List(
          new core.Container {
            name = "nginx"
            image = deployCfg.image
            ports = List(
              new core.ContainerPort {
                containerPort = 8080
              }
            )
          }
        )
      }
    }
  }
}

Nickel (示例[35]):

# Type contracts
let DeploymentConfig = {
  name | Str,
  image | Str,
}

# Function to generate labels
let makeLabels = fun name => {
  app = name
}

# Main deployment generator function
let makeDeployment = fun config | DeploymentConfig => {
  apiVersion = "apps/v1",
  kind = "Deployment",
  metadata = {
    name = config.name,
    namespace = "example",
    labels = makeLabels config.name,
  },
  spec = {
    replicas = 3,
    selector = {
      matchLabels = makeLabels config.name,
    },
    template = {
      metadata = {
        labels = makeLabels config.name,
      },
      spec = {
        dnsPolicy = "ClusterFirst",
        containers = [
          {
            name = "nginx",
            image = config.image,
            ports = [
              {
                containerPort = 8080,
              },
            ],
          },
        ],
      },
    },
  },
}

# Default configuration
let defaultConfig = {
  name = "mydep",
  image = "nginx:latest",
}

# Generate the deployment with default config
makeDeployment defaultConfig

KCL (示例[36]):

import k8s.api.apps.v1 as appsv1
import k8s.api.core.v1 as corev1

# Configuration parameters
schema DeploymentConfig:
    name: str = "mydep"
    image: str = "nginx:latest"

# Configuration values
config = DeploymentConfig {}

# Generate deployment using standard library types
deployment = appsv1.Deployment {
    metadata = corev1.ObjectMeta {
        name = config.name
        namespace = "example"
        labels.app = config.name
    }
    spec = appsv1.DeploymentSpec {
        replicas = 3
        selector = corev1.LabelSelector {
            matchLabels.app = config.name
        }
        template = corev1.PodTemplateSpec {
            metadata = corev1.ObjectMeta {
                labels.app = config.name
            }
            spec = corev1.PodSpec {
                dnsPolicy = "ClusterFirst"
                containers = [
                    corev1.Container {
                        name = "nginx"
                        image = config.image
                        ports = [
                            corev1.ContainerPort {
                                containerPort = 8080
                            }
                        ]
                    }
                ]
            }
        }
    }
}

Starlark (示例[37]):

# Helper function to create consistent labels
def make_labels(name):
    return {"app": name}

# Main deployment generator function
def make_deployment(name = "mydep", image = "nginx:latest"):
    """Creates a Kubernetes deployment configuration.
    
    Args:
        name: The name of the deployment
        image: The container image to deploy
    
    Returns:
        Dictionary containing the deployment configuration
    """
    return {
        "apiVersion": "apps/v1",
        "kind": "Deployment",
        "metadata": {
            "name": name,
            "namespace": "example",
            "labels": make_labels(name),
        },
        "spec": {
            "replicas": 3,
            "selector": {
                "matchLabels": make_labels(name),
            },
            "template": {
                "metadata": {
                    "labels": make_labels(name),
                },
                "spec": {
                    "dnsPolicy": "ClusterFirst",
                    "containers": [
                        {
                            "name": "nginx",
                            "image": image,
                            "ports": [
                                {
                                    "containerPort": 8080,
                                },
                            ],
                        },
                    ],
                },
            },
        },
    }

# Default deployment configuration
deployment = make_deployment()

def main(ctx):
    """Main entry point for Starlark configuration.
    
    Args:
        ctx: The rule context
    
    Returns:
        The deployment configuration
    """
    return deployment

正如不同的通用編程語言一樣,語法[38] 顯然也略有不同:是否使用大括號,是否允許尾隨逗號,雙引號與單引號與無引號,嚴格嵌套與否,冒號與等號,是否使用類型名稱,是否在語言內部定義模式,是否需要顯式生成語句,額外的關鍵字或標點符號等等。有些語言的樣板代碼稍多一些,有些則稍少一些。類型安全在每種語言中的工作方式也略有不同。不同的語言會讓不同的人感覺更熟悉,這取決于他們了解的其他語言。例如,Dhall 可能對熟悉 Haskell 的人來說更熟悉[39]。

在這個例子中,這些語言并沒有什么顯著的優勢。我本可以使用 envsubst。我沒有使用更復雜的例子,例如圍繞 Deployment 構建可重用的函數或模塊,部分原因是為了保持例子的簡單性,部分原因是我已經多次看到這種抽象被削弱[40],并且已經看到試圖使配置更可重用適得其反[41] 的嘗試。在任何這些語言中,具有大量參數的 Kubernetes Deployment 也不會更簡單。

無論如何,沒有任何配置語言能夠比使用 cdk8s 或 Pulumi 等通用語言的工具更強大。配置語言在 JSON 和 YAML 等數據格式與通用語言之間是一種折衷方案。對某些人來說,這是一個恰到好處的選擇,而對另一些人來說則不然?;蛘咧皇桥渲脧碗s性時鐘[42]上的一個停頓點。

其目的是,語言施加的約束應該使更容易發現和防止錯誤,并可能使配置更容易閱讀和/或編寫。但是,雖然我已經閱讀了許多關于哪些語言“更好”或“更差”的冗長辯論[43],但它們都是主觀的,并且沒有達成共識。我沒有看到任何關于用不同語言表達配置生成器的定量益處的研究。如果您知道任何此類研究,請告訴我!

此外,雖然這些語言周圍的生態系統有時優于模板語言(Pkl 更強調其集成[44]而不是特定語言特性),但它們實際上無法與通用語言相比。配置語言可用的文檔、示例、教育內容、工具集成、服務集成等都較少。

原因之一是,所有配置語言的使用范圍都遠不如 Python 或 Javascript 等流行的編程語言廣泛。其中最流行的語言是 HCL,這當然是因為 Terraform 的流行。但是,我沒有看到 HCL 在 Terraform 生態系統之外使用,有些人甚至用 YAML 包裝它的用途[45]。就像Helm 的模板語法[46]一樣,并非每個人都喜歡它,但它通常都能完成工作。

好的,我的觀點是什么?

如果您讀到這里,您可能已經猜到我認為配置語言并不是解決配置復雜性的最佳方案。每種語言都有其優缺點,但沒有任何一種語言能帶來顯著的改變。它們是微優化而不是宏優化。正如我之前提到的[47]那樣,沒有任何新的配置語言能夠解決IaC 的根本問題[48]。為了取得顯著改進,我們需要對整體方法進行一些宏觀層面的改變。

您是否有我未涉及的喜歡的配置語言?它的優勢是什么?您是否發現使用配置語言與其他表示和方法相比有任何顯著的、可衡量的益處?您是否發現該語言的任何靜態分析工具特別有用?您組織中的其他人學習該語言是否遇到任何困難?您是否想知道為什么我們到 2025 年仍在手動編寫配置文件?

請隨時在此處回復,或通過LinkedIn[49], X/Twitter[50], 或Bluesky[51]向我發送消息,我計劃將此內容交叉發布。

如果您覺得這篇文章有趣,您可能還會對我的基礎設施即代碼和聲明式配置系列[52]中的其他文章感興趣。

引用鏈接

[1]?Can Configuration Languages (config DSLs) solve configuration complexity?:https://itnext.io/can-configuration-languages-dsls-solve-configuration-complexity-eee8f124e13a

[2]HCL:https://github.com/hashicorp/hcl

[3]Dhall:https://dhall-lang.org/

[4]Jsonnet:https://jsonnet.org/

[5]Starlark:https://github.com/bazelbuild/starlark

[6]CUE:https://cuelang.org/

[7]Nickel:https://nickel-lang.org/

[8]KCL:https://www.kcl-lang.io/

[9]Pkl:https://pkl-lang.org/

[10]其他:https://github.com/rix0rrr/gcl

[11]15種:https://xkcd.com/927/

[12]YAMLScript:https://yamlscript.org/

[13]KCL 項目的這篇文章:https://blog.stackademic.com/10-ways-for-kubernetes-declarative-configuration-management-3538673fd0b5

[14]比較了 KCL 與許多這些語言:https://www.kcl-lang.io/docs/user_docs/getting-started/intro

[15]確保它們不會產生副作用:https://sre.google/workbook/configuration-specifics/

[16]根據自己的喜好塑造語言:https://ruudvanasseldonk.com/2024/a-reasonable-configuration-language

[17]為特定工具創建的:https://www.reddit.com/r/ProgrammingLanguages/comments/gzqsxj/the_future_of_general_purpose_configuration/

[18]Bazel:https://bazel.build/extending/config

[19]Nix 包管理器:https://www.tweag.io/blog/2023-01-24-nix-with-with-nickel/

[20]KusionStack:https://www.kusionstack.io/docs/

[21]使用熟悉的通用語言:/generating-configuration-using-general-purpose-programming-languages-19230a2c2573

[22]CUE:https://cuelang.org/docs/introduction/

[23]Jsonnet:https://jsonnet.org/

[24]通過不允許覆蓋來更容易確定最終值設置的位置:https://cuelang.org/docs/concept/the-logic-of-cue/#relation-to-inheritance

[25]Dhall 的一個目標是使導入安全:https://dhall-lang.org/

[26]可嵌入的 Python 方言:https://github.com/bazelbuild/starlark/?tab=readme-ov-file#design-principles

[27]JSON 的超集:https://jsonnet.org/articles/design.html

[28]Nickel 中的類型是可選的:https://nickel-lang.org/user-manual/introduction

[29]Pkl:https://www.youtube.com/watch?v=N7zmsHUiTkM

[30]Kubernetes 提供程序:https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment#example-usage

[31]官方示例:https://github.com/dhall-lang/dhall-kubernetes/blob/master/examples/deployment.dhall

[32]更多Kubernetes示例:https://jsonnet.org/articles/kubernetes.html

[33]Kubernetes 教程:https://github.com/cue-labs/cue-by-example/tree/main/003_kubernetes_tutorial#controlling-kubernetes-with-cue

[34]示例:https://github.com/apple/pkl-k8s-examples/tree/main/pkl

[35]示例:https://github.com/tweag/nickel-kubernetes/blob/master/examples/redis-replication-controller.ncl

[36]示例:https://github.com/kcl-lang/examples

[37]示例:https://github.com/cruise-automation/isopod/blob/master/examples/ingress.ipd

[38]語法:https://github.com/lightbend/config/blob/master/HOCON.md#syntax

[39]對熟悉 Haskell 的人來說更熟悉:https://pv.wtf/posts/taming-the-beast#dhall

[40]這種抽象被削弱:/the-tension-between-flexibility-and-simplicity-in-infrastructure-as-code-6cec841e3d16

[41]使配置更可重用適得其反:https://medium.com/itnext/how-software-engineering-instincts-clash-with-infrastructure-as-code-6b18a9cd9cef

[42]配置復雜性時鐘:https://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html

[43]冗長辯論:https://news.ycombinator.com/item?id=22787332

[44]Pkl 更強調其集成:https://github.com/apple/pkl/discussions/7

[45]用 YAML 包裝它的用途:https://github.com/AppsFlyer/terra-crust

[46]Helm 的模板語法:/kubernetes-configuration-in-2024-434abc7a5a1b

[47]之前提到的:/fundamental-challenges-with-infrastructure-as-code-imply-the-language-doesnt-matter-41030475c296

[48]IaC 的根本問題:/the-12-anti-factors-of-infrastructure-as-code-acb52fba3ae0

[49]LinkedIn:https://www.linkedin.com/in/bgrant0607/

[50]X/Twitter:https://x.com/bgrant0607

[51]Bluesky:https://bsky.app/profile/bgrant0607.bsky.social

[52]基礎設施即代碼和聲明式配置系列:https://medium.com/@bgrant0607/list/infrastructure-as-code-and-declarative-configuration-8c441ae74836

責任編輯:武曉燕 來源: 云云眾生S
相關推薦

2020-03-04 11:20:22

DSL開發領域特定語言

2019-08-21 13:24:25

KubernetesHadoop容器

2021-06-07 21:02:44

語言業務領域

2013-11-01 13:38:41

程序員編程語言

2012-12-26 10:53:26

2009-03-12 14:31:15

QCon

2017-06-23 08:45:02

存儲技術復雜性

2019-05-13 15:47:29

Kubernetes云計算云復雜性

2009-01-20 15:23:33

存儲安全密鑰數據保護

2021-04-29 15:15:03

網絡配置網絡復雜性網絡

2019-11-23 23:30:55

Python數據結構時間復雜性

2019-07-29 12:35:15

云計算復雜性云計算平臺

2010-05-27 22:30:08

桌面虛擬化回報

2012-04-10 22:52:58

IBMTivoli云計算

2016-11-22 09:24:29

大數據部署Hadoop

2023-04-04 08:42:30

IT成本技術堆

2012-09-19 13:18:37

復雜設計UI設計

2020-06-15 09:58:23

云計算云安全數據

2022-06-17 11:04:47

語法分析器GoyaccAST

2017-08-29 20:19:56

對象存儲架構存儲數據中心
點贊
收藏

51CTO技術棧公眾號

亚洲成人免费| 亚洲视频网在线直播| 日韩av免费在线看| 国产免费拔擦拔擦8x高清在线人 | 一区二区亚洲精品| 国产精品高潮呻吟视频| 国产精品1区在线| 久艹在线视频| 91小视频在线免费看| 自拍偷拍视频在线| 三级影片在线观看欧美日韩一区二区 | 免费 成 人 黄 色| 国产老女人精品毛片久久| 亚洲精品一区二区久| 精品无码国产一区二区三区av| 精品少妇无遮挡毛片| 一区二区乱码| 国产探花在线精品| 久久精品免费观看| 少妇高潮 亚洲精品| 成人免费观看cn| 中文字幕在线观看第三页| 久草中文综合在线| 亚洲欧洲日韩综合二区| 99热在线精品观看| 久久精品国产理论片免费| 新版中文字幕在线资源| 美女黄网久久| 亚洲国产成人高清精品| 天天综合天天操| 日韩片欧美片| 亚洲free嫩bbb| 69堂免费精品视频在线播放| 亚洲欧美一区二区三区情侣bbw| 欧美在线视频一区| 黑人粗进入欧美aaaaa| 成年人视频免费在线播放| 精品一区91| 亚洲图片自拍偷拍| 国产精品一区二区久久精品 | 色一区av在线| 日本一级理论片在线大全| 欧美精品自拍偷拍动漫精品| 高清国产福利在线观看| 欧美一区二区三区视频在线| 免费男女羞羞的视频网站在线观看| 亚洲护士老师的毛茸茸最新章节| 国模套图日韩精品一区二区| 中文字幕精品—区二区| av综合网页| 国产精品稀缺呦系列在线| 亚洲人成免费| 51xx午夜影福利| 国产精品免费视频网站| 天堂影院在线| 精品无码久久久久久国产| 国产狼人综合免费视频| 亚洲无中文字幕| 警花观音坐莲激情销魂小说| 91麻豆蜜桃一区二区三区| 玖玖在线免费视频| 精品日韩av一区二区| 日韩在线亚洲| 国产一区二区三区免费不卡| 国产suv一区二区三区88区| 免费女人黄页| 日韩欧美一区二区在线视频| 色综合.com| 成人动漫视频在线观看免费| 国产一区91精品张津瑜| 日韩男人天堂| 亚洲人成毛片在线播放| 成人激情诱惑| 免费网站在线观看视频| 欧美日韩激情视频8区| 高清电影一区| 91在线看www| 91香蕉视频黄| 国产二区在线播放| 欧美激情一级精品国产| 国产亚洲在线| 男女激情视频网站| 亚洲天堂成人在线| 欧美在线网站| 天天爱天天操天天干| 日韩精品一区二区在线观看| 色橹橹欧美在线观看视频高清| 日韩精品大片| 午夜私人影院久久久久| 日韩城人网站| 欧美一区1区三区3区公司 | 国产成人精品自拍| 久久久久免费观看| 黄色小说在线播放| 91精品免费看| 欧美国产禁国产网站cc| 182在线播放| 91精品国产综合久久香蕉| 91亚洲大成网污www| 伊人影院蕉久影院在线播放| 国产精品男女猛烈高潮激情| 95精品视频在线| 超碰在线99| 欧美精品免费观看二区| 欧美视频在线视频| 欧美日韩播放| 国产三级三级看三级| 中国china体内裑精亚洲片| 国产人成精品一区二区三| 诱人的瑜伽老师3hd中字| 色在人av网站天堂精品| 成人激情免费网站| 无码小电影在线观看网站免费| 好看的日韩精品| 在线欧美日韩精品| 色天天综合网| 麻豆免费网站| 欧美中文在线免费| 中文字幕亚洲一区二区av在线| 国产亚洲久久| 欧美精品色婷婷五月综合| 中文字幕久热精品在线视频| 黑人巨大精品欧美黑白配亚洲| 超碰在线最新| 国产伦视频一区二区三区| 粉嫩老牛aⅴ一区二区三区| 精品久久久亚洲| 97秋霞电影网| 日本欧美中文字幕| 综合亚洲深深色噜噜狠狠网站| 亚洲精品一区国产| 少妇激情一区二区三区| www.久久久久久.com| 成人午夜在线播放| 亚州精品国产| 中文字幕国产传媒| 欧美一级大片在线观看| 亚洲色图制服丝袜| 欧美色图一区| 国产精品一区二区三区四区色| 91九色偷拍| 欧美性视频一区二区三区| 亚洲国产国产亚洲一二三| 风间由美一区| 欧美精品一区在线| 亚洲毛茸茸少妇高潮呻吟| 成人免费看黄yyy456| 免费一级欧美片在线观看网站| 一级在线免费视频| 国产suv精品一区二区| 欧美日韩在线视频一区| 99热免费精品在线观看| 大桥未久在线视频| 精品成在人线av无码免费看| 久久久精品国产| 一区二区三区精品| 影音先锋久久| 日韩成人动漫| av高清在线| 超碰97在线资源| 日韩精品免费在线| 国产欧美精品一区二区色综合 | 五月天亚洲视频| 国产精品草莓在线免费观看| 精品高清美女精品国产区| 亚洲狼人精品一区二区三区| 黑人玩欧美人三根一起进| 日韩一级片免费视频| 高清欧美性猛交xxxx| 色综合中文字幕| 久久国产人妖系列| 粉嫩精品导航导航| 伦理片一区二区三区| 一区精品视频| 久久免费福利视频| 欧美专区亚洲专区| 懂色一区二区三区免费观看| 荡女精品导航| yiren22综合网成人| 亚洲一区二区三区涩| 欧美日韩xxxxx| 在线日韩一区二区| 波多野结衣中文字幕一区| 欧美亚洲国产日韩| av免费网站在线观看| 男的插女的下面视频| 国产精品18久久久久久首页狼| 欧美日韩国产综合一区二区三区 | 国产精品网站在线| 今天的高清视频免费播放成人| 天堂av中文在线观看| 1024欧美极品| 视频一区二区精品| 日本午夜在线亚洲.国产| 欧美中文字幕一区| 91一区二区三区在线观看| 黄色av一区| 无码国模国产在线观看| 影院在线观看全集免费观看| 久久久久久久久久久久久久久久久久久|