Microservice Builder 输入规范

在本节中,我们将详细介绍用于创建和构建 UCS 微服务的 UCS Microservice Builder (msbuider) 工具的输入规范。

有关 UCS 微服务的更多信息,请参阅 - UCS 微服务

注意

可以使用以下命令为 msbuilder 生成模板输入目录 - 生成脚手架

输入目录结构

msbuilder 的典型输入目录结构包含

<msbuilder-input-directory>
  ├── changelog.txt
  ├── configs
  ├── containers
  │   └── cb_config.yaml
  ├── endpoints
  │   ├── http-api.yaml
  │   └── myservice-endpoint-name.yaml
  ├── LICENSE.txt
  ├── manifest.yaml
  ├── manual_compliance_test_results.yaml
  ├── README.md
  ├── scripts
  ├── tests
  │   └── dev
  │       ├── app.yaml
  │       └── params1.yaml
  └── values.yaml

当使用特定类型的 msbuilder 输入时,某些文件/目录不会被使用。以下各个部分将阐明文件/目录是否未使用。

Manifest 文件 - manifest.yaml

manifest 文件 manifest.yaml 包含用于描述微服务、helm chart 实现和容器构建配置详细信息的信息。

为三个用例生成的模板 manifest 略有不同。

以下是模板 manifest.yaml 文件的示例

type: msapplication
specVersion: 2.5.0
name: ucf.svc.myservice
chartName: myservice
description: default description
version: 0.0.1
tags: []
keywords: []

publish: false

egress-endpoints:
  - name: myservice-endpoint-name
    description: Short description of endpoint
    protocol: TCP # Or UDP
    scheme: asyncio # Or grpc / rtsp / asyncio / none
    mandatory: True # Or False
    data-flow: in-out # Or in or out

ingress-endpoints:
  - name: http-api
    description: Short description of http-api ingress endpoint
    scheme: http
    data-flow: in-out # Or in or out

secrets:
  - name: some-secret-name
    description: Description for the secret
    mandatory: True
    mountPath: /secrets
    fileName: someSecretFileName

params:
  stringToEcho: someString
  #> type: string
  #> enum_values: someString, someOtherString
  #> description: String to echo in init container
  timeToSleep: 1000000
  #> type: integer
  #> maximum: 2000000
  #> minimum: 1000000
  #> description: String to echo in init container
  #> flags: mandatory

# Files and directories will be mounted with prefix /opt/ext-files/
externalFiles:
- name: some-config.yaml # File will be available in containers at /opt/ext-files/some-config.yaml
  description: Some Configuration file
  mandatory: True
  isDirectory: False

tests:
  - name: dev-params1
    app: tests/dev/app.yaml
    params: tests/dev/params1.yaml
    ciTrigger: false
    timeout: 10
    duration: 10
    installPreReqs: true  # Wether to install foundational services
    namespace: default  # Kubernetes namespace
    gpuNodeLabels: ""
    watchAllPods: true # OR set to false and set list of pods to watch below
    watchPods:
    - <pod-name-regex>
    testerPods:  # At least one tester pod is required
    - name: testpod1  # Name of the test pod
      startSignature: <START>  # Signature to look for in the logs indicating start of tests. Regex is accepted
      endSignature: <END>  # Signature to look for in the logs indicating end of tests. Regex is accepted
      errorSignatures:  # Signatures that indicate test failures.  Regex is accepted
      - <REGEX1>
      - <REGEX2>


---
spec:
  - name: myservice-deployment
    type: ucf.k8s.app.deployment
    parameters:
      apptype: stateless

  - name: myservice-init-container
    type: ucf.k8s.initcontainer
    parameters:
      image: ubuntu
      imagePullPolicy: IfNotPresent
      args: [echo, $params.stringToEcho]
  - name: "myservice-container"
    type: ucf.k8s.container
    parameters:
      image:
        repository: ubuntu
        tag: "latest"
      command: ["sleep", "$params.timeToSleep"]
      ports:
      - containerPort: 0 # <PORT>
        name: http
      startupProbe:
        httpGet:
          path: /healthz
          port: http
        failureThreshold: 30
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz
          port: http
      readinessProbe:
        exec:
          command:
          - cat
          - /tmp/healthy
        initialDelaySeconds: 5
        periodSeconds: 5

  - name: myservice-service
    type: ucf.k8s.service
    parameters:
      annotations:
        test-svc-annotation: annotation-value
      labels:
        test-svc-label: label-value
      ports:
      - port: 0 # <OUT_PORT>
        name: http-api
      #externalTrafficPolicy: # Cluster / Local. Allowed when service type is NodePort or LoadBalancer

