Snowpark Container Services: サービスの操作¶
Snowpark Container Services を使用すると、コンテナー化されたアプリケーションを簡単に展開、管理、スケーリングできるようになります。アプリケーションを作成し、Snowflakeアカウントのリポジトリにアプリケーションイメージをアップロードしたら、アプリケーションコンテナをサービスとして実行できます。
サービスは、疑似マシン (VM) ノードのコレクションである コンピューティングプール 上でコンテナ化されたアプリケーションを実行するSnowflakeを表します。サービスには2つのタイプがあります。
長時間実行サービス。 自動的に終了しないウェブサービスのようなものです。サービスを作成した後、Snowflakeは実行中のサービスを管理します。たとえば、何らかの理由でサービスコンテナーが停止した場合、Snowflakeはそのコンテナーを再起動し、サービスが中断されることなく実行されるようにします。
ジョブサービス。 ストアドプロシージャと同じように、コードが終了すると終了します。すべてのコンテナが終了すると、ジョブサービスは完了します。
Snowpark Container Servicesは、サービスの作成と管理に使用できる SQL コマンドのセットを提供します。これらには次が含まれます。
サービスの作成。 CREATE SERVICE、 EXECUTE JOB SERVICE
サービスの変更。 ALTER SERVICE、 DROP SERVICE
サービスに関する情報の取得。 SHOW SERVICES、 DESCRIBE SERVICE
サービスの開始¶
サービスの開始に最低限必要な情報には以下が含まれます。
名前: サービス名。
サービス仕様: この 仕様 は、サービスの実行に必要な情報をSnowflakeに提供します。仕様は YAML ファイルです。
コンピューティングプール: Snowflakeは、指定された コンピューティングプール でサービスを実行します。
長時間実行サービスの作成¶
CREATE SERVICE を使用して長時間実行サービスを作成します。
インライン仕様を使用してサービスを作成します。以下に示すように、開発中はほとんどのケースでインライン仕様を選ぶことができます。
CREATE SERVICE echo_service IN COMPUTE POOL tutorial_compute_pool FROM SPECIFICATION $$ spec: containers: - name: echo image: /tutorial_db/data_schema/tutorial_repository/my_echo_service_image:tutorial readinessProbe: port: 8000 path: /healthcheck endpoints: - name: echoendpoint port: 8000 public: true $$;
ステージ情報を使用してサービスを作成します。サービスを実稼働環境に展開する際には、懸念事項の分離という設計原則を適用し、仕様をステージにアップロードし、以下に示すように、ステージ情報の CREATE SERVICE コマンドを提供することをお勧めします。
CREATE SERVICE echo_service IN COMPUTE POOL tutorial_compute_pool FROM @tutorial_stage SPECIFICATION_FILE='echo_spec.yaml';
ジョブサービスの実行¶
EXECUTE JOB SERVICE を使用してジョブサービスを作成します。このコマンドは同期的に実行され、ジョブサービスのすべてのコンテナが終了した後に応答を返します。
インライン仕様を使用してジョブサービスを実行します。
EXECUTE JOB SERVICE IN COMPUTE POOL tutorial_compute_pool NAME = example_job_service FROM SPECIFICATION $$ spec: container: - name: main image: /tutorial_db/data_schema/tutorial_repository/my_job_image:latest env: SNOWFLAKE_WAREHOUSE: tutorial_warehouse args: - "--query=select current_time() as time,'hello'" - "--result_table=results" $$;
ステージ情報を使用してジョブサービスを実行します。
EXECUTE JOB SERVICE IN COMPUTE POOL tutorial_compute_pool NAME = example_job_service FROM @tutorial_stage SPECIFICATION_FILE='my_job_spec.yaml';
複数のサービスインスタンスを作成し、自動スケールを構成する¶
デフォルトでは、Snowflakeは指定したコンピューティングプールでサービスのインスタンスを1つ実行します。重いワークロードを管理するには、 MIN_INSTANCES と MAX_INSTANCES プロパティを設定して、複数のサービスインスタンスを実行できます。このプロパティは、サービスの最小インスタンス数から開始し、必要に応じてSnowflakeがスケールできる最大インスタンス数を指定します。
例
CREATE SERVICE echo_service
IN COMPUTE POOL tutorial_compute_pool
FROM @tutorial_stage
SPECIFICATION_FILE='echo_spec.yaml'
MIN_INSTANCES=2
MAX_INSTANCES=4;
複数のサービスインスタンスが実行されている場合、Snowflakeは自動的にロードバランサーを提供し、受信するリクエストを分散します。
注釈
ジョブ・サービスの複数のインスタンスを実行することはできません。
実行中のサービスインスタンス数を自動スケールするようにSnowflakeを構成するには、以下のステップに従います。
サービス仕様ファイルで、サービスインスタンスに必要なメモリと CPU を指定します。詳細については、 container.resources フィールドをご参照ください。
例
resources: requests: memory: <memory-reserved> cpu: <cpu-units>
CREATE SERVICE コマンドを実行する場合は、 MIN_INSTANCES と MAX_INSTANCES パラメーターを設定します。また、 ALTER SERVICE を使用してこれらの値を変更することもできます。オートスケーリングは、指定された MAX_INSTANCES が MIN_INSTANCES より大きい場合に発生します。
Snowflakeは、指定されたコンピューティングプール上に最小数のサービスインスタンスを作成することから開始します。Snowflakeはしきい値の80%( CPU とメモリの双方で)を使用して、サービスインスタンス数をスケールアップまたはスケールダウンします。Snowflakeは、現在実行中のすべてのサービスインスタンスから使用状況データを集約して、コンピューティングプール内のリソース使用量(メモリまたは CPU)を継続的にモニターします。
リソース使用量の合計(すべてのサービスインスタンス)が80%を超えると、Snowflakeはコンピューティングプール内に追加のサービスインスタンスを展開します。集約されたリソースの使用量が80%を下回ると、Snowflakeは実行中のサービスインスタンスを削除してスケールダウンします。Snowflakeは5分間の安定化ウィンドウを使用して、頻繁なスケーリングを防止します。
以下のスケーリング動作に注意してください。
サービスインスタンスのスケーリングは、サービス用に構成された MIN_INSTANCES と MAX_INSTANCES パラメーターによって制約されます。
スケールアップが必要で、コンピューティングプールノードが別のサービスインスタンスを起動するために必要なリソース容量が不足している場合は、コンピューティングプールの自動スケールをトリガーできます。詳細については、 コンピューティングプールノードの自動スケーリング をご参照ください。
サービスの作成時に MAX_INSTANCES と MIN_INSTANCES パラメーターを指定しても、サービス仕様ファイルでサービスインスタンスのメモリと CPU 要件を指定しない場合は、自動スケーリングは実行されません。Snowflakeは MIN_INSTANCES パラメーターで指定されたインスタンスの数で開始され、数は自動スケーリングされません。
仕様テンプレートの使用¶
同じ仕様で複数のサービスを作成したいが、構成が異なる場合があります。たとえば、サービス仕様で 環境変数 を定義し、同じ仕様で環境変数の値が異なる複数のサービスを作成したいとします。
仕様テンプレートのサポートにより、仕様内でフィールド値の変数を定義することができます。サービスを作成するときに、これらの変数に値を指定します。
仕様テンプレートの使用は、2段階のプロセスからなります。
さまざまな仕様フィールドの値として変数を使用して仕様を作成します。これらの変数を指定するには、
{{ variable_name }}
構文を使用します。例えば、以下の指定では、イメージタグ名に「tag_name」という変数を使い、サービスごとに異なるイメージタグを指定します。spec: containers: - name: echo image: myorg-myacct.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:{{ tag_name }} ... endpoints: …
CREATE SERVICE コマンドで仕様テンプレートを提供してサービスを作成します。テンプレートの指定には SPECIFICATION_TEMPLATE または SPECIFICATION_TEMPLATE_FILE を使用します。変数の値を指定するには、 USING パラメーターを使用します。例えば、次のステートメントはSnowflakeステージの仕様テンプレートを使用しています。USING パラメーターは、変数
tag_name
に値'latest'
を設定します。CREATE SERVICE echo_service IN COMPUTE POOL tutorial_compute_pool FROM @STAGE SPECIFICATION_TEMPLATE_FILE='echo.yaml' USING (tag_name=>'latest');
仕様で変数を定義するためのガイドライン¶
仕様でフィールド値として変数を定義するには、
{{ variable_name }}
構文を使用します。これらの変数はデフォルト値を持つことができます。デフォルト値を指定するには、変数宣言で
default
関数を使用します。たとえば、以下の仕様では2つの変数(character_name
とendpoint_name
)をデフォルト値で定義しています。spec: containers: - name: echo image: <image_name> env: CHARACTER_NAME: {{ character_name | default('Bob') }} SERVER_PORT: 8085 endpoints: - name: {{ endpoint_name | default('echo-endpoint') }} port: 8085
default
関数にオプションのブール値パラメーターを指定すると、変数に空白値が渡されたときにデフォルト値を使用するかどうかを指定できます。次の仕様を検討します。spec: containers: - name: echo image: <image_name> env: CHARACTER_NAME: {{ character_name | default('Bob', false) }} SERVER_PORT: 8085 endpoints: - name: {{ endpoint_name | default('echo-endpoint', true) }} port: 8085
仕様で、
変数
character_name
の場合、ブール値パラメーターはfalse
に設定されます。したがって、このパラメータに空の文字列値('')が設定されている場合、値は空白のままであり、デフォルト値("Bob")は使用されません。変数
echo_endpoint
の場合、ブール値パラメーターはtrue
に設定されます。したがって、このパラメーターに空白値を渡すと、デフォルト値(「echo-endpoint」)が使用されます。
デフォルトでは、
default
関数のブール値パラメーターはfalse
です。
仕様変数に値を渡す際のガイドライン¶
CREATE SERVICE コマンドで USING パラメーターを指定して、変数の値を提供します。USING の一般的な構文は次のとおりです。
USING( var_name=>var_value, [var_name=>var_value, ... ] );
条件
var_name
は大文字小文字を区別し、有効なSnowflake識別子でなければなりません(識別子の要件 を参照)。var_value
には英数字か有効な JSON 値を指定します。例:
-- Alphanumeric string and literal values USING(some_alphanumeric_var=>'blah123', some_int_var=>111, some_bool_var=>true, some_float_var=>-1.2) -- JSON string USING(some_json_var=>' "/path/file.txt" ') -- JSON map USING(env_values=>'{"SERVER_PORT": 8000, "CHARACTER_NAME": "Bob"}' ); -- JSON list USING (ARGS='["-n", 2]' );
CREATE SERVICE の USING パラメーターは、仕様変数(仕様がデフォルト値を提供する変数を除く)の値を提供しなければなりません。それ以外の場合、エラーが返されます。
例¶
次の例は、仕様テンプレートを使用してサービスを作成する方法を示しています。これらの例の CREATE SERVICE コマンドはインライン仕様を使っています。
例1: 単純な値を提供する¶
チュートリアル1 では、インライン仕様を提供してサービスを作成します。以下の例は同じものを修正したバージョンで、 image_url
と SERVER_PORT
の2つの変数を定義します。変数 SERVER_PORT
が3箇所で繰り返されていることに注意してください。これは、同じ値を持つことが期待されるすべてのフィールドが同じ値を持つことを保証する変数を使用することの利点です。
CREATE SERVICE echo_service
IN COMPUTE POOL tutorial_compute_pool
MIN_INSTANCES=1
MAX_INSTANCES=1
FROM SPECIFICATION_TEMPLATE $$
spec:
containers:
- name: echo
image: {{ image_url }}
env:
SERVER_PORT: {{SERVER_PORT}}
CHARACTER_NAME: Bob
readinessProbe:
port: {{SERVER_PORT}}
path: /healthcheck
endpoints:
- name: echoendpoint
port: {{SERVER_PORT}}
public: true
$$
USING (image_url=>' "/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest" ', SERVER_PORT=>8000 );
この CREATE SERVICE コマンドでは、 USING パラメーターが2つの仕様変数の値を提供します。1つの image_url
値にはスラッシュとコロンが含まれます。英数字ではありません。そのため、この例では値を二重引用符で囲み、有効な JSON 文字列値にしています。テンプレート仕様は以下の仕様を拡張したものです。
spec:
containers:
- name: echo
image: /tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest
env:
SERVER_PORT: 8000
CHARACTER_NAME: Bob
readinessProbe:
port: 8000
path: /healthcheck
endpoints:
- name: echoendpoint
port: 8000
public: true
例2: JSON 値を提供する¶
チュートリアル1では、以下のように2つの環境変数(SERVER_PORT
と CHARACTER_NAME
)を定義しています。
spec:
containers:
- name: echo
image: /tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest
env:
SERVER_PORT: 8000
CHARACTER_NAME: Bob
…
この指定をテンプレート化するには、 env
フィールドに変数を使用します。これにより、環境変数の値を変えて複数のサービスを作ることができます。以下の CREATE SERVICE コマンドは、envフィールドに変数(env_values
)を使用しています。
CREATE SERVICE echo_service
IN COMPUTE POOL tutorial_compute_pool
MIN_INSTANCES=1
MAX_INSTANCES=1
FROM SPECIFICATION_TEMPLATE $$
spec:
containers:
- name: echo
image: /tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest
env: {{env_values}}
readinessProbe:
port: {{SERVER_PORT}} #this and next tell SF to connect to port 8000
path: /healthcheck
endpoints:
- name: echoendpoint
port: {{SERVER_PORT}}
public: true
$$
USING (env_values=>'{"SERVER_PORT": 8000, "CHARACTER_NAME": "Bob"}' );
CREATE SERVICE の USING パラメーターは、 env_values
変数の値を提供します。値は JSON マップで、両方の環境変数の値を提供します。
例3: 変数値としてリストを提供する¶
チュートリアル2 では、仕様に2つの引数を含む args
フィールドが含まれています。
spec:
container:
- name: main
image: /tutorial_db/data_schema/tutorial_repository/my_job_image:latest
env:
SNOWFLAKE_WAREHOUSE: tutorial_warehouse
args:
- "--query=select current_time() as time,'hello'"
- "--result_table=results"
仕様書のテンプレートバージョンでは、以下のように、これらの引数を JSON リストとして提供することができます:
spec:
container:
- name: main
image: /tutorial_db/data_schema/tutorial_repository/my_job_image:latest
env:
SNOWFLAKE_WAREHOUSE: tutorial_warehouse
args: {{ARGS}}
$$
USING (ARGS=$$["--query=select current_time() as time,'hello'", "--result_table=results"]$$ );
サービスの変更とドロップ¶
サービス作成後:
サービスを作成した後、 DROP SERVICE を使用してスキーマからサービスを削除できます(Snowflakeはすべてのサービスコンテナを終了します)。
ALTER SERVICE を使ってサービスを変更します(たとえば、サービスを一時停止または再開し、実行中のインスタンス数を変更し、新しいサービス仕様を使用してサービスを再展開するようにSnowflakeに指示します)。
注釈
ジョブサービスを変更することはできません。
サービスの終了¶
サービスを一時停止 (ALTERSERVICE... SUSPEND) またはサービスを停止 (DROP SERVICE) すると、Snowflake はすべてのサービスインスタンスを終了します。同様に、サービスコードをアップグレードする場合(ALTER SERVICE...<fromSpecification> )、Snowflake は、一度に 1 つのサービスインスタンスを終了して再デプロイすることで、 ローリングアップグレード を適用します。
サービスインスタンスを終了する際、Snowflakeはまず各サービスコンテナに SIGTERM シグナルを送信します。コンテナーには、シグナルを処理し、30秒のウィンドウで優雅にシャットダウンするオプションがあります。そうでない場合は、猶予期間の後、Snowflake はコンテナー内のすべてのプロセスを終了します。
サービスコードの更新とサービスの更新¶
サービス作成後、 ALTER SERVICE...<fromSpecification> コマンドを使用してサービスコードを更新し、サービスを再デプロイします。
まず、修正したアプリケーションコードをイメージリポジトリにアップロードし、インラインまたはSnowflakeステージの仕様ファイルへのパスを指定して、サービス仕様を提供する ALTER SERVICE を呼び出します。例:
ALTER SERVICE echo_service
FROM SPECIFICATION $$
spec:
…
…
$$;
リクエストを受信すると、Snowflakeは新しいコードを使用してサービスを再展開します。
CREATESERVICE...<from-Specification> コマンドを実行すると、Snowflake は提供されたイメージの特定のバージョンを記録します。Snowflakeは、リポジトリ内のイメージが更新された場合でも、以下のシナリオで同じイメージバージョンをデプロイします。
中断されたサービスが再開された場合(ALTERSERVICE... RESUMEを使用)。
オートスケールがさらにサービス・インスタンスを追加する場合。
クラスタメンテナンス中にサービスインスタンスが再起動された場合。
しかし、 ALTER SERVICE...<fromSpecification> を呼び出すと、Snowflakeがそのイメージのリポジトリにある最新バージョンを使用するトリガーとなります。
あなたがサービス・オーナーである場合、 DESCRIBE SERVICE コマンドの出力にはサービス仕様が含まれ、下図のようにイメージ・ダイジェスト(仕様の sha256
フィールドの値)が含まれます。
spec:
containers:
- name: "echo"
image: "/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest"
sha256: "@sha256:8d912284f935ecf6c4753f42016777e09e3893eed61218b2960f782ef2b367af"
env:
SERVER_PORT: "8000"
CHARACTER_NAME: "Bob"
readinessProbe:
port: 8000
path: "/healthcheck"
endpoints:
- name: "echoendpoint"
port: 8000
public: true
ALTER SERVICE は、サービスとの通信( サービスの使用 を参照)に影響を与える可能性があります。
ALTER SERVICE...<fromSpecification> でエンドポイントが削除されたり、エンドポイントを使用するために必要な関連するパーミッションが削除されたりした場合(仕様リファレンスの serviceRoles を参照)、サービスへのアクセスは失敗します。詳しくは、 Using Service をご参照ください。
アップグレード中は、新しい接続が新しいバージョンにルーティングされる可能性があります。新しいサービス・バージョンに後方互換性がない場合、有効なサービス利用は中断されます。例えば、サービス・ファンクションを使った継続的なクエリは失敗するかもしれません。
注釈
ネイティブアプリの一部であるサービスコードをコンテナで更新する場合、 SYSTEM$WAIT_FOR_SERVICES システム機能を使用してネイティブアプリのセットアップスクリプトを一時停止し、サービスを完全にアップグレードできるようにします。詳細については、 コンテナを使用してアプリをアップグレードする をご参照ください。
ローリングアップグレードの監視¶
複数のサービスインスタンスが実行されている場合、Snowflakeはサービスインスタンスの ID に基づいて降順にローリングアップグレードを実行します。サービスのアップグレードを監視するには、以下のコマンドを使用します。
DESCRIBE SERVICE および SHOW SERVICES:
サービスがアップグレードされている場合、出力の
is_upgrading
列の表示は TRUE です。出力の
spec_digest
列は、現在のサービス仕様の仕様ダイジェストを表します。このコマンドは定期的に実行することができます。;spec_digest
の値が変化した場合は、サービスのアップグレードがトリガーされたことを示しています。 SHOW SERVICE INSTANCES IN SERVICE コマンドを使用して、以下の説明に従って、すべてのインスタンスが最新バージョンにアップグレードされているかどうかを確認します。
SHOW SERVICE INSTANCES IN SERVICE:
出力の
status
列は、ローリングアップグレードの進行中に、個々のサービスインスタンスのステータスを提供します。アップグレード中、 TERMINATING から PENDING 、 PENDING から READY のように、各サービス・インスタンスの移行ステータスが表示されます。サービス・アップグレード中、 SHOW SERVICE INSTANCES IN SERVICE コマンドは、
spec_digest
出力カラムに、常に最新のスペックダイジェストを返す SHOWSERVICES とは異なる値を返すかもしれません。これは単に、サービスのアップグレードが進行中であり、サービスインスタンスがまだ古いバージョンのサービスを実行していることを示しています。
サービスについての情報の取得¶
これらのコマンドを使うことができます。
サービスのプロパティとステータスを取得するには、 DESCRIBE SERVICE コマンドを使用します。
SHOW SERVICES コマンドを使用して、あなたが権限を持っている現在のサービス(ジョブ・サービスを含む)をリストアップします。各サービスについて、出力はサービスのプロパティとステータスを提供します。デフォルトでは、現在のデータベースとスキーマのサービスが出力されます。また、以下のスコープを指定することもできます。例:
特定のデータベース、または特定のスキーマでアカウントのサービスをリストする: 例えば、 IN ACCOUNT フィルタを使用して、サービスがどのデータベースまたはスキーマに属しているかに関係なく、Snowflake アカウントのサービスを一覧表示します。これは、アカウント内の複数のデータベースとスキーマにSnowflakeサービスが作成されている場合に便利です。他のコマンドと同様に、 SHOW SERVICES IN ACCOUNTS は権限によって制限され、使用しているロールが表示権限を持っているサービスのみを返します。
IN DATABASE または IN SCHEMA を指定して、現在の(または指定した)データベースまたはスキーマのサービスを一覧表示することもできます。
コンピューティングプールで実行されているサービスをリストする: 例えば、 IN COMPUTE POOL フィルターを使用して、コンピューティングプールで実行されているサービスをリストします。
プレフィックスで始まる、またはパターンに一致するサービスをリストする: LIKE と STARTS WITH フィルタを適用して、名前でサービスをフィルタリングすることができます。
ジョブ・サービスのみをリストアップする、またはジョブ・サービスをリストから除外する: SHOW JOB SERVICES または SHOW SERVICES EXCLUDE JOBS を使用します。
これらのオプションを組み合わせて、 SHOW SERVICES 出力をカスタマイズすることもできます。
サービス・インスタンスのプロパティを取得するには、 SHOW SERVICE INSTANCES IN SERVICE コマンドを使用します。
サービスインスタンスのプロパティとステータスを取得するには、 SHOW SERVICE CONTAINERS IN SERVICE コマンドを使用します。
サービスのモニタリング¶
Snowpark Container Servicesは、アカウント内のコンピューティングプールとその上で実行されているサービスを監視するためのツールを提供します。詳細については、 Snowpark Container Services: Monitoring Services をご参照ください。
サービスエンドポイントへのアクセス管理¶
サービス 所有者 ロール(サービスを作成するために使用するロール)は、サービスとサービスが公開するエンドポイントへのフルアクセス権を持っています。その他のロールは、サービスと通信するためにエンドポイントで USAGE 権限が必要です。例:
クライアントの所有者ロールは、エンドポイントで USAGE 権限が必要です。 クライアント とは、サービス関数またはサービスが他のサービスのエンドポイントにリクエストを行うことを指します。
Snowflakeの外部からパブリックエンドポイントに イングレス リクエストを行うユーザーは、エンドポイントで USAGE 権限が必要です。
サービス・ロール は、サービスエンドポイント上の権限を他のロールに付与する仕組みです。以下のようなオプションがあります。
デフォルトサービスロールを使用する: Snowflakeはまた、サービスが公開するすべてのエンドポイントに USAGE 権限を付与するデフォルトサービスロール(
ALL_ENDPOINTS_USAGE
)を定義し、このデフォルトサービスロールをサービスの所有者ロールに付与します。このため、所有者ロールはサービスが公開するずべてのエンドポイントにアクセスすることができます。このデフォルトのサービス・ロールを他のロールに付与することができます。サービス・ロールの作成: デフォルトのサービス・ロールを使用してすべてのエンドポイントに権限を付与する代わりに、 サービス仕様 で1つ以上のサービス・ロールを定義することができます。定義内では、ロールに USAGE 権限が付与される特定のエンドポイントを示します。 GRANT SERVICE ROLE 、 REVOKE SERVICE ROLE コマンドを使用して、サービス・ロールを他のロールに付与(または取り消し)できます。 SHOW ROLES IN SERVICE, SHOW GRANTS コマンドを使用して、付与についての情報を表示することもできます。
Snowflakeはサービスの作成時にサービスロールを作成し、サービスの削除時にそれを削除します。
カスタム・サービス・ロールを作成することで、シナリオごとに異なるアクセス許可を付与することができます。例えば、サービス機能で使用するために、エンドポイントにサービス・ロール権限を付与することができます。ウェブ UI で使用されるパブリック・エンドポイントへの権限を持つ別のサービス・ロールを作成することになるかもしれません。
次の点に注意してください。
同じロールを使用して複数のサービスを作成する場合、所有者ロールはすべてのエンドポイントへのアクセス権を持っているため、余分な構成を行わなくても、それらのサービスはシームレスに相互に通信できます。
サービスに複数のコンテナがある場合、それらのコンテナーはlocalhostを介して相互に通信することができ、これらの通信は各サービスインスタンス内でローカルであり、ロールベースのアクセス制御の対象ではないことに注意してください。
以下のセクションで詳細を説明します。また、この機能をステップバイステップで説明するチュートリアル(サービスエンドポイント権限を構成してテストする)を試すこともできます。
デフォルトのサービス・ロールを使用するすべてのエンドポイントで USAGE 権限を付与します。¶
サービス(ジョブサービスを含む)を作成すると、Snowflakeは ALL_ENDPOINTS_USAGE
という名前のデフォルトサービスロールも作成します。このロールはサービスが公開するすべてのエンドポイントに対して USAGE の権限を持ちます。 GRANT SERVICE ROLE コマンドを使用して、このデフォルトサービスロールを他のロールに付与できます。
GRANT SERVICE ROLE my_echo_service_image!ALL_ENDPOINTS_USAGE TO ROLE some_other_role;
some_other_role
を使用しているユーザーは、すべてのサービスエンドポイントで USAGE 権限を持ちます。
サービスをドロップすると、Snowflakeはサービスに関連付けられたすべてのサービスロール(デフォルトサービスロールおよびサービス仕様で定義されたサービスロール)をドロップし、すべてのサービスロールの付与を無効にします。
仕様で定義されたサービス・ロールを使用して、特定のエンドポイントに USAGE 権限を付与します。¶
サービスロールを使用して、サービスエンドポイントへのきめ細かなアクセスを管理します。サービスロールは、サービス仕様で USAGE 権限を付与されたエンドポイントのリストとともに定義します。
サービスの特定のエンドポイントに権限を付与するには、2段階のプロセスがあります。
サービスロールを定義する: ロール名と、 USAGE 権限を付与したい1つ以上のエンドポイントのリストを提供することによって、サービスロールを定義するためにサービス仕様を使用します。たとえば、以下の仕様の断片では、最上位
serviceRoles
フィールドは、特定のエンドポイントで USAGE 権限を持つ2つのサービスロールを定義しています。spec: ... serviceRoles: # Optional list of service roles - name: <svc_role_name1> endpoints: # endpoints that role can access - <endpoint_name1> - <endpoint_name2> - name: <svc_role_name2> endpoints: - <endpoint_name3> - <endpoint_name4>
他のロールにサービスロールを付与する: GRANT SERVICE ROLE コマンドを使用して、サービスロールを他のロール(アカウントロール、アプリケーションロール、データベースロール)に付与します。例:
GRANT SERVICE ROLE <service-name>!<svc_role_name1> TO ROLE <another-role>
サービスの使用¶
サービスを作成した後、同じアカウント(サービスを作成したアカウント)のユーザーは、次の3つのサポートされている方法のいずれかを使用してサービスを使用することができます。ユーザーは、必要な権限を持つロールにアクセスする必要があります。
SQL クエリからサービスを使用する: (サービス関数): サービスに関連付けられたユーザー定義関数(UDF)であるサービス関数を作成し、 SQL クエリで使用してサービスと通信します。例については、 チュートリアル1 をご参照ください。
Snowflake の外部からサービスを使用する (Ingress): 1つまたは複数のサービスエンドポイントをパブリックとして宣言し、サービスへのネットワークイングレスアクセスを許可することができます。例については、 チュートリアル1 をご参照ください。
他のサービスのサービスを使用する (サービス間通信): サービス間通信のために Snowflake が割り当てたサービス DNS 名を使用して、サービス間で通信することができます。例については、 チュートリアル 3 を参照してください。
注釈
ジョブサービスはジョブのように実行され、ジョブ完了時に終了します。ジョブ・サービスとの通信にサービス関数またはイングレスを使用することはサポートされていません。
ジョブ・サービスのどのエンドポイントにもサービス関数を関連付けることはできません。
パブリック・エンドポイントを定義する仕様では、ジョブ・サービスを作成できません。
ジョブ・サービスとのサービス間通信はサポート対象です。つまり、サービスとジョブ・サービスは互いに通信することができます。
以下のセクションで詳細を説明します。
サービス関数: SQL クエリからのサービスの使用¶
サービス関数とは、 CREATE FUNCTION (Snowpark Container Services) を使用して作成するユーザー定義関数(UDF)のことです。しかし、 UDF のコードを直接記述する代わりに、 UDF をサービスエンドポイントに関連付けます。サービス機能は、 HTTP または HTTPS プロトコルをサポートするサービスエンドポイントにのみ関連付けることができます。
たとえば、 チュートリアル1 では、サービス仕様で定義された1つのエンドポイント(echoendoint)を公開する echo_service
という名前のサービスを作成します。
spec:
…
endpoints:
- name: echoendpoint
port: 8080
echoendpoint
は、対応するポート(8080)を表す分かりやすいエンドポイント名です。このサービスエンドポイントと通信するには、次に示すように SERVICE と ENDPOINT パラメーターを指定してサービス関数を作成します。
CREATE FUNCTION my_echo_udf (text varchar)
RETURNS varchar
SERVICE=echo_service
ENDPOINT=echoendpoint
AS '/echo';
AS
パラメーターは、サービスコードへの HTTP パスを提供します。このパス値はサービスコードから取得します(例: チュートリアル 1 のservice.pyを参照)。例えば、以下のコード行は チュートリアル 1 の service.py
にあります。
@app.post("/echo")
def echo():
...
サービス関数を呼び出すと、Snowflakeは関連するサービスエンドポイントとパスにリクエストを誘導します。
注釈
サービス関数は、ジョブとではなく、サービスと通信するために使用されます。つまり、サービスのみ(ジョブではなく)をサービス関数に関連付けることができます。
サービスにデータを送信する際にバッチサイズを指定し、同時実行性を高める¶
サービスの複数のインスタンスを実行する場合は、オプションの MAX_BATCH_ROWS
パラメーターを指定してサービス関数を作成し、 バッチサイズ (Snowflakeがサービスにバッチで送信する最大行数)を制限することができます。たとえば、 MAX_BATCH_ROWS
が10で、 my_echo_udf
サービス関数を100入力行で呼び出したとします。Snowflakeは入力行をバッチに分割し、各バッチは最大10行を持ち、リクエスト本文にバッチ行を持つ一連のリクエストをサービスに送信します。処理に多くの時間がかかる場合は、バッチサイズを設定すると役に立ちます。行を利用可能なサーバー全体に分散することも役に立ちます。
サービス関数を変更するには、 ALTER FUNCTION を使用します。次の ALTER FUNCTION コマンドは、関連付けるサービスエンドポイントとバッチサイズを変更します。
ALTER FUNCTION my_echo_udf(VARCHAR)
SET SERVICE=other_service
ENDPOINT=otherendpoint
MAX_BATCH_ROWS=100
データ交換形式¶
サービス関数とコンテナー間のデータ交換では、Snowflakeは外部関数が使用するのと同じ形式に従います( データ形式 を参照)。たとえば、テーブル(input_table
)にデータ行が格納されているとします。
"Alex", "2014-01-01 16:00:00"
"Steve", "2015-01-01 16:00:00"
…
このデータをサービスに送信するには、これらの行をパラメーターとして渡してサービス関数を呼び出します。
SELECT service_func(col1, col2) FROM input_table;
Snowflakeは、一連のリクエストをリクエスト本文のデータ行のバッチと合わせて次の形式でコンテナーに送信します。
{
"data":[
[
0,
"Alex",
"2014-01-01 16:00:00"
],
[
1,
"Steve",
"2015-01-01 16:00:00"
],
…
[
<row_index>,
"<column1>",
"<column2>"
],
]
}
そして、コンテナーは次の形式で出力を返します。
{
"data":[
[0, "a"],
[1, "b"],
…
[ row_index, output_column1]
]
}
上記の出力例では、行(「a」、「b」)を持つ1列のテーブルを想定しています。
複数のサービスインスタンスが稼働している場合は、 MAX_BATCH_ROWS
パラメーターを使用してサービス関数を作成し、利用可能なすべてのサーバーに入力行を分散して処理することができます。詳細については、 サービスにデータを送信する際にバッチサイズを指定し、同時実行性を高める をご参照ください。
サービス関数の作成および管理に必要な権限¶
サービス関数を作成して管理するには、ロールに以下の権限が必要です。
サービス関数を作成するには: 現在のロールは、参照されるサービスに対する USAGE 権限を持っている必要があります。
**サービス関数を変更するには
サービス関数を使用するには: 現在のロールには、サービス関数に対する USAGE 権限が必要であり、サービス関数所有者ロールには、関連するサービスに対する USAGE 権限が必要です。
次のスクリプト例では、サービス関数の権限を付与する方法を示します。
USE ROLE service_owner;
GRANT USAGE ON service service_db.my_schema.my_service TO ROLE func_owner;
USE ROLE func_owner;
CREATE OR REPLACE test_udf(v VARCHAR)
RETURNS VARCHAR
SERVICE=service_db.my_schema.my_service
ENDPOINT=endpointname1
AS '/run';
SELECT test_udf(col1) FROM some_table;
ALTER FUNCTION test_udf(VARCHAR) SET
SERVICE = service_db.other_schema.other_service
ENDPOINT=anotherendpoint;
GRANT USAGE ON FUNCTION test_udf(varchar) TO ROLE func_user;
USE ROLE func_user;
SELECT my_test_udf('abcd');
イングレス: Snowflake外部からのサービスの使用¶
サービスは、1つまたは複数のエンドポイントを パブリック として公開して、ユーザーがパブリックウェブからサービスを使用できるようにします。この場合は、Snowflakeがアクセス制御を管理します。イングレスは HTTP または HTTPS のエンドポイントでのみ許可されます。
サービス仕様ファイルでエンドポイントをパブリックとしてマークします。
spec
...
endpoints
- name: <endpoint name>
port: <port number>
public: true
Snowflake外部からのパブリック エンドポイントアクセスと認証¶
サービスによって公開された公開エンドポイントには、誰もがアクセスできるわけではありません。サービスと同じ Snowflake アカウントで、パブリックエンドポイントの USAGE 権限を持つユーザーのみがパブリックエンドポイントにアクセスできます。この権限を付与するには、 サービス・ロール を使用します。
パブリックエンドポイントには、ブラウザーまたはプログラムを使用してアクセスできます。Snowflake はこれらのリクエストの認証に OAuth を使用します。
ブラウザーの使用によるパブリックエンドポイントのアクセス: ブラウザーを使用してパブリックエンドポイントにアクセスすると、Snowflakeはユーザー認証のために自動的にリダイレクトします。ユーザーはサインインする必要があり、その裏側で、ユーザーのサインインによりSnowflakeから OAuth トークンが生成されます。そして、 OAuth トークンを使用してサービスエンドポイントにリクエストが送信されます。
プログラムによるパブリック・エンドポイントへのアクセス: アプリケーションでは、 キーペア認証 を使って、パブリック・エンドポイントへのリクエストを認証することができます。コードでは、キーペアから JSON Web Token (JWT) を生成し、 JWT トークンを Snowflake と交換して OAuth トークンを生成し、 OAuth トークンを使用してサービスのパブリックエンドポイントへのリクエストを認証します。
チュートリアル 1 は、公開エンドポイント・アクセスをテストするための手順をステップ・バイ・ステップで説明します。
チュートリアル 1 に示すキーペア認証は、公開エンドポイントにアクセスする際にリクエストを認証するための推奨方法です。以下のコードは、キーペアを使用する代わりに認証に使用することができます。しかし、このコードが Python用Snowflake Connector の将来のバージョンで動作する保証はありません。この Python コードでは、まず Python コネクタを使って、あなたの ID を表すセッショントークンを生成します。その後、コードはセッショントークンを使用してパブリックエンドポイントにログインします。
import snowflake.connector import requests ctx = snowflake.connector.connect( user="<username>",# username password="<password>", # insert password here account="<orgname>-<acct-name>", session_parameters={ 'PYTHON_CONNECTOR_QUERY_RESULT_FORMAT': 'json' }) # Obtain a session token. token_data = ctx._rest._token_request('ISSUE') token_extract = token_data['data']['sessionToken'] # Create a request to the ingress endpoint with authz. token = f'\"{token_extract}\"' headers = {'Authorization': f'Snowflake Token={token}'} # Set this to the ingress endpoint URL for your service url = 'http://<ingress_url>' # Validate the connection. response = requests.get(f'{url}', headers=headers) print(response.text) # Insert your code to interact with the application hereコードで、
アカウント情報(
<組織名>-<アカウント名>
)が分からない場合は、チュートリアルの 共通セットアップ をご参照ください。SHOW ENDPOINTS を使用すると、サービスが公開しているパブリックエンドポイントの
ingress_url
を取得できます。
イングレスリクエストのユーザー固有ヘッダー¶
Snowflakeは、イングレスエンドポイントのリクエストを受信すると、自動的に HTTP リクエストとともに以下のヘッダーをコンテナに渡します。
Sf-Context-Current-User: <user_name>
コンテナコードにより、オプションでこれらのヘッダーを読み取り、呼び出し元が誰であるかを把握し、異なるユーザーに対してコンテキスト固有のカスタマイズを適用することができます。さらに、Snowflakeではオプションで Sf-Context-Current-User-Email
ヘッダーを含めることができます。このヘッダーを含めるには、 Snowflakeサポート までご連絡ください。
サービス間通信¶
サービスは、Snowflakeが各サービスに自動的に割り当てる DNS 名を使用して相互に通信できます。例については、 チュートリアル3 をご参照ください。サービス間の通信を可能にするためだけにサービスエンドポイントを作成する場合は、 TCP プロトコルを使用する必要があることに注意してください。
DNS 名形式は以下のとおりです。
<service-name>.<schema-name>.<db-name>.snowflakecomputing.internal
サービスの DNS 名を取得するには、 SHOW SERVICES (または DESCRIBE SERVICE )を使用します。前述の DNS 名はフルネームです。同じスキーマで作成されたサービスでは、 <サービス名>
を使用するだけで通信できます。同じデータベースにありながらスキーマが異なるサービスでは、 <サービス名>.<スキーマ名>
のようにスキーマ名を指定する必要があります。
Snowflakeは、同じロールによって作成されたサービス間のネットワーク通信を許可し、異なるロールによって作成されたサービス間のネットワーク通信をブロックします。サービス同士が通信できないようにする場合(セキュリティなどの理由により)は、異なるSnowflakeロールを使用してこれらのサービスを作成します。
DNS 名には以下の制限があります。
データベース名、スキーマ名、サービス名は、有効な DNS ラベルにする必要があります。(https://www.ietf.org/rfc/rfc1035.html#section-2.3.1 もご参照ください)。それ以外の場合は、サービスの作成に失敗します。
Snowflakeは、名前(データベース、スキーマ、およびサービス名)のアンダースコア(_)を DNS 名ではダッシュ(-)に置き換えます。
Snowflakeはサービスの DNS 名を更新しないため、サービスを作成した後はデータベースやスキーマ名を変更しないでください。
DNS 名は、同じアカウントで実行されているサービス間のSnowflake内部での通信にのみ使用されます。インターネットからはアクセスできません。
権限¶
権限 |
使用状況 |
メモ |
---|---|---|
USAGE |
サービスと通信するには、 USAGE 権限がサービスエンドポイントで 必要になります。サービス関数の作成、パブリックエンドポイントの使用、他のサービスからの接続に必要です。 |
|
MONITOR |
サービスをモニターし、ランタイムのステータスを取得します。 |
|
OPERATE |
サービスを中断または再開します。 |
|
OWNERSHIP |
サービスを包括的に制御します。特定のオブジェクトに対して一度にこの権限を保持できるのは、1つのロールのみです。 |
|
ALL [ PRIVILEGES ] |
OWNERSHIP を除く、サービスに対するすべての権限を付与します。 |