こんにちは、CCCMKホールディングスAIエンジニアの三浦です。最近オフィスが変わり、電車に乗っている時間が長くなりました。「読まないと」と思ってため込んでいた論文や記事を集中して読んでいく時間として活用しています。
最近Snowflakeでコンテナアプリを動かすことが出来る、という話を知り、どんな感じなのか試してみたいと思いました。利用するのは"Snowpark Container Services"というSnowflakeのフルマネージドコンテナサービスで、今回は開発環境でDockerで作っていたコンテナアプリをこの機能を使ってSnowflakeで動かしてみる、という話をご紹介していきます。
Snowpark Container Servicesとは
Snowpark Container Servicesはフルマネージドなコンテナサービスで、イメージの管理から複数コンテナを組み合わせたサービスの稼働まで、Snowflake上で完遂することが出来る面白いサービスです。ドキュメントはこちらです。
Snowflake上でコンテナアプリを動かすまでの流れは、ざっと次のようになります。
- ビルドしたイメージを登録するImage RepositoryをSchema配下に作成する
- アプリを動かすためのCompute Poolを作成する
- 開発環境でビルドしたイメージをImage Repositoryにpushする
- サービスの定義ファイルをYAML形式で書く
- サービスを作成し、アプリを動かす
今回はこの流れに従って手順をまとめていきます。
初期設定
検証用の環境を作成しました。手順はこちらのSnowpark Container Servicesの共通セットアップの内容に従っています。
SQLクエリを実行して進めていきます。まず検証用のRoleを作成します。
CREATE ROLE test_role;
検証用のDatabaseを作成し、test_role
に権限を付与します。
CREATE DATABASE IF NOT EXISTS tutorial_db; GRANT OWNERSHIP ON DATABASE tutorial_db TO ROLE test_role COPY CURRENT GRANTS;
検証用のWarehouseの作成と利用権限をRoleに付与。
CREATE OR REPLACE WAREHOUSE tutorial_warehouse WITH WAREHOUSE_SIZE='X-SMALL'; GRANT USAGE ON WAREHOUSE tutorial_warehouse TO ROLE test_role;
アプリを動かすためのCompute Poolの作成と権限をRoleに付与。
CREATE COMPUTE POOL tutorial_compute_pool MIN_NODES = 1 MAX_NODES = 1 INSTANCE_FAMILY = CPU_X64_XS; GRANT USAGE, MONITOR ON COMPUTE POOL tutorial_compute_pool TO ROLE test_role;
アプリのEndpointへのアクセス権限のRoleへの付与と、RoleのUserへの付与を行います。
GRANT BIND SERVICE ENDPOINT ON ACCOUNT TO ROLE test_role; GRANT ROLE test_role TO USER test_user
あとはDatabaseに検証用のSchemaを作り、Image Repositoryとサービス定義ファイル置き場用のStageを作成しました。
USE ROLE test_role; USE DATABASE tutorial_db; USE WAREHOUSE tutorial_warehouse; CREATE SCHEMA IF NOT EXISTS data_schema; CREATE IMAGE REPOSITORY IF NOT EXISTS tutorial_repository; CREATE STAGE IF NOT EXISTS tutorial_stage DIRECTORY = ( ENABLE = true );
開発環境からイメージをpushする
今度はアプリの開発環境で作業を行います。イメージをビルドしてImage Registry配下のRepositoryにpushするのですが、Snowflakeに接続するために最初にSnowflake CLIをインストールしました。
実行したコマンドはこちらです。
wget https://sfc-repo.snowflakecomputing.com/snowflake-cli/linux_x86_64/3.5.0/snowflake-cli-3.5.0.x86_64.deb sudo dpkg -i snowflake-cli-3.5.0.x86_64.deb
最初CLIのバージョンが3.8.3のものをインストールしたのですが、コマンドを実行するとIllegal instruction (core dumped)
というメッセージが表示されて起動することが出来ませんでした。おそらくこちらと同様の現象で、このイシューには3.5だと上手くいった、と書いてあったため今回3.5.0をインストールしています。
Snowflakeへの接続にはキーペア認証を使用しました。秘密鍵や公開鍵の登録手順はこちらを参考にしています。
接続情報はtomlファイルに記入しました。以下のような内容です。
default_connection_name = "myconnection" [connections] [connections.myconnection] account = "ACCOUNT_NAME" user = "test_user" authenticator = "SNOWFLAKE_JWT" private_key_file = "./rsa_key.p8" [cli.logs] save_logs = true level = "info" path = "/home/xx/.snowflake/logs"
あらかじめ作成済みのコンテナアプリのディレクトリ内でイメージをビルドします。 ちなみに今回のアプリのDockerfileは以下のようにしました。streamlitが動くようになっています。
FROM python:3.12.7-slim WORKDIR /app COPY ./requirements.txt . RUN pip install -r requirements.txt COPY ./src ./src WORKDIR ./src EXPOSE 8501 CMD ["streamlit","run","app.py"]
buildしてタグ付けをします。RepositoryのURLは以下に従って設定しました。
docker build -t account.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/test-app
Snowflake CLIでRegistryにログインします。
snow --config-file=connection.toml spcs image-registry login
イメージをpushします。
docker push account.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/test-app
サービス定義ファイルの作成
次にサービスを定義するYAMLファイルを作成します。"docker-compose.yml"の形式に似ています。複数のコンテナを指定することが出来ますが、今回はコンテナ1つの構成です。containers
の箇所で起動するコンテナの情報を記入しています。image
には先ほどpushしたイメージのパスを指定しています。env
には環境変数を設定できます。また、readinessProbe
を上手く使うとアプリ起動時のヘルスチェックの処理を指定出来るようです。(今回は特に処理を作っていません。)
endpoints
がこのサービスのEndpointを示しています。public: true
にすることで同一アカウント内の権限があるユーザーがアクセスできるようになります。
spec: containers: - name: app image: /tutorial_db/data_schema/tutorial_repository/test-app env: SERVER_PORT: 8501 ... readinessProbe: port: 8501 path: / endpoints: - name: app port: 8501 public: true
この内容をspec.yamlとして保存し、Stage上に格納しました。
サービスの作成
あとは以下のSQLクエリを実行してサービスを作成しました。
USE ROLE test_role; USE DATABASE TUTORIAL_DB; USE SCHEMA DATA_SCHEMA; CREATE SERVICE test_app IN COMPUTE POOL tutorial_compute_pool FROM @TUTORIAL_STAGE SPECIFICATION_FILE='spec.yaml' MIN_INSTANCES = 1 MAX_INSTANCES = 1;
サービスの作成が完了した後は、以下のクエリでエンドポイントのURLを確認出来るようになります。
SHOW ENDPOINTS IN SERVICE test_app;
実行結果に含まれる"ingress_url"にアクセスすると、アカウントへのログイン画面が表示され、ログインが完了するとsnowflakeのアプリが表示されます!
まとめ
今回はSnowpark Container Servicesを使ってSnowflakeの中でコンテナアプリを動かす、といったことを試してみました。手順が多いのでハードルが高く感じていたのですが、いざやってみるとそれほど詰まるところもなく、スムーズに進めることが出来ました。またアプリへの認証もSnowflakeの機能を利用できるのもいいな、と思います。
この後はSnowflakeに格納されたTableにコンテナアプリからアクセスさせたり、作ったアプリをパッケージ化する方法なども調べていきたいと思います。