教程 3:创建和管理 Snowpark 容器服务

简介

Snowpark Container Services 是一种完全托管式容器服务,旨在促进 Snowflake 生态系统中容器化应用程序的部署、管理和扩展。您可以利用此功能,直接在 Snowflake 中运行容器化工作负载。

在本教程中,您将学习如何在 Snowpark Container Services 中使用 Snowflake Python APIs 管理组件。

重要

Snowpark Container Services Snowflake 账户通常可在 AWS 中使用。针对 Azure 中的账户提供了 预览版支持。有关详细信息,请参阅 Snowpark Container Services – 可用区域

先决条件

在开始本教程之前,您必须完成以下步骤:

  1. 安装 Docker Desktop。

    本教程提供的说明需要用到 Docker Desktop。有关安装说明,请参阅 ` <https://docs.docker.com/get-docker/ (https://docs.docker.com/get-docker/)> `_ 。

  2. 根据 常见设置 说明操作,其中包括以下步骤:

    • 设置开发环境。

    • 安装 Snowflake Python APIs 包。

    • 配置 Snowflake 连接。

    • 导入 Python API 教程所需的所有模块。

    • 创建一个 API Root 对象。

    备注

    如果您已经完成了 常见设置,则可以跳过此步骤并开始教程。

满足这些先决条件后,即可开始使用 API 管理 Snowpark Container Services。

设置开发环境

如果您在之前的 Snowflake Python APIs 教程中使用的是笔记本,在本教程中可以切换到新的笔记本。笔记本将包含使用 Snowpark Container Services 运行 NGINX Web 服务器的示例代码,所有这些都在 Snowflake 中运行。

  1. 使用您喜爱的代码编辑器或运行 jupyter notebook 命令打开一个新笔记本。

  2. 在笔记本的第一个单元格中运行以下代码:

    from snowflake.core.database import Database
    from snowflake.core.schema import Schema
    
    database = root.databases.create(Database(name="spcs_python_api_db"), mode="orreplace")
    schema = database.schemas.create(Schema(name="public"), mode="orreplace")
    
    Copy

    使用 Snowflake 连接和您先前在 常见设置 中创建的 root 对象,创建一个名为 spcs_python_api_db 的数据库,并在该数据库中创建一个名为 public 的架构。您还要保存代表这些新创建的对象的引用。您的 Snowpark Container Services 组件将存在于此数据库和架构中。

Snowpark Container Services 概述

在继续本教程之前,简要回顾一下 Snowpark Container Services 的主要组件。若要在 Snowpark Container Services 中运行容器化应用程序,您通常要使用以下对象:

  • 镜像仓库:提供一个存储单元,您可以在自己的 Snowflake 账户中将应用程序镜像上传到这个存储单元中。

    Snowpark Container Services 提供了一个符合 OCIv2 标准的镜像注册表服务,让 OCI 客户端(例如 Docker CLI 和 SnowSQL)可以访问您的 Snowflake 账户中的镜像注册表。使用这些客户端,您可以将应用程序镜像上传到仓库中。

    有关更多信息,请参阅 使用镜像注册表和镜像仓库

  • 计算池:表示一组计算资源(虚拟机节点)。

    这些计算资源与 Snowflake 虚拟仓库相似,但并非完全相同。服务(在本例中是您的 NGINX 服务)将在计算池中运行。计算密集型服务需要具有大量核心和大量 GPUs 的高算力计算尺,而密集度较低的服务则可以在具有较少核心的较小计算池中运行。

    有关更多信息,请参阅 使用计算池

  • 服务:提供了一种运行应用程序容器的途径。

    服务至少需要具备一个规范和一个计算池。规范包含运行应用程序容器所需的信息,例如容器镜像的路径,以及服务将会公开的端点。规范使用 YAML 编写。计算池是服务将在其中运行的一组计算资源。

    有关更多信息,请参阅 使用服务

继续进入下一步,以创建和设置这些对象。

创建镜像仓库

在本节中,首先使用 Snowflake Python APIs 创建一个镜像仓库。然后您要从 Docker Hub 提取一个 NGINX 应用程序镜像,并使用 Docker CLI 将镜像上传到镜像仓库。

创建仓库并获取与其相关的信息

  1. 在笔记本的下一个单元格中,运行以下代码:

    from snowflake.core.image_repository import ImageRepository
    
    my_repo = ImageRepository("MyImageRepository")
    schema.image_repositories.create(my_repo)
    
    Copy

    在此代码示例中,您将在本教程中前面创建的数据库和架构中创建一个镜像仓库。

  2. 要通过提取仓库的详细信息并输出其名称来确认仓库已成功创建,请运行以下代码:

    my_repo_res = schema.image_repositories["MyImageRepository"]
    my_repo = my_repo_res.fetch()
    print(my_repo.name)
    
    Copy
  3. 您需要有关仓库(仓库 URL 和注册表主机名)的信息,才能构建和上传镜像。

    要获取存储库 URL,请在下一个单元格中,运行以下代码:

    repositories = schema.image_repositories
      for repo_obj in repositories.iter():
        print(repo_obj.repository_url)
    
    Copy
    • 输出中的 repository_url 属性提供了 URL。例如:

      <orgname>-<acctname>.registry.snowflakecomputing.cn/spcs_python_api_db/public/myimagerepository
      
    • 仓库 URL 中的主机名为注册表主机名。例如:

      <orgname>-<acctname>.registry.snowflakecomputing.cn
      

提取 NGINX 镜像并将其上传到仓库

  1. 要让 Docker 代表您将镜像上传到仓库,您必须首先使用 Snowflake 对 Docker 进行身份验证。

    要使用 Snowflake 注册表对 Docker 进行身份验证,请打开命令行终端,并使用 Docker 命令 CLI 运行以下 docker login 命令:

    docker login <registry_hostname> -u <username>
    
    Copy
    • registry_hostname:指定来自上一步结果中 repository_url 的主机名。

    • username:指定您的 Snowflake 用户名。Docker 将提示您输入密码。

    示例

    docker login myorg-myacct.registry.snowflakecomputing.cn -u admin
    
    Copy
  2. 提取 Docker Hub 中 NGINX 镜像 (https://hub.docker.com/r/amd64/nginx/) 的 AMD64 内部版本:

    docker pull --platform linux/amd64 amd64/nginx
    
    Copy
  3. 使用 Snowflake 镜像仓库 URL 标记 amd64/nginx 镜像:

    docker tag docker.io/amd64/nginx:latest <repository_url>/<image_name>
    
    Copy

    示例

    docker tag docker.io/amd64/nginx:latest myorg-myacct.registry.snowflakecomputing.cn/spcs_python_api_db/public/myimagerepository/amd64/nginx:latest
    
    Copy

    标记是一种自定义的、人类可读的标识符,您可以选择使用它来识别镜像的特定版本或变体。

  4. 将镜像上传到 Snowflake 账户中的仓库:

    docker push <repository_url>/<image_name>
    
    Copy

    示例

    docker push myorg-myacct.registry.snowflakecomputing.cn/spcs_python_api_db/public/myimagerepository/amd64/nginx:latest
    
    Copy

创建计算池

要定义和创建计算池,在笔记本的下一个单元格中,运行以下代码:

new_compute_pool_def = ComputePool(
    name="MyComputePool",
    instance_family="CPU_X64_XS",
    min_nodes=1,
    max_nodes=2,
)

new_compute_pool = root.compute_pools.create(new_compute_pool_def)
Copy

在此单元格中,您通过为以下属性提供值来使用 ComputePool 构造函数定义计算池:

  • instance_family:实例系列定义了您要为计算池中的节点配置的机器类型。

    每种机器类型均为其计算池提供不同数量的计算资源。在此单元格中,使用可用的最小机器类型,即 CPU_X64_XS。有关更多信息,请参阅 CREATE COMPUTE POOL

  • min_nodes:启动计算池所需的最小节点数。

  • max_nodes:计算池可以扩展到的最大节点数。

    创建计算池时,Snowflake 会按照指定的最小节点数启动它。随后,当运行中的节点无法承担任何额外的工作负载时,Snowflake 会自动管理扩展并创建新节点,最多可扩展到指定的最大数量。

然后,您通过将计算池定义传递给 compute_pools.create() 来创建计算池。

创建服务

使用您设置的镜像仓库和计算池,您现在可以定义和创建服务。服务是指在计算池中运行的容器集合,这些容器均在 Snowflake 中编排。

  1. 要检索包含容器镜像的仓库,在笔记本的下一个单元格中,运行以下代码:

    image_repository = schema.image_repositories["MyImageRepository"]
    
    Copy

    此仓库位于您的 Snowflake 账户中,列为 PUBLIC 架构内的一个暂存区。您需要此引用,以便在下一步中提取容器镜像信息。

  2. 要定义和创建服务,请在下一个单元格中,运行以下代码:

    from textwrap import dedent
    from io import BytesIO
    from snowflake.core.service import Service, ServiceSpecInlineText
    
    specification = dedent(f"""\
        spec:
          containers:
          - name: web-server
            image: {image_repository.fetch().repository_url}/amd64/nginx:latest
          endpoints:
          - name: ui
            port: 80
            public: true
        """)
    
    service_def = Service(
        name="MyService",
        compute_pool="MyComputePool",
        spec=ServiceSpecInlineText(specification),
        min_instances=1,
        max_instances=1,
    )
    
    nginx_service = schema.services.create(service_def)
    
    Copy

    此单元格定义服务规范和服务,然后为您的 NGINX Web 服务器创建服务。规范和服务的定义具有以下属性:

    • specification – 使用 Python 格式化字符串字面量 (f-string) 定义规范。该字符串格式化为 YAML。

      该规范包含容器的名称、容器镜像的路径,以及服务将公开以供公众访问的端点。在此示例中,您采用内联方式定义规范,但也可以将规范定义为对暂存区中某个 .yml 文件的引用。

    • service_def – 您使用 Service 构造函数定义服务,传入服务的名称、服务将在其中运行的计算池、规范的路径以及服务的实例总数。

      在此单元格中,使用 ServiceSpecInlineText 设置 spec 的值,因为您将规范内联定义为 f-string。您可以指定服务运行多个实例,但在此示例中,您通过将 min_instancesmax_instances 设置为 1,指定仅运行服务的一个实例。

  3. 要检查服务的状态,请在下一个单元格中,运行以下代码:

    from pprint import pprint
    
    pprint(nginx_service.get_service_status(timeout=5))
    
    Copy

    输出应类似于以下内容:

    {'auto_resume': True,
    'auto_suspend_secs': 3600,
    'instance_family': 'CPU_X64_XS',
    'max_nodes': 1,
    'min_nodes': 1,
    'name': 'MyService'}
    

使用服务

创建服务后,Snowpark Container Services 将需要几分钟时间来配置访问服务所需的端点。

  1. 要检查端点的状态,在笔记本的下一个单元格中,运行以下代码:

    import json, time
    
    while True:
        public_endpoints = nginx_service.fetch().public_endpoints
        try:
            endpoints = json.loads(public_endpoints)
        except json.JSONDecodeError:
            print(public_endpoints)
            time.sleep(15)
        else:
            break
    
    Copy

    该代码示例并非特定于 Snowpark Container Services 或 Snowflake Python APIs,只是提供了一种便捷的方法来检查端点是否已经准备就绪。请注意,您可以通过在服务对象上调用 .fetch().public_endpoints 来提取端点。

    输出应类似于以下内容:

    Endpoints provisioning in progress... check back in a few minutes
    Endpoints provisioning in progress... check back in a few minutes
    Endpoints provisioning in progress... check back in a few minutes
    
  2. 配置端点后,即可在浏览器中打开公共端点。

    请在下一个单元格中运行以下代码:

    import webbrowser
    
    print(f"Visiting {endpoints['ui']} in your browser. You might need to log in there.")
    webbrowser.open(f"https://{endpoints['ui']}")
    
    Copy

    输出应类似于以下内容:

    Visiting myorg-myacct.snowflakecomputing.app in your browser. You might need to log in there.
    

    如果成功,在访问端点时,您会在浏览中看到以下 NGINX 成功页面:

    浏览器中的 NGINX Web 服务器成功页面的屏幕截图
  3. 您可以使用 Python API 管理新服务。

    例如,若要暂停服务然后检查其状态,请运行以下代码:

    from time import sleep
    
    nginx_service.suspend()
    sleep(3)
    print(nginx_service.get_service_status(timeout=5))
    
    Copy
  4. 若要恢复服务,请运行以下代码:

    nginx_service.resume()
    sleep(3)
    print(nginx_service.get_service_status(timeout=5))
    
    Copy

只需几行 Python 代码,您就可以使用 Snowpark Container Services 在 Snowflake 中运行 NGINX。

清理

Snowflake 会针对您账户中的活跃计算池节点收费。为了避免不必要的费用,请先暂停服务和计算池,然后删除这两个对象。

  1. 若要暂停计算池和服务,在笔记本的下一个单元格中,运行以下代码:

    new_compute_pool_def.suspend()
    nginx_service.suspend()
    
    Copy
  2. 若要删除计算池和服务,运行以下代码:

    new_compute_pool_def.drop()
    nginx_service.drop()
    
    Copy

下一步是什么?

恭喜!在本教程中,您学习了使用 Snowflake Python APIs 管理 Snowpark Container Services 中组件的基本知识。

摘要

在此过程中,您完成了以下步骤:

  • 创建镜像仓库,并将应用程序镜像上传到其中。

  • 创建运行服务的计算池。

  • 创建服务来运行应用程序容器。

  • 使用和管理服务。

  • 通过暂停和删除来清理 Snowpark Container Services 资源对象。

其他资源

要获取更多使用 API 管理 Snowflake 中其他类型对象的示例,请参阅以下开发者指南:

指南

描述

使用 Python 管理 Snowflake 数据库、架构、表和视图

使用 API 创建和管理数据库、架构和表。

使用 Python 管理 Snowflake 用户、角色和授权

使用 API 创建和管理用户、角色和授权。

用 Python 管理数据加载和卸载资源

使用 API 创建和管理数据加载和卸载资源,包括外部卷、管道和暂存区。

使用 Python 管理 Snowflake 任务和任务图

使用 API 创建、执行和管理任务和任务图。

语言: 中文