チュートリアル3:Snowparkコンテナサービスの作成と管理

概要

Snowpark Container Services は、Snowflakeエコシステム内におけるコンテナー化されたアプリケーションの展開、管理、スケーリングを容易にするように設計されたフルマネージドコンテナーサービスです。この機能により、Snowflake内でコンテナー化されたワークロードを直接実行できます。

このチュートリアルでは、 Snowpark Container Services のコンポーネントを管理するために Snowflake Python APIs を使用する方法を学びます。

重要

Snowpark Container Services は通常、 AWS の Snowflake アカウントで利用可能です。 プレビューサポート は、Azure のアカウントで利用可能です。詳しくは、 Snowpark Container Services – Available regions をご覧ください。

前提条件

このチュートリアルを始める前に、以下のステップを完了する必要があります:

  1. Docker Desktopをインストールします。

    このチュートリアルでは、Docker Desktopを必要とする手順を説明します。インストール手順については、 https://docs.docker.com/get-docker/ をご参照ください。

  2. 次の手順を含む 共通セットアップ の指示に従ってください:

    • 開発環境を設定します。

    • Snowflake Python APIs パッケージをインストールします。

    • Snowflake接続を設定します。

    • Python API チュートリアルに必要なすべてのモジュールをインポートします。

    • API Root オブジェクトを作成します。

    注釈

    共通セットアップ をすでに完了している場合は、このステップを飛ばしてチュートリアルを始めることができます。

これらの前提条件が完了したら、 Snowpark Container Services を管理するために API を使い始める準備が整います。

開発環境のセットアップ

以前の Snowflake Python APIs チュートリアルでノートブックを使用していた場合、このチュートリアルでは新しいノートブックに切り替えます。このノートブックには、全てがSnowflakeで実行される Snowpark Container Services を使用して NGINX Web サーバーを実行するサンプルコードが含まれています。

  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 により、 OCI クライアント(Docker CLI や SnowSQL など)がSnowflakeアカウント内のイメージレジストリにアクセスできる OCIv2 に準拠したイメージレジストリサービスが提供されます。これらのクライアントを使用して、リポジトリにアプリケーションイメージをアップロードできます。

    詳細については、 イメージレジストリおよびリポジトリの操作 をご参照ください。

  • コンピューティングプール: コンピューティング・リソース(仮想マシン・ノード)の集合を表します。

    これらのコンピューティングリソースは、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.com/spcs_python_api_db/public/myimagerepository
      
    • リポジトリ URL のホスト名はレジストリのホスト名です。例:

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

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.com -u admin
    
    Copy
  2. NGINX イメージの AMD64 ビルドを Docker Hub: から取得します。

    docker pull --platform linux/amd64 amd64/nginx
    
    Copy
  3. amd64/nginx イメージに Snowflake イメージリポジトリ URL のタグを付けます。

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

    docker tag docker.io/amd64/nginx:latest myorg-myacct.registry.snowflakecomputing.com/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.com/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-文字列として指定を定義しているからです。複数のインスタンスを実行するようにサービスを指定できますが、この例では、 min_instancesmax_instances1 に設定することで、実行するサービスのインスタンスを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 ウェブサーバーのサクセス・ページのスクリーンショット
  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 Webサーバーを実行することができました。

クリーンアップする

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 を使用します。