服务规范参考

要查看 Snowpark Container Services 规范,请参阅 YAML (` https://yaml.org/spec/ (https://yaml.org/spec/) <https://yaml.org/spec/ (https://yaml.org/spec/)>`_)。它为 Snowflake 提供了配置和运行服务所需的信息。

一般语法为:

spec:
  containers:                           # container list
  - name: <name>
    image: <image-name>
    command:                            # optional list of strings
      - <cmd>
      - <arg1>
    args:                               # optional list of strings
      - <arg2>
      - <arg3>
      - ...
    env:                                # optional
        <key>: <value>
        <key>: <value>
        ...
    readinessProbe:                     # optional
        port: <TCP port-num>
        path: <http-path>
    volumeMounts:                       # optional list
      - name: <volume-name>
        mountPath: <mount-path>
      - name: <volume-name>
        ...
    resources:                          # optional
        requests:
          memory: <amount-of-memory>
          nvidia.com/gpu: <count>
          cpu: <cpu-units>
        limits:
          memory: <amount-of-memory>
          nvidia.com/gpu: <count>
          cpu: <cpu-units>
    secrets:                            # optional list
      - snowflakeSecret:
        secretKeyRef:
        envVarName:                      # specify this or directoryPath
        directoryPath:                   # specify this or envVarName
  endpoints:                             # optional endpoint list
    - name: <name>
      port: <TCP port-num>
      public: <true / false>
      protocol : < TCP / HTTP / HTTPS >
    - name: <name>
      ...
  volumes:                               # optional volume list
    - name: <name>
      source: local | @<stagename> | memory | block
      size: <bytes-of-storage>           # specify if memory or block is the volume source
      blockConfig:                       # optional
        initialContents:
          fromSnapshot: <snapshot-name>
      uid: <UID-value>                   # optional, only for stage volumes
      gid: <GID-value>                   # optional, only for stage volumes
    - name: <name>
      source: local | @<stagename> | memory | block
      size: <bytes-of-storage>           # specify if memory or block is the volume source
      ...
  logExporters:
    eventTableConfig:
      logLevel: <INFO | ERROR | NONE>
serviceRoles:                   # Optional list of service roles
- name: <service-role-name>
  endpoints:
  - <endpoint_name1>
  - <endpoint_name2>
  - ...
- ...
Copy

一般准则

服务规范具有以下这些顶级 spec 字段:

  • spec.containers (必填):一个或多个应用程序容器的列表。容器化应用程序必须至少有一个容器。

  • spec.endpoints (可选):服务显示的端点列表。您可选择将端点设为公开,以允许网络入口访问该服务。

  • spec.volumes (可选):供容器使用的存储卷列表。

  • spec.logExporters (可选):此字段管理导出到您账户中的事件表的容器日志级别。

以下格式准则适用于 name 字段(容器、端点和卷名称):

  • 最多可包含 63 个字符

  • 可包含一串小写字母数字或“-”字符

  • 必须以字母字符开头

  • 必须以字母数字字符结尾

注意

客户应确保没有个人数据、敏感数据、出口控制数据或其他受监管数据作为元数据输入规范文件。有关更多信息,请参阅 Snowflake 中的元数据字段

以下各节介绍了每个顶级 spec 字段。

spec.containers 字段(必填)

containers 字段是您应用程序中 ` OCI <https://opencontainers.org/ (https://opencontainers.org/)> _ 容器的列表。对于每个容器,仅 :code:`nameimage 为必填字段。image 字段是指您上传到 Snowflake 账户中的 Snowflake 镜像仓库中镜像的名称。例如:

spec:
  containers:
    - name: echo
      image: /tutorial_db/data_schema/tutorial_repository/echo_service:dev
Copy

当您创建服务(包括作业服务)时,Snowflake 会在指定计算池中的单个节点上运行这些容器,共享相同的网络接口。您可运行多个服务实例;在这种情况下,正在运行的这些容器中的每一组都称为一个服务实例。

备注

目前,Snowpark Container Services 需要 linux/amd64 平台镜像。