基本信息

下表列出了 manifest 文件中必须指定的基本信息。

字段

描述

specVersion

manifest / MS 遵循的 UCS MS 规范版本。当前 specVersion 为 2.5.0

name

微服务的唯一字符串标识符。必须以 ucf.svc. 前缀开头

chartName

微服务 helm chart 的唯一名称。必须遵循 https://helm.kubernetes.ac.cn/docs/chart_best_practices/conventions/#chart-names 的约定。如果使用预构建的 helm chart,则忽略此项

chart

预构建的 helm chart 的链接

description

微服务的简短描述

displayName

微服务的用户友好名称

category.functional

微服务的功能类别,例如数据库、视觉 AI 等

category.industry

微服务的行业类别,例如通用、零售、智能空间等

version

微服务版本。必须遵循语义版本控制 https://semver.org/

tags

用于对微服务进行分类的字符串列表

keywords

在搜索此微服务时可能有所帮助的字符串列表

Ingress 端点

Ingress 端点在 ingress-endpoints 字段下指定为列表。 Ingress 端点的属性为

字段

描述

name

Ingress 端点的字符串标识符

description

端点的简短描述

scheme

端点遵循的方案。为 httpgrpcrtspasyncioucxrespmongodb-wirenone 之一

data-flow

通过 egress 端点的数据流。为 inoutin-out 之一

service

端点的 Kubernetes 服务抽象名称。如果应从 ucf.k8s.service 组件推断,则可以跳过。 ingress 端点名称和 ucf.k8s.service 中的端口名称必须匹配。

port

Ingress 端点的端口号。如果应从 ucf.k8s.service 组件推断,则可以跳过。 ingress 端点名称和 ucf.k8s.service 中的端口名称必须匹配。

protocol

端点必须使用的网络协议。 TCPUDP。如果应从 ucf.k8s.service 组件推断,则可以跳过。 ingress 端点名称和 ucf.k8s.service 中的端口名称必须匹配。

有关端点的更多信息,请参阅 端点

Egress 端点

Egress 端点在 egress-endpoints 字段下指定为列表。 Egress 端点的属性为

字段

描述

name

Egress 端点的字符串标识符

description

端点的简短描述

protocol

端点必须使用的网络协议。 TCPUDP

scheme

端点遵循的方案。为 httpgrpcrtspasyncioucxrespmongodb-wirenone 之一

mandatory

布尔值,指示连接 egress 端点对于微服务正常工作是否是强制性的

data-flow

通过 egress 端点的数据流。为 inoutin-out 之一

multi

布尔值,指示 egress 端点是否可以连接到多个 ingress 端点。如果未指定,则假定为 false。

占位符 $egress.<egress-endpoint-name>.address$egress.<egress-endpoint-name>.port 可以在需要这些 egress 连接参数的地方使用。 这些占位符可以在 manifest.yamlspec 部分或 configs 目录中的文件中使用。 这些占位符将在应用程序构建期间被实际的 addressport 覆盖。

例如,microserviceServer 实现了一个 HTTP API 服务器,为其创建了一个名为 server-http-api-svc 和端口 8000 的 kubernetes 服务资源,并创建了一个名为 http-api 的相应 ingress 端点。

另一个 microserviceClient 包含一个 HTTP API 的客户端,并创建一个名为 http-api 的相应 egress 端点。 它在容器部分中指定了一个环境变量 SERVER_ENDPOINT,其值中包含占位符 http://$egress.http-api.address:$egress.http-api.port/,例如

# microserviceClient manifest.yaml
...
egress-endpoints:
  - name: myservice-endpoint-name
    description: Short description of endpoint
    protocol: TCP # Or UDP
    scheme: asyncio # Or grpc / rtsp / asyncio / none
    mandatory: True # Or False
    data-flow: in-out # Or in or out
...
spec:
- name: "client-container"
    type: ucf.k8s.container
    parameters:
      image:
        repository: client-container-repo
        tag: client-container-tag
      env:
      - name: SERVER_ENDPOINT
        value: http://$egress.http-api.address:$egress.http-api.port/

在 UCS 应用程序中,microserviceClienthttp-api egress 端点连接到 microserviceServerhttp-api egress 端点,然后在应用程序构建期间,所有出现的 $egress.http-api.address$egress.http-api.port 将分别被 server-http-api-svc8000 覆盖。 因此,microserviceClient 容器中的环境变量 SERVER_ENDPOINT 将设置为 http://server-http-api-svc:8000/

有关端点的更多信息,请参阅 端点

参数

微服务的参数可以在 params 字段下描述。 支持的参数类型包括 Boolean、数字和字符串等基本类型,以及列表和对象。 支持嵌套结构。

可以为参数提供默认值。 可以使用从参数后下一行开始的注释来注释参数。 这些行必须以 #> 前缀开头,后跟关键字和关键字的值。 示例

params:
  someParam: 100
  #> type: number
  #> description: Description for someParam
  #> minimum: 10
  #> maximum: 1000
  #> flags: mandatory
  someStringParam: someDefaultValue
  #> type: string
  #> description: Description for someStringParam
  #> enum_values: someDefaultValue, someOtherValue
  someObjectParam:
  #> type: object
  #> description: Description for someObjectParam
    someSubParamInSomeObjectParam: false
    #> type: boolean
    #> description: Description for someSubParamInSomeObjectParam

注释关键字支持的注释包括

关键字

描述

type

参数类型。 为 booleannumberintegerstringobjectarraynull 之一

description

参数的简短描述

minimum

如果参数类型为 number,则为允许的最小值

maximum

如果参数类型为 number,则为允许的最大值

enum_values

逗号分隔的允许值列表

flags

参数的逗号分隔的标志列表。 当前支持的标志为 mandatory

可以在 manifest.yamlconfigs 目录中的文件中使用 $params 占位符引用参数。 这些占位符将在应用程序构建时被用户设置的值或默认值覆盖。 示例

spec:
...
- name: app-container
  type: ucf.k8s.container
  parameters:
    ...
    env:
    - name: SOME_ENV_VAR
      value: $params.someObjectParam.someSubParamInSomeObjectParam

参数值也在微服务 helm chart 的值中设置。 因此,也可以使用 helm 模板引用它们。 示例

{{- if .Values.someObjectParam.someSubParamInSomeObjectParam }}
...
{{- end }}

密钥

微服务的密钥要求可以在 secrets 字段下描述。 密钥作为文件挂载在微服务容器内。

可以在 secrets 字段下添加密钥要求列表。 支持的属性包括

字段

描述

name

密钥的字符串标识符

description

密钥要求的简短描述

mountPath

微服务容器内用于挂载密钥文件的路径

fileName

挂载密钥文件时使用的文件名。 文件挂载在 <mountPath>/<fileName>

mandatory

布尔值,指示使用微服务的应用程序是否必须设置密钥

有关密钥在 UCS 中如何工作以及微服务和应用程序开发人员的要求的详细信息,请参阅 密钥管理

外部文件

微服务的外部文件要求可以在 externalFiles 字段下描述。 使用此功能,应用程序构建器可以在构建应用程序时将本地系统的整个文件/目录传递到微服务。 文件挂载在微服务容器内,前缀为 /opt/ext-files。 支持的属性包括

字段

描述

name

文件的名称。 预期文件挂载在 /opt/ext-files/<name>

description

预期文件及其内容的简短描述

mandatory

布尔值,指示使用微服务的应用程序是否必须设置文件

isDirectory

布尔值,指示微服务是否期望提供目录而不是文件

指标

有关微服务指标端点和微服务导出的指标的信息在 metrics 字段下描述为数组。

测试

微服务的测试可以在 tests 部分下指定。 测试基本上是为测试正在开发的微服务而定制的 UCS 应用程序。 构建微服务时,也会构建其测试应用程序。

可以通过部署测试应用程序 helm chart 在本地执行测试。

测试在 tests 部分下指定为列表。 测试支持的属性包括

字段

描述

name

测试应用程序的字符串标识符

app

UCS 应用程序图文件的路径。 可以指定为绝对路径或相对于 manifest.yaml 文件的路径

params

UCS 应用程序参数文件的路径,用于覆盖应用程序图文件中的参数。 可以指定为绝对路径或相对于 manifest.yaml 文件的路径

ciTrigger

布尔值,指示是否应将测试作为 UCS MS 验证的一部分执行

timeout

CI 管道将在此时之后停止测试,如果测试在此时间后未完成,则将其标记为失败。 值为分钟。 此参数适用于返回结果并在完成后停止的服务。

duration

CI 管道将在此时之后停止测试,并将测试标记为通过。 值为分钟。 此参数适用于不返回结果且不停止的服务。 它可用于测试特定服务是否可部署并在特定时间内运行。

installPreReqs

布尔值,指示是否必须在测试应用程序之前安装基础服务

namespace

用于安装测试应用程序 helm chart 的 Kubernetes 命名空间。 当前未使用

gpuNodeLabels

保留供将来使用

watchAllPods

布尔值,指示 CI 是否应监视所有 pod 以查找故障

watchPods

CI 应监视以查找故障的 pod 名称的正则表达式列表

testerPods

保留供将来使用

有关创建 UCS 应用程序的更多详细信息,请参阅 创建应用程序

Spec

微服务(即其 helm chart)的实现可以在 spec 字段下指定。 作为 UCS Microservice Builder Tool 的一部分,微服务实现必须使用可组合的组件完成。

当使用 预构建的 Helm Chart 时,必须省略此部分。 msbuilder 忽略此字段,因为它不构建微服务 helm chart。

组件

组件定义了微服务实现的一小部分,例如容器、服务、卷。

向 spec 添加组件

组件必须在 spec 下作为列表及其参数一起添加。 参数值必须遵循组件的参数模式,可以使用 component info 命令查看组件的参数模式,如上所示。 占位符 $params$egress$secrets 可以在参数值中使用,以分别引用参数、egress 端点和密钥。 这些占位符保留在构建的微服务 helm chart 中,但在应用程序构建期间被替换。

使用占位符添加组件的示例如下

spec:
  - name: myservice-deployment
    type: ucf.k8s.app.deployment
    parameters:
      apptype: stateless

  - name: "myservice-container"
    type: ucf.k8s.container
    parameters:
      image:
        repository: ubuntu
        tag: "latest"
      env:
      - name: HTTP_API_CA_CERT_PATH
        value: $secrets.ca-cert.path
      command: ["curl", "$egress.http-api.address:$egress.http-api.port",
        "--connect-timeout", $params.connectTimeout, "--cacert", $(HTTP_API_CA_CERT_PATH)]
      startupProbe:
        httpGet:
          path: /healthz
          port: http
        failureThreshold: 30
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz
          port: http
      readinessProbe:
        exec:
          command:
          - cat
          - /tmp/healthy
        initialDelaySeconds: 5
        periodSeconds: 5

注意

对于 spec 中定义的组件,参数必须遵循特定于每种类型的组件模式,如上所示。

在一个 yamldoc 中只能指定一种工作负载类型(例如 statelessstatefuljobcronjobdaemonsetstatic-pod)。 要向微服务添加多种工作负载类型(例如,两个 stateless(即 Deployment

---
spec:
- name: app-deployment-1
  type: ucf.k8s.app.deployment
  parameters:
    apptype: stateless
...
---
spec:
- name: app-deployment-2
  type: ucf.k8s.app.deployment
  parameters:
    apptype: stateless
...

Configs 目录 - configs

此目录可用于为微服务添加任何配置文件。 添加到此目录的文件会自动添加到 configmap,并挂载在作为微服务一部分的容器中的 /opt/configs 目录下。

在此目录中使用的文件可以包含 $params$egress$secrets 占位符。 当应用程序构建和部署时,这些占位符以及 /opt/configs 目录下挂载的文件中的占位符将被替换为实际值。

例如,configs 目录中名为 app_cfg.yaml 的文件将挂载在作为微服务一部分的容器中的 /opt/configs/app_cfg.yaml,占位符已更新为实际值。

当使用 预构建的 Helm Chart 时,使用此目录中的文件。

Scripts 目录 - scripts

此目录可用于为微服务内运行的应用程序添加任何脚本文件。 添加到此目录的文件会自动添加到 configmap,并挂载在作为微服务一部分的容器中的 /opt/scripts 目录下。

添加到此目录内的文件中的占位符 $params$egress$secrets被替换。

例如,scripts 目录中名为 run.sh 的文件将挂载在作为微服务一部分的容器中的 /opt/scripts/run.sh,内容完全相同。

当使用 预构建的 Helm Chart 时,使用此目录中的文件。

Container Configs 目录 - containers

此目录包含微服务使用的容器的 容器构建 配置文件。 容器在 微服务构建 期间使用这些配置文件构建。

这些配置文件遵循 容器构建 配置规范。 必须为要构建的每个容器创建一个单独的文件。 文件名没有限制。

当使用 预构建的 Helm Chart 或使用 预构建的容器镜像 时,使用此目录中的文件。

Endpoint Definition Files 目录 - endpoints

此目录包含微服务中每个 IngressEgress 端点的端点定义文件。 预期的文件名是 <endpoint-name>.<ext>。 文件扩展名取决于端点的方案。

端点定义文件不是构建微服务的强制性要求,但对于完全符合 UCS 标准的微服务是必需的。

有关端点和端点定义文件的更多信息,请参阅 端点

Customized Helm Template 目录 - templates

用户可以将自定义的 Helm 模板 yaml 文件放在此处,它们将原样复制到最终的 Helm 模板文件夹。

Manual Compliance Test Results - manual_compliance_test_results.yaml

UCS 微服务合规性要求微服务开发人员手动运行一些测试。 测试结果可以使用 manual_compliance_test_results.yaml 输入文件提供。

文件的预期格式是 <compliance-id>: <result-as-boolean> 的映射。 文件内容的示例

DEV-005: false
DEV-011: false
DEV-014: false
DEV-017: false
DEV-018: false
DEV-019: false
DEV-020: false
DEV-101: false

有关 UCS 微服务合规性和手动合规性检查的更多信息,请参阅 UCS 微服务合规性

文档 - README.md

微服务的详细文档必须添加到 README.md。 它必须采用特定格式,并且需要包含一系列章节。 这些章节包括

  • 描述 - 微服务、功能、特性的详细描述

  • 用法 - 有关在应用程序中使用微服务的详细信息,例如无法添加到 manifest 的任何参数/端点详细信息、有关向应用程序添加微服务及其连接的示例。

  • 性能/KPI - 有关预期性能/KPI 的详细信息

  • 支持的平台 - 有关支持的平台/GPU 的信息

  • 部署要求 - 部署要求,例如 CPU/内存/NIC/节点主机配置

  • 许可证 - 微服务使用的许可证

  • 已知问题/限制 - 已知问题、限制和解决方法列表

  • 参考 - 参考/有用的链接,例如 GitHub 上的示例应用程序、使用的 SDK、进一步阅读。

注意

可以使用 service create 命令创建模板 README.md。 请参阅 生成脚手架

许可证 - LICENSE.txt

微服务中使用的第三方软件的许可证

Changelog - changelog.txt

此文件必须包含当前版本的微服务的变更日志。

Tests 目录 - tests

此目录包含微服务的测试应用程序。 应用程序必须符合 UCS 应用程序 规范。 这些测试应用程序与微服务一起构建。

Values 文件 values.yaml

此文件仅在使用 预构建的 Helm Chart 时使用。

它采用标准 Helm values.yaml 的形式,并包含必须覆盖的预构建 helm chart 的值。 该文件可以包含 $params$egress$secrets 占位符,这些占位符将在应用程序构建和部署时被实际值替换。