AWS、GCP、Azureといった従来のクラウドプラットフォームの経験を持つ方がSnowpark Container Services(SPCS)に触れると、どこか馴染みがあるようでいて、微妙に異なる部分に戸惑うかもしれません。コンテナを実行できる点は同じですが、用語(compute pool、serviceなど)や挙動が独特で、混乱を招くことがあります。本記事でひとつずつ整理していきましょう。
Snowpark Container Servicesとは?
Snowpark Container Servicesは、コンテナ化されたアプリケーションをSnowflakeの内部で直接実行できる仕組みです。AWS ECS、Google Cloud Run、Azure Container InstancesのSnowflake版と考えるとよいでしょう。ただし、自社のクラウドアカウントではなく、Snowflakeのコンピュート環境内でコンテナが動作し、Snowflakeのデータにネイティブにアクセスできる点が特徴です。
最大の利点は、コンテナがSnowflakeテーブルに直接クエリを発行したり、Snowflake関数を呼び出したり、データにアクセスしたりできることです。サービスアカウントの作成、データアクセス用の認証情報の管理、プラットフォーム外へのデータ移動も不要です。さらに、アプリのユーザーへのアクセス権限はシンプルなGRANT文で付与できるため、認証ソフトの構築やユーザー/パスワード管理なども必要ありません。最近、私はAWS/Snowflakeを利用するお客様向けにコンテナアプリをデプロイしましたが、ユーザー管理とセキュリティが格段にシンプルだという理由で、ECSではなくSPCSが選ばれました。
Snowpark Container Servicesでのアプリのデプロイ例を扱った記事はたくさんあります。本記事では、構成要素(用語)、料金、そして従来のコンテナサービスとの細かな違いに焦点を当てて解説します。
中核となる構成要素
扱うことになる4つの主要オブジェクトを見ていきましょう。
1. Image Repository
Snowflakeのコンテナレジストリで、Docker HubやAmazon ECRに相当します。ここにDockerイメージをプッシュすると、サービス起動時にSnowflakeがそこからイメージを取得します。
1CREATE IMAGE REPOSITORY my_app_repo;
Snowpark Container Servicesは、Docker Hubのような外部レジストリから直接コンテナイメージを取得することはありません。ローカルビルド時にパブリックなベースイメージを利用するのは構いませんが、Snowflakeにデプロイする前に、最終的なイメージをアカウント内のSnowflake image repositoryにプッシュする必要があります。サービスはSnowflake独自のリポジトリに保存されたイメージしか実行できません。
2. Compute Pool
ここから、既知の概念とは少し異なる領域に入ります。compute poolとは、1つまたは複数のコンテナを実行するための仮想マシンインスタンスの集合です。多数のサービスやアプリを実行できるノードクラスターのようなものと考えてください。
CREATE COMPUTE POOL my_pool
MIN_NODES = 1
MAX_NODES = 3
INSTANCE_FAMILY = CPU_X64_XS
AUTO_RESUME = TRUE
AUTO_SUSPEND_SECS = 60;
主なパラメータ:
MIN_NODES/MAX_NODES:稼働可能なVMインスタンス数(コンテナ数ではなく、キャパシティを指します)。最小ノード数は0より大きくする必要があります。サービスが何も動作していない場合は自動的にサスペンドされます。INSTANCE_FAMILY:VMのサイズ/種類(CPU_X64_S、CPU_X64_M、GPU_NV_Sなど)AUTO_RESUME:必要時にプールを自動起動するかどうかAUTO_SUSPEND_SECS:サービスが何も動作していないアイドル状態のプールをサスペンドするまでの待機時間
3. Service
serviceとは、実行中のコンテナ化されたアプリケーションのことです。どのイメージを実行するか、何個のインスタンス(コンテナ)を起動するか、トラフィックをどのようにルーティングするかを定義します。
-- 最小限のコード:
CREATE SERVICE my_web_app
IN COMPUTE POOL my_pool
FROM @specs
SPECIFICATION_FILE = 'service.yaml';
-- より一般的なプロパティ...
CREATE SERVICE my_api_service
IN COMPUTE POOL my_pool
FROM @specs
SPECIFICATION_FILE = 'service.yaml'
MIN_INSTANCES = 1
MAX_INSTANCES = 5 -- CPU使用率に応じて最大5までスケール
MIN_READY_INSTANCES = 1 -- サービスが準備完了とみなされるには最低1必要
EXTERNAL_ACCESS_INTEGRATIONS = (api_eai, cdn_eai)
コードを展開
serviceは、コンテナ構成を記述したYAML仕様ファイル(stageに格納)を読み込みます。これはKubernetesのdeploymentやDocker Composeファイルに似ています。以下は、サービスが起動時に読み込むSPECIFICATION_FILE.ymlの例です:
spec:
containers:
- name: my_app_container
image: /dbt_dev/my_app/repo/my_app_container:latest
env:
# アプリの環境変数をここに記述
## このアプリは以下の変数を使ってSnowflakeからデータを読み込む
SNOWFLAKE_WAREHOUSE: COMPUTE_WH
SNOWFLAKE_DATABASE: FIVETRAN
SNOWFLAKE_SCHEMA: SAP_ECC
SNOWFLAKE_ROLE: DBT_ROLE
APP_HOST: 0.0.0.0
APP_PORT: "8080"
readinessProbe:
port: 8080
コードを展開
4. External Access Integration(任意)
コンテナからSnowflake外部のAPIやサービスを呼び出す必要がある場合、external access integrationが必要になります。これは、Snowflakeが外向きのネットワークアクセスを制御するための仕組みです。
CREATE EXTERNAL ACCESS INTEGRATION my_api_access
ALLOWED_NETWORK_RULES = (my_network_rule)
ENABLED = TRUE;
ご覧の通り、このサービス特有の新しい概念がいくつかあります。Snowflakeやクラウド全般の知識があれば取りかかりは容易ですが、これらの新しい用語をしっかり身につける必要があります。
Snowpark Container Servicesの料金は?
SPCSの料金体系は、個人的にはかなり妥当だと感じます。従来のコンテナサービス(ECS、Cloud Run、ACI)と比較すれば割高になりますが、Snowflakeのガバナンスやデータとの近接性というメリットを考えれば、十分に元が取れることが多いでしょう。SPCSに関わる料金項目は以下の通りです。
Compute Pools
SPCSの主な課金対象はcompute poolです。表面的には、SPCSは非常に手頃に見えます。Extra Smallはわずか0.06クレジット/時間です。1クレジットあたり3ドルとすると、XSは1日あたり4.32ドル、年間で1,576ドルになります。Cloud Runで同等のハードウェアを使うと1日3ドル弱なので、SPCSは確かに高めですが、前述のメリットが付いてきます。
compute poolが再開すると、最低5分間ぶんが課金されます。
Snowflake仮想ウェアハウスとのコスト比較
Snowflakeの仮想ウェアハウスと比較すると、最小サイズでも1クレジット/時間かかります。SPCSは、Pythonスクリプトの実行やノートブックのホスティングのような軽量タスクには、はるかに安価な選択肢となります。上述の通り、XSの仮想ウェアハウスの総コストのわずか6%でcompute nodeを動かせるのです!
ストレージコスト
ストレージは安価で、SPCSが大量のストレージを消費することはありませんが、念のため把握しておきましょう。ストレージに関する課金項目は以下の通りです:
- Image Repository:これはstageとして実装されているため、標準のストレージ料金が適用されます。
- コンテナ用ブロックボリューム:AWS EBSやGoogle Persistent Diskと同様、アプリケーションの状態を保存します。ストレージ関連では最もコストがかかる部分で、1TBあたり月82〜100ドル程度です。
- Snowflakeのイベントテーブルへのロギング(標準ストレージ)
- アプリで使用するその他のstageやテーブル(標準ストレージ)
SPCSのコスト管理の落とし穴:パブリックサービスは自動サスペンドされない
ここが、私を含む多くの新規ユーザーが驚かされるポイントです。Cloud Run、AWS Lambda、ECSのような「サーバーレス」コンテナプラットフォームに慣れていると、誰も使っていないときはサービスが自動的に停止してくれると期待するかもしれません。しかしSPCSはそうではありません。
SPCSコストの実態
ベンジャミン・フランクリンは「経験は最良の教師だが、愚か者は他から学ぼうとしない」と述べました。残念ながら、私は以下の点を身をもって学ぶことになったので、皆さんは私の失敗から学んでいただければ幸いです!
compute poolにはAUTO_SUSPEND_SECSがありますが、これはプールが空のときにしか適用されません。compute poolでサービスが動作していれば、プールはアクティブなままです。compute poolにAUTO_SUSPEND_SECS = 60を設定しても、サービスが動作中であればプールはサスペンドされず、サービス自体も自分でサスペンドすることはありません。
serviceはデフォルトで24時間365日稼働します。MIN_INSTANCES = 1(0は指定不可)でサービスを作成すると、Snowflakeは1つのコンテナを常時稼働させ続けます。つまり、明示的にサービスをサスペンドするまで、コンピュート料金が24時間365日発生し続けるのです。Cloud Runとは異なり、誰も利用していなくてもゼロにスケールダウンすることはありません。サービスのauto_suspend_secsプロパティはプレビュー機能で、Service Functionsやサービス間通信のような、パブリックエンドポイントを持たない内部アプリでは機能します。しかし、コンテナで動作するWebアプリは、アイドル状態でも自動サスペンドされません。Snowflakeは非アクティブ状態の判定に内部のservice function呼び出しのみを追跡しており、HTTPの受信トラフィックは対象外なのです。
前述の通り、クレジット消費レートが低いため、24時間365日稼働させたとしても十分手頃な料金です(1クレジット3ドル、XS構成として1日4.32ドル)。とはいえ、私にとっては予想外だったので、注意しておくとよいポイントです。
2段階のサスペンド手順
compute poolを自動サスペンドさせるには、まずサービスをサスペンドする必要があります:
-- ステップ1:サービスをサスペンド
ALTER SERVICE my_app SUSPEND;
-- ステップ2:待てばAUTO_SUSPEND_SECSが効きます
-- もしくは即座に強制サスペンドも可能:
ALTER COMPUTE POOL my_pool SUSPEND;
-- compute pool単体をサスペンドすると、サービスも一緒にサスペンドされます。
自動再開は機能する(ただしサービスについてのみ)
救いとなるのは、サービスは自動サスペンドされませんが、エンドポイントにアクセスがあれば自動的に再開する点です。ただし、有効化しておく必要があります:
ALTER SERVICE my_app SET AUTO_RESUME = TRUE;
-- これで:
-- 1. 手動でサービスをサスペンド
-- 2. 誰かがサービスエンドポイントにアクセス
-- 3. サービスが自動的に起動
-- 4. compute poolも自動的に再開(プールでAUTO_RESUME = TRUEのため)
Snowpark Container Servicesのコスト管理戦略
これらの制約を踏まえ、アプリを24時間365日稼働させたくない場合の実践的なアプローチを紹介します。
1. 手動サスペンド/再開(開発・テスト環境に最適)
-- 作業が終わったら:
ALTER SERVICE my_app SUSPEND;
-- サービスは誰かがアクセスすれば自動的に再開します
-- 手動ですが確実な方法です
2. スケジュールされたタスク(利用パターンが予測できる場合に有効)
-- 毎晩午後6時にサスペンド
CREATE TASK suspend_service_nightly
SCHEDULE = 'USING CRON 0 18 * * * America/New_York'
AS
ALTER SERVICE my_app SUSPEND;
-- 次に誰かが利用すれば自動再開します。
3. 監視とアラート(本番環境では必須)
-- showコマンドはウェアハウスを使いません
SHOW SERVICES;
-- SQLで集計やフィルタリングを行う場合...
SELECT
service_name,
status,
compute_pool_name,
current_instances,
DATEDIFF('hour', last_resumed, CURRENT_TIMESTAMP()) as hours_running
FROM INFORMATION_SCHEMA.SERVICES
WHERE status = 'RUNNING';
サスペンド中のSPCS URLへのアクセス
サービスがサスペンドされている状態でURLにアクセスすると、ユーザーは以下のエラーを目にします:
{
"responseType": "ERROR",
"requestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"detail": "Service EXAMPLE_SERVICE not reachable: no service hosts found."
}
サービスとcompute poolで自動再開が有効になっていれば、ユーザーがURLにアクセスした時点で起動が始まります。所要時間は約39〜60秒で、その後ページを再読み込みすればアクセスできます。やや使い勝手が悪い面はありますが、ユーザーが事前にそれを把握していれば許容範囲でしょう。
Compute Poolを使ったバッチジョブの実行
SPCSのcompute poolはクレジット単価が大幅に安いため、これを活用してSnowflake上でPython(あるいは任意の言語)のバッチジョブを安価に実行できます。例えば、コンテナ化したPythonジョブをSnowflakeレジストリにプッシュし、サービスを記述したYAMLファイルをstageにアップしたとします。すると、execute job service ...コマンドでそのコンテナ内のコードを実行できます。これらのサービスは処理が完了すると自動的に停止し、compute poolも通常通り自動サスペンドされます。Snowflakeで安価なコンピュートを活用できる便利なテクニックです!
EXECUTE JOB SERVICE
IN COMPUTE POOL my_compute_pool
NAME = my_batch_job
FROM @my_stage
SPEC = 'job_spec.yaml';
SnowsightでSnowpark Container Servicesのコストを監視する
Snowsight UIを使えば、SPCSの利用料を手軽に監視できます。accountadminロールまたは利用状況の監視権限を持つロールでログインし、Admin → Cost Management → Consumptionに移動して、Service TypeフィルターをSPCSに切り替えてください。
スタートアップチェックリスト
✅ コンテナ管理用の専用ロールを作成
✅ データベース、スキーマ、image repository、stageをセットアップ
✅ 外部APIを呼び出す場合はexternal access integrationを構成
✅ 適切なサイズと自動サスペンド設定でcompute poolを作成
✅ サービス仕様をstageにアップロード
✅ AUTO_RESUME = TRUEでサービスを作成
✅ 手動サスペンドの手順を文書化、もしくはスケジュールタスクを作成
✅ 稼働中のサービスとコストを追跡するための監視クエリを設定
✅ 本番展開前にサスペンド/再開サイクルをテスト
まとめ
Snowpark Container Servicesによって、コンテナ化アプリケーションのパワーをSnowflake内のデータに直接持ち込めるようになりました。ただし、学習曲線は存在します。image repository、compute pool、service、そしてそれらの相互作用を理解する必要があります。これらの構成要素とコスト管理上の癖をひとたび把握すれば、Snowflakeプラットフォームから一歩も外に出ることなく、データのすぐ隣で動作する強力なデータアプリケーションを構築できます。
Jeffは、洞察の自動化やデータを活用したビジネスプロセスの制御において15年以上の経験を持つData and Analytics Consultantです。技術面ではSnowflake + dbt + Tableauを得意とし、業界面では公益事業、臨床試験、出版、CPG、製造業での経験があります。お気軽にご連絡ください:[email protected]。
- サービスが動作中はcompute poolはアイドル状態になりません -
AUTO_SUSPEND_SECS設定は、プールにアクティブなサービスが存在しない場合にのみ適用されます - サービスのライフサイクルは明示的に管理する必要があります - 利用していないときは
ALTER SERVICE ... SUSPENDを実行し、自動起動のためにAUTO_RESUME = TRUEを有効化しましょう(httpアプリの場合) - パブリックエンドポイントでは自動サスペンドが機能しません - パブリックエンドポイントを持つサービスは自動再開はできますが、非アクティブ状態に基づく自動サスペンドは行われません
- コスト管理戦略は事前に計画しましょう - 手動サスペンド、スケジュールタスク、あるいはサービスを稼働させ続けて予算を確保するか、方針を決めておきましょう
- すべてのオブジェクトに権限設定が必要です - image repository、stage、compute pool、external access integration、サービスのすべてに固有のGRANTが必要です