[kube 027]用CUE配置K8s

CUE是一种开源数据约束语言,旨在简化涉及定义和使用数据的任务。它是JSON的超集,可让熟悉JSON的用户快速入门。

什么是CUE

CUE(https://cuelang.org/)是一种开源的数据验证语言和推理引擎,其根源在于逻辑编程。虽然该语言不是通用的编程语言,但它有很多应用,如数据验证、数据模板、配置、查询、代码生成甚至脚本。推理引擎可以用来验证代码中的数据,也可以将其作为代码生成流水线的一部分。

CUE区别于同类语言的一个关键点是它将类型和值合并成一个单一的概念。在大多数语言中,类型和值是严格区分的,而CUE则将它们排列在一个单一的层次结构(网格)中。这是一个非常强大的概念,它允许CUE做很多花哨的事情。它还简化了事情。

CUE的应用

CUE的设计确保了以任何顺序组合CUE值总是得到相同的结果(它是关联的、互换的和幂等的)。这使得CUE特别适合于从不同来源的CUE约束组合的情况。

  • 数据验证
    不同的部门或组可以各自定义自己的约束条件,应用于同一组数据。

  • 代码提取和生成
    从多个来源(Go代码、Protobuf)提取CUE定义,将它们组合成一个定义,并使用该定义生成另一种格式的定义(如OpenAPI)。

  • 配置
    可以将不同来源的值组合在一起,而不需要导入另一个。

值的排序也允许对整个配置进行集合包含分析。大多数验证系统只限于检查一个具体的值是否匹配一个模式,而CUE可以验证一个模式的任何实例是否也是另一个模式的实例(是否向后兼容?),或者计算一个新的模式,代表所有匹配两个其他模式的实例。

CUE的使用案例

CUE可用于与数据相关的广泛的连续应用中。在不同的应用领域提供下列优势。

  • 配置
    管理基于文本的文件,以定义系统的理想状态。

  • 数据验证
    验证基于文本或程序的数据。为数据定义一个详细的验证模式(手动或自动从数据中获取)。

  • 模式定义
    定义模式来传达API或标准。

  • 代码生成和提取
    CUE约束转换为其他语言中的定义或从其他语言中转换出来。

  • 查询
    查找符合特定标准的数据。

  • 脚本
    定义和运行声明式脚本

CUE的安装

  • 二进制文件安装CUE
    在页面https://github.com/cuelang/cue/releases中下载对应的二进制文件

  • MacOSLinux使用brew安装CUE

brew install cuelang/tap/cue
  • 源码安装CUE

下载并安装cue命令行工具运行:

go get -u cuelang.org/go/cmd/cue

要同时下载API和文档,请运行:

go get -u cuelang.org/go/cue

Kubernetes的CUE

CUE并非特定于Kubernetes。它可用于创作任何结构化配置。CloudBuildCircle CI配置,Cloud InitCloudFormationAzure资源管理器模板等。CUE是用于编写配置的工具,而不是另一种序列化有线格式。

下面是一个deployment YAML中的简单配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes
  template:
    metadata:
      labels:
        app: hello-kubernetes
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.8
        ports:
        - containerPort: 8080

运行下列命令:

$ cue import deployment.yaml
$ ls
deployment.cue    deployment.yaml

查看deployment.cue内容如下:

apiVersion: "apps/v1"
kind:       "Deployment"
metadata name: "hello-kubernetes"
spec: {
  replicas: 3
  selector matchLabels app: "hello-kubernetes"
  template: {
    metadata labels app: "hello-kubernetes"
    spec containers: [{
      name:  "hello-kubernetes"
      image: "paulbouwer/hello-kubernetes:1.5"
      ports: [{
        containerPort: 8080
      }]
    }]
  }
}

如上所述,CUEJSON的超集。但是也有下列可用性的差异:

  • 没有最外面的嵌套"{}"
  • 结尾没有逗号
  • 嵌套语句的单行格式,如selector matchLabels app: "hello-kubernetes"

CUE模板

YAML只是一种序列化格式。为了减少管理多个配置文件时的重复,需要经常在顶部使用模板工具。CUE使数据成为该语言的一流部分。

package kubernetes

deployment : {
 apiVersion: string
 kind:       "Deployment"
 metadata name: Name
 spec: {
  replicas: *1 | int
  selector matchLabels app: Name
  template: {
   metadata labels app: Name
   spec containers: [{name: Name}]
  }
 }
}
deployment "hello-kubernetes": {
 apiVersion: "apps/v1"
 spec: {
  replicas: 3
  template spec containers: [{
   image: "paulbouwer/hello-kubernetes:1.5"
   ports: [{
    containerPort: 8080
   }]
  }]
 }
}

在这里,我们创建了一个deployment可以重用的模板,然后使用它来定义一个名为的具体部署hello-kubernetes。注意事项:

  • apiersionstring在模板中指定为。如果省略或不是字符串,则CUE配置的评估将失败
  • replicas指定为默认值1或采用int
  • 部署的名称放置在名为的变量中,该变量Name随后用于填充元数据和标签

在上面这种简单的情况下,我们只有一个部署,这可能看起来有点多余。但是我们可以将模板重用于许多部署。这样就可以轻松地将属性注入所有类型,或者使某些属性成为必需的或有限的,甚至更多。编写YAML时,该语言只能看到任意数据,使用CUE可以引入语义,这意味着可以推理所用语言的配置。

我们可以评估稍微抽象一些的配置,并检查模板是否正常工作:

$ cue eval
{
    deployment "hello-kubernetes": {
        apiVersion: "apps/v1"
        kind:       "Deployment"
        metadata name: "hello-kubernetes"
        spec: {
            replicas: 3
            selector matchLabels app: "hello-kubernetes"
            template: {
                metadata labels app: "hello-kubernetes"
                spec containers: [{
                    name:  "hello-kubernetes"
                    image: "paulbouwer/hello-kubernetes:1.5"
                    ports: [{
                        containerPort: 8080
                    }]
                }]
            }
        }
    }
}

导出到JSON

如前所述,CUE是一种创作工具。它不打算直接替换JSONYAML或其他序列化格式。它支持导出到那些格式以供其他工具使用的概念。目前,CUE仅支持导出到JSON

$ cue export
{
  "deployment": {
    "hello-kubernetes": {
      "apiVersion": "apps/v1",
      "kind": "Deployment",
      "metadata": {
        "name": "hello-kubernetes"
       },
      "spec": {
        "replicas": 3,
          "selector": {
          "matchLabels": {
            "app": "hello-kubernetes"
          }
       },
       "template": {
         "metadata": {
           "labels": {
             "app": "hello-kubernetes"
           }
        },
        "spec": {
          "containers": [
            {
              "name": "hello-kubernetes",
              "image": "paulbouwer/hello-kubernetes:1.5",
              "ports": [
                {
                  "containerPort": 8080
                }
              ]
            }
          }
        }
      }
    }
  }
}

在这里使用一个简单的Kubernetes配置文件展示了CUE的基础知识。有机会接下来再介绍更多更完整的CUE功能。

a77cb97a2f9ed4d1e0335a778bff8242.png


欢迎关注我的公众号“互动云原生”,原创技术文章第一时间推送。

6708595b1a9daa025b2e802eaf22d23a.png

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