以下各节介绍了 containers 字段的类型。

containers.commandcontainers.args 字段

使用这些可选字段来替换在 Dockerfile (应用程序镜像的一部分)中定义的容器的入口点(容器与任何参数一起运行的命令),而无需重新创建应用程序镜像:

  • containers.command 可替换 Dockerfile ENTRYPOINT。这允许您在容器中运行不同的可执行文件。

  • containers.args 可替换 Dockerfile CMD。这允许您为命令(可执行文件)提供不同的实参。

示例

Dockerfile 包括以下代码:

ENTRYPOINT ["python3", "main.py"]
CMD ["Bob"]
Copy

这些 Dockerfile 条目执行 python3 命令并传递两个实参:main.pyBob。您可按如下方式替换规范文件中的这些值:

  • 要替换 ENTRYPOINT,请在规范文件中添加 containers.command 字段:

    spec:
      containers:
      - name: echo
        image: <image_name>
        command:
        - python3.9
        - main.py
    
    Copy
  • 要替换实参“Bob”,请在规范文件中添加 containers.args 字段:

    spec:
      containers:
      - name: echo
        image: <image_name>
        args:
          - Alice
    
    Copy

containers.env 字段

使用 containers.env 字段来指定传递给容器中所有进程的环境变量:

spec:
  containers:
  - name: <name>
    image: <image_name>
    env:
      ENV_VARIABLE_1: <value1>
      ENV_VARIABLE_2: <value2>
      
      
Copy

示例

教程 1 中,如未显式设置环境变量的值,则应用程序代码 (echo_service.py) 将读取其默认值。

CHARACTER_NAME = os.getenv('CHARACTER_NAME', 'I')
SERVER_PORT = os.getenv('SERVER_PORT', 8080)
Copy
  • CHARACTER_NAME:当 Echo 服务收到带字符串(例如,“Hello”)的 HTTP POST 请求时,服务默认返回“I said Hello”。 您可在规范文件中覆盖此默认值。例如,将值设置为“Bob”,则 Echo 服务会返回“Bob said Hello”的响应。

  • SERVER_PORT:在此默认配置中,Echo 服务监听端口 8080。您可以替换该默认值并指定另一端口。

以下规范文件将替换这两个环境变量值:

spec:
  containers:
  - name: echo
    image: <image_name>
    env:
      CHARACTER_NAME: Bob
      SERVER_PORT: 8085
  endpoints:
  - name: echo-endpoint
    port: 8085
Copy

请注意,由于您更改了服务监听的端口号,因此在规范中也更新了端点(endpoints.port 字段值)。

containers.readinessProbe 字段

在您的应用程序中使用 containers.readinessProbe 对象为 Snowflake 提供就绪情况探测。Snowflake 调用此探测以确定应用程序何时准备好处理请求。

Snowflake 在指定的端口和路径上向指定的就绪情况探测发出 HTTP GET 请求,并查找您的服务以返回 HTTP 200 OK 状态,以确保只有正常运行的容器才能提供流量。

使用以下字段提供所需信息:

  • port:服务正在监听就绪情况探测请求的网络端口。您无需将此端口声明为端点。

  • path:Snowflake 使用此路径向服务发出 HTTP GET 请求。

示例

在教程 1 中,应用程序代码 (echo_python.py) 实现以下就绪情况探测:

@app.get("/healthcheck")
def readiness_probe():
Copy

因此,规范文件包括 containers.readinessProbe 字段:

spec:
  containers:
  - name: echo
    image: <image_name>
    env:
      SERVER_PORT: 8088
      CHARACTER_NAME: Bob
    readinessProbe:
      port: 8088
      path: /healthcheck
  endpoints:
  - name: echo-endpoint
    port: 8088
Copy

就绪情况探测指定的端口可以不是已配置的端点。服务可以仅出于就绪情况探测的目的来监听不同的端口。

containers.volumeMounts 字段

因为 spec.volumesspec.containers.volumeMounts 字段是一起使用的,所以将在一个小节中一起介绍它们。有关更多信息,请参阅 spec.volumes 字段(可选)

containers.resources 字段

Snowflake 确定如何使用可用的计算池资源来运行应用程序。建议您在规范中明确指出服务实例的资源需求,并设置适当的限制。请注意,您指定的资源受到计算池中节点的实例系列的约束。有关更多信息,请参阅 CREATE COMPUTE POOL

Snowflake 确保提供 containers.resources.requests 指定的资源,并防止服务使用超过指定数目的 containers.resources.limits。您可以为以下资源指定请求和限制:

  • memory:这是应用程序容器所需的内存。您可以使用小数或二进制单位来表示值。例如,2G 表示 2,000,000,000 字节的请求。指定内存时,单位是必填项。例如,100M5Gi。支持的单位有:M、Mi、G、Gi。有关更多信息,请参阅 关于单位

  • cpu:这是指虚拟核心 (vCPU) 单位。例如,1 个 CPU 单位相当于 1 个 vCPU。允许小数请求,例如 0.5,也可表示为 500m。有关更多信息,请参阅 关于单位

  • nvidia.com/gpu:如果需要 GPUs,则必须请求它们,并且对于相同的数量也必须指定 limit。如果容器未指定 GPU 容量的请求和限制,则它无法访问任何 GPUs。您可请求的 GPUs 的数量受您在创建计算池时所选择的 INSTANCE_TYPE 所支持的最大 GPUs 数量的限制。有关更多信息,请参阅 CREATE COMPUTE POOL

如果 Snowflake 无法分配规范文件中明确包含的资源,您可创建服务(使用 CREATE SERVICE),但服务状态会显示:由于资源不足,无法安排服务。

示例 1

在以下规范中,containers.resources 字段描述容器的资源需求:

spec:
  containers:
  - name: resource-test-gpu
    image: ...
    resources:
      requests:
        memory: 2G
        cpu: 0.5
        nvidia.com/gpu: 1
      limits:
        memory: 4G
        nvidia.com/gpu: 1
Copy

在此示例中,要求 Snowflake 为容器至少分配 2 个 GB 内存,1 个 GPU 和 0.5 个 CPU 核心。同时,不允许容器使用超过 4 个 GB 内存和 1 个 GPU。

示例 2

  • 创建包含两个节点的计算池;每个节点有 16 个 GB 内存和 1 个 GPU:

    CREATE COMPUTE POOL tutorial_compute_pool
      MIN_NODES = 2
      MAX_NODES = 2
      INSTANCE_FAMILY = gpu_nv_s
    
    Copy
  • 您创建一个服务,该服务要求 Snowflake 运行该服务的两个实例:

    CREATE SERVICE echo_service
      MIN_INSTANCES=2
      MAX_INSTANCES=2
      IN COMPUTE POOL tutorial_compute_pool
      FROM @<stage_path>
      SPEC=<spec-file-stage-path>;
    
    Copy

    MIN_INSTANCESMAX_INSTANCES 均设置为 2。因此,Snowflake 将运行该服务的两个实例。

如果未在应用程序规范中明确包含资源需求,那么 Snowflake 将决定是在计算池中的同一节点还是不同节点上运行这些实例。

  • 您确实需要包括资源需求,并为容器请求 10 个 GB 内存:

    - name: resource-test
      image: ...
      resources:
        requests:
          memory: 10G
    
    Copy

    计算池节点有 16 个 GB 内存,并且 Snowflake 无法在同一节点上运行两个容器。Snowflake 将在计算池中的不同节点上运行这两个服务实例。

  • 为容器请求 1 个 GB 内存和 1 个 GPU:

    spec:
      containers:
      - name: resource-test-gpu
        image: ...
        resources:
          requests:
            memory: 2G
            nvidia.com/gpu: 1
          limits:
            nvidia.com/gpu: 1
    
    Copy

    您正在为每个容器请求 1 个 GPU,并且每个节点只有 1 个 GPU。在这种情况下,尽管内存不是问题,但 Snowflake 无法在一个节点上安排这两项服务。此需求迫使 Snowflake 在两个单独的计算池节点上运行两个服务实例。

containers.secrets 字段

secrets:                            # optional list
  - snowflakeSecret:
    secretKeyRef:
    envVarName:                      # specify this or directoryPath
    directoryPath:                   # specify this or envVarName
Copy

使用 containers.secrets密钥 对象提供给Snowflake,当服务与外部端点(在Snowflake 之外)通信时,容器可使用这些对象进行身份验证。有关更多信息,请参阅 使用 Snowflake 密钥将凭据传递到容器

  • snowflakeSecret (必填):Snowflake :doc:` 密钥 </sql-reference/sql/create-secret>` 对象名称。

  • secretKeyRef:密钥中密钥的名称。提供此字段后,Snowflake 会将与此键引用关联的值传递给容器。这对于作为环境变量挂载的基本身份验证密钥是必填项。仅当将密钥传递给容器中的环境变量时,才指定此字段。

  • envVarName:保存密钥的环境变量的名称。此字段或 directoryPath 字段为必填项。

  • directoryPath:容器中要复制密钥的目录路径。Snowflake 为此指定目录中的每个密钥填充一个文件。当您指定 directoryPath 时,请勿指定 secretKeyRef。此字段或 envVarName 字段为必填项。

有关更多信息,请参阅 将 Snowflake 密钥传递到容器中

spec.endpoints 字段(可选)

使用 spec.endpoints 字段指定应用程序显示的 TCP 网络端口的名称列表。Snowpark Container Services 可能会向多个端点显示为零。使用以下字段描述端点:

  • name:端点的唯一名称。在服务函数中引用端点时,请指定其名称。

  • port:应用程序正在监听的网络端口。

  • protocol:端点支持的协议。支持的值为:TCP、HTTP 和 HTTPS。默认情况下,该协议为 HTTP。当此端点是公共的或某一服务功能的目标时,该协议必须为 HTTP 或 HTTPS(请参阅 使用服务)。作业服务要求所有指定的端点使用 TCP 协议;不支持 HTTP/HTTPS 协议。

  • public:如果您希望可以从 Internet 访问此端点,请将此字段设置为 true。TCP 协议不支持公共端点。

备注

Snowflake 对公共访问执行身份验证和授权检查,只允许有权限的 Snowflake 用户使用该服务。

示例

以下是 教程 1 中使用的应用程序规范:

spec:
  container:
  - name: echo
    image: <image-name>
    env:
      SERVER_PORT: 8000
      CHARACTER_NAME: Bob
    readinessProbe:
      port: 8000
      path: /healthcheck
  endpoint:
  - name: echoendpoint
    port: 8000
    public: true
Copy

此应用程序容器显示一个端点。它还包括一个可选的 public 字段,允许从 Snowflake 外部访问端点(互联网访问)。默认情况下,publicfalse

spec.volumes 字段(可选)

本节将介绍 spec.volumesspec.containers.volumeMounts 规范字段,因为它们密切相关。

  • spec.volumes 定义共享文件系统,即容器可用的卷。

  • spec.containers.volumeMount 定义卷在特定容器中显示的位置。

在规范中,volumes 字段在 spec 级别指定,但由于多个容器可共享相同的卷,所以 volumeMounts 成为 spec.containers 级别的字段。

使用这些字段来描述卷和卷挂载。

  • 使用 spec.volumes 指定可用于容器的卷。volumes 是一个列表。也就是说,可以存在多个卷。使用以下字段描述卷:

    • name:卷的唯一名称。该名称请参考 spec.containers.volumeMounts.name

    • source:这可以是 localmemoryblock"@<stagename>"。下一节将介绍这些卷类型。

    • size:对于内存卷和块卷,这是以字节为单位的卷的大小。对于块存储,该值必须始终是一个整型,使用 Gi 单位后缀指定。例如,5Gi 表示 5*1024*1024*1024 个字节。

    • blockConfig:对于 block 类型的卷,如果您希望使用先前获取的另一个卷的快照初始化块卷,请指定此可选字段。有关更多信息,请参阅 在服务规范中指定块存储

  • 使用 spec.containers.volumeMounts 指示指定卷在容器文件系统中的挂载位置。containers.volumeMounts 也是一个列表。也就是说,每个容器可以有多个卷挂载。使用以下字段来描述卷装载:

    • name:要挂载的卷的名称。单个容器可以多次引用同一卷。

    • mountPath:容器中应挂载的卷的文件路径。

关于支持的卷类型

Snowflake 支持应用程序容器使用以下这些卷类型:本地、内存、块和 Snowflake 暂存区。

  • 本地卷: 服务实例中的容器可使用本地磁盘来共享文件。例如,如果应用程序有两个容器 – 一个应用程序容器和一个日志分析器,则应用程序可将日志写入本地卷,而日志分析器可读取日志。

    请注意,如果您正在运行一个服务的多个实例,则只有属于一个服务实例的容器才能共享卷。属于不同服务实例的容器不共享卷。

  • 内存: 您可以使用 RAM 支持的文件系统供容器使用。

  • 块: 容器也可以使用块存储卷。大小值可以介于 1Gi16384Gi 之间。有关更多信息,请参阅 将块存储卷与服务一起使用

  • Snowflake 暂存区: 您可以创建一个 Snowflake 暂存区,并让容器可以很方便地访问暂存文件。挂载 Snowflake 暂存区时,以下条件适用:

    • 不支持外部暂存区。只支持使用 SSE 加密的 Snowflake 内部暂存区(请参阅 内部暂存区参数)。要使用 CREATE STAGE 创建这样的暂存区,请执行以下操作:

      CREATE STAGE my_stage ENCRYPTION = (type = 'SNOWFLAKE_SSE');
      
      Copy
    • 您可以在一个暂存区内挂载一个暂存区或一个子目录,例如 @my_stage@my_stage/folder。您无法在暂存区内挂载一个文件,例如 @my_stage/folder/file

    • 服务角色确定授予容器访问已挂载暂存区的权限。服务角色是用于创建服务的角色。它也是服务用于所有 Snowflake 交互的角色。

      例如,如果服务角色在某个暂存区没有 WRITE 权限,则该暂存区的挂载将为只读。也就是说,容器只能从暂存区读取文件。如果服务角色在某个暂存区确实具有 WRITE 权限,则该暂存区的挂载将同时支持读取和写入。Snowflake 异步上传文件更新。

    • 挂载 Snowflake 暂存区的容器通常以根用户身份运行。但是,有时您的容器可能会以非根用户身份运行。例如:

      • 如果应用程序使用第三方库,则该库将使用非根用户在容器内运行应用程序代码。

      • 出于安全性等其他原因,您可以在容器内以非根用户身份运行应用程序。

        为避免与文件用户权限相关的潜在错误,将容器的 UID(用户 ID)和 GID(组 ID)设置为规范的一部分非常重要。这对于使用特定用户和组在容器内启动或运行应用程序的容器来说,这一点尤为重要。通过设置适当的 UID 和 GID,您可以使用以非根用户身份运行的容器。例如:

        spec:
          ...
        
          volumes:
          - name: stagemount
            source: "@test"
            uid: <UID-value>
            gid: <GID-value>
        
        Copy

        Snowflake 使用此信息以适当的权限挂载暂存区。

        要获取容器的 UID 和 GID,请执行以下操作:

        1. 使用 docker run 在本地运行容器。

        2. 使用 docker container list 命令查找容器 ID。部分样本输出:

          CONTAINER ID   IMAGE                       COMMAND
          —----------------------------------------------------------
          a6a1f1fe204d  tutorial-image         "/usr/local/bin/entr…"
          
        3. 在容器内运行 docker id 命令来获取 UID 和 GID:

          docker exec -it <container-id> id
          
          Copy

          示例输出:

          uid=0(root) gid=0(root) groups=0(root)
          

示例

机器学习应用程序包括以下两个容器:

  • 一个适用于主应用程序的 app 容器

  • 一个收集日志并将其上传到 Amazon S3 的 logger-agent 容器

这些容器使用以下两个卷:

  • local 卷:此应用程序写入日志代理读取的日志。

  • Snowflake 暂存区 – @model_stage:主应用程序从此暂存区中读取文件。

在以下示例规范中,app 容器挂载 logsmodels 两个卷,而 logging-agent 容器仅挂载 logs 卷:

spec:
  containers:
  - name: app
    image: <image1-name>
    volumeMounts:
    - name: logs
      mountPath: /opt/app/logs
    - name: models
      mountPath: /opt/models
  - name: logging-agent
    image: <image2-name>
    volumeMounts:
    - name: logs
      mountPath: /opt/logs
  volumes:
  - name: logs
    source: local
  - name: models
    source: "@model_stage"
Copy

如果服务的多个实例正在运行,则一个服务实例中的 logging-agentapp 容器共享 logs 卷。logs 卷不在服务实例之间共享。

如果除这些卷之外,您的 app 容器还使用一个 2-GB 内存的卷,请修改规范,以将该卷包含在 volumes 列表中,并在 app 容器 volumeMounts 列表中添加另一个卷挂载:

spec:
  containers:
  - name: app
    image: <image1-name>
    volumeMounts:
    - name: logs
      mountPath: /opt/app/logs
    - name: models
      mountPath: /opt/models
    - name: my-mem-volume
      mountPath: /dev/shm
  - name: logging-agent
    image: <image2-name>
    volumeMounts:
    - name: logs
      mountPath: /opt/logs
  volumes:
  - name: logs
    source: local
  - name: models
    source: "@model_stage"
  - name: "my-mem-volume"
    source: memory
    size: 2G
Copy

请注意,当您指定 memory 作为卷 source 时,您还必须指定 volumes.size 字段来表示内存大小。有关您可以指定的内存大小单位的信息,请参阅 关于单位

spec.logExporters 字段(可选)

使用 spec.logExporters 配置 Snowflake 收集应用程序日志的方式。 Snowflake 将应用程序容器中代码的输出收集为标准输出或标准错误。

Snowflake 将这些日志导出到您账户中的 事件表 中。有关更多信息,请参阅 访问本地容器日志。要使用 spec.logExporters.eventTableConfig 来指示您想要保存到事件表中的日志,请执行以下操作:

logExporters:
  eventTableConfig:
    logLevel: < INFO | ERROR | NONE >
Copy

支持的 logLevel 值为:

  • :code:`INFO`(默认):导出所有用户日志。

  • ERROR:仅导出错误日志。Snowflake 仅导出标准错误 (stderr) 流中的日志。

  • NONE:不将日志导出到事件表中。

关于单位

服务规范在多个地方采用数值。Snowpark Container Services 支持各种单元来表示这些值。对于大值和小值,您可使用二进制和十进制单位,如下所示。在以下列表中,“#”表示整数值。

  • 二进制单位:

    • numberKi 表示 number*1024。 例如,4Ki 等于 4096。

    • numberMi 表示 number*1024^2

    • numberGi 表示 number*1024^3

  • 十进制单位:

    • numberk 表示 number*10^3。例如,4k 等于 4000。

    • numberM 表示 number*10^6

    • numberG 表示 number*10^9

  • 小数单位:

    • numberm 表示 number*0.001。例如,cpu: 500m 相当于 cpu: 0.5

serviceRoles 字段(可选)

使用规范中的 serviceRoles 顶级字段来定义一个或多个服务角色。对于每个服务角色,提供您希望服务角色授予 USAGE 权限的一个或多个端点的名称和列表(在 spec.endpoints 中定义)。

serviceRoles:                   # Optional list of service roles
- name: <name>
  endpoints:
  - <endpoint-name>
  - <endpoint-name>
  - ...
- ...
Copy

请注意以下事项:

  • nameendpoints 都是必填项。

  • 服务角色名称须遵循以下格式:

    • 必须包含字母数字或 _ 字符。

    • 必须以字母字符开头。

    • 必须以字母数字字符结尾。

有关更多信息,请参阅 管理对服务端点的访问

语言: 中文