サービス仕様リファレンス¶
Snowpark Container Services仕様は、 YAML (https://yaml.org/spec/)にあります。サービスやジョブの構成と実行に必要な情報をSnowflakeに提供します。
一般的な構文は次のとおりです。
spec:
containers: # container list
- name: <name>
image: <image-name>
command: # optional list of strings
- <cmd>
- <arg1>
args: # optional list of strings
- <arg2>
- <arg3>
- ...
env: # optional
<key>: <value>
<key>: <value>
...
readinessProbe: # optional
port: <TCP port-num>
path: <http-path>
volumeMounts: # optional list
- name: <volume-name>
mountPath: <mount-path>
- name: <volume-name>
...
resources: # optional
requests:
memory: <memory-reserved>
nvidia.com/gpu: <count>
cpu: <cpu-units>
limits:
memory: <memory-reserved>
nvidia.com/gpu: <count>
cpu: <cpu-units>
secrets: # optional list
- snowflakeSecret:
secretKeyRef:
envVarName: # specify this or directoryPath
directoryPath: # specify this or envVarName
endpoints: # optional endpoint list
- name: <name>
port: <TCP port-num>
public: <true / false>
protocol : < TCP / HTTP / HTTPS >
- name: <name>
...
volumes: # optional volume list
- name: <name>
source: local | @<stagename> | memory
size: <amount-of-memory> # specify if memory is the volume source
- name: <name>
source: local | @<stagename> | memory
size: <amount-of-memory> # specify if memory is the volume source
...
logExporters:
eventTableConfig:
logLevel: <INFO | ERROR | NONE>
一般的なガイドライン¶
サービス/ジョブ仕様には、これら最上位の spec
フィールドがあります。
spec.containers
(必須): 1つ以上のアプリケーションコンテナーのリスト。コンテナー化されたアプリケーションには、少なくとも1つのコンテナーが必要です。spec.endpoints
(オプション): サービスが公開するエンドポイントのリスト。エンドポイントにパブリックを選択し、サービスへのネットワークイングレスアクセスを許可することもできます。spec.volumes
(オプション): コンテナーで使用するストレージボリュームのリスト。spec.logExporters
(オプション): このフィールドは、アカウントのイベントテーブルにエクスポートされるコンテナーログのレベルを管理します。
name
フィールド(コンテナー名、エンドポイント名、ボリューム名)には、以下の形式ガイドラインが適用されます。
長さは63文字まで
小文字の英数字または'-'を含めることができる
英文字で始まること
英数字で終わること
注意
Snowflakeサービスを使用する場合、お客様は、個人データ(ユーザーオブジェクト向け以外)、機密データ、エクスポート制限データ、またはその他の規制されたデータがメタデータとして入力されていないことを確認する必要があります。詳細については、 Snowflakeのメタデータフィールド をご参照ください。
以下のセクションでは、最上位 spec
フィールドのそれぞれについて説明します。
spec.containers
フィールド(必須)¶
containers
フィールドは、アプリケーション内の OCI コンテナーのリストです。各コンテナーについて、 name
と image
のみが必須フィールドです。 image
フィールドは、SnowflakeアカウントのSnowflakeイメージリポジトリにアップロードしたイメージの名前を指します。例:
spec:
containers:
- name: echo
image: /tutorial_db/data_schema/tutorial_repository/echo_service:dev
サービス(またはジョブ)を作成すると、Snowflakeはこれらのコンテナーを指定されたコンピューティングプール内の単一ノード上で実行し、同じネットワークインターフェイスを共有します。複数のサービスインスタンスを実行することができます。その場合、実行されているコンテナーの各セットはサービスインスタンスと呼ばれます。
注釈
現在、Snowpark Container Servicesにはlinux/amd64プラットフォームイメージが必要です。
以下のセクションでは、 containers
フィールドの型について説明します。
containers.command
および containers.args
フィールド¶
これらのオプションフィールドを使用すると、 Dockerfile
(アプリケーションイメージの一部)で定義されたコンテナーのエントリポイント(コンテナーが実行するコマンドとパラメーター)を、アプリケーションイメージを再作成することなく上書きできます。
containers.command
はDockerfile
ENTRYPOINT
を上書きします。これにより、コンテナー内で別の実行ファイルを実行することができます。containers.args
はDockerfile
CMD
を上書きします。これにより、コマンド(実行ファイル)に異なる引数を付与することができます。
例
Dockerfile
には、以下のコードが含まれています。
ENTRYPOINT ["python3", "main.py"]
CMD ["Bob"]
これらの Dockerfile
エントリは python3
コマンドを実行し、 main.py
と Bob
の2つの引数を渡します。これらの値は、以下のように仕様ファイルで上書きすることができます。
ENTRYPOINT を上書きするには、仕様ファイルに
containers.command
フィールドを追加します。spec: containers: - name: echo image: <image_name> command: - python3.9 - main.py
引数「Bob」を上書きするには、仕様ファイルに
containers.args
フィールドを追加します。spec: containers: - name: echo image: <image_name> args: - Alice
containers.env
フィールド¶
コンテナー内のすべてのプロセスに渡す環境変数を指定するには、 containers.env
フィールドを使用します。
spec:
containers:
- name: <name>
image: <image_name>
env:
ENV_VARIABLE_1: <value1>
ENV_VARIABLE_2: <value2>
…
…
例
チュートリアル1 では、値が明示的に設定されていない場合に、アプリケーションコード(echo_service.py
)がデフォルト値で環境変数を読み取ります。
CHARACTER_NAME = os.getenv('CHARACTER_NAME', 'I')
SERVER_PORT = os.getenv('SERVER_PORT', 8080)
CHARACTER_NAME
: Echoサービスは、文字列(例: 「Hello」)を含む HTTP POST リクエストを受信すると、「I said Hello」を返します。このデフォルト値は、仕様ファイルで上書きすることができます。たとえば、値を「Bob」に設定すると、Echoサービスは「Bob said Hello」という応答を返します。SERVER_PORT
: このデフォルト構成では、Echoサービスはポート8080でリッスンします。デフォルト値を上書きして、別のポートを指定することができます。
以下の仕様ファイルは、これらの環境変数の値両方を上書きします。
spec:
containers:
- name: echo
image: <image_name>
env:
CHARACTER_NAME: Bob
SERVER_PORT: 8085
endpoints:
- name: echo-endpoint
port: 8085
サービスがリッスンするポート番号を変更したため、仕様ではエンドポイント(endpoints.port
フィールド値)も更新されていることに注意してください。
containers.readinessProbe
フィールド¶
containers.readinessProbe
オブジェクトを使用して、アプリケーションでSnowflakeにreadinessプローブを付与します。Snowflakeはこのプローブを呼び出して、アプリケーションがいつリクエストを処理できるようになったかを判断します。
Snowflakeは、指定されたポートおよびパスで、指定されたreadinessプローブに対して HTTP GET リクエストを実行し、健全なコンテナーのみがトラフィックを提供できるように、 HTTP 200 OK ステータスを返すサービスを探します。
以下のフィールドを使用して、必要な情報を入力します。
port
: サービスがreadinessプローブリクエストをリッスンしているネットワークポート。このポートをエンドポイントとして宣言する必要はありません。path
: Snowflakeは、このパスを持つサービスに HTTP GET リクエストを実行します。
例
チュートリアル1では、アプリケーションコード(echo_python.py
)は以下のreadinessプローブを実装します。
@app.get("/healthcheck")
def readiness_probe():
したがって、仕様ファイルには containers.readinessProbe
フィールドが含まれます。
spec:
containers:
- name: echo
image: <image_name>
env:
SERVER_PORT: 8088
CHARACTER_NAME: Bob
readinessProbe:
port: 8088
path: /healthcheck
endpoints:
- name: echo-endpoint
port: 8088
readinessプローブが指定するポートは、構成されたエンドポイントである必要はありません。使用するサービスは、readinessプローブ専用に別のポートをリッスンすることができます。
containers.volumeMounts
フィールド¶
spec.volumes
フィールドと spec.containers.volumeMounts
フィールドは連動しているため、1つのセクションでまとめて説明します。詳細については、 spec.volumes フィールド(オプション) をご参照ください。
containers.resources
フィールド¶
Snowflakeは、利用可能なコンピューティングプールリソースを使用してアプリケーションを実行する方法を決定します。サービスインスタンスのリソース要件を明示的に示し、仕様に適切な制限を設定することを推奨します。指定するリソースは、コンピューティングプール内のノードのインスタンスファミリーに制約されることに注意してください。詳細については、 CREATE COMPUTE POOL をご参照ください。
Snowflakeは、 containers.resources.requests
で指定されたリソースが提供されることを保証し、また、示された containers.resources.limits
以上のリソースをサービスが使用することを防ぎます。以下のリソースのリクエストと制限を指定できます。
memory
: アプリケーションコンテナーに必要なメモリ。値を表す単位は10進数でも2進数でも構いません。たとえば、2Gは2,000,000,000バイトのリクエストを表します。詳細については、 単位について をご参照ください。cpu
: 仮想コア(vCPU)単位を指します。たとえば、1 CPU 単位は1 vCPU と等価です。0.5のような小数リクエストも可能で、500mと表すこともできます。詳細については、 単位について をご参照ください。nvidia.com/gpu
: GPUs が必要な場合は、それらをリクエストしなければならず、同じ数量に対してlimit
も指定する必要があります。コンテナーが GPU の容量に対するリクエストと制限を指定しない場合は、 GPUs にアクセスできません。リクエストできる GPUs の数は、コンピューティングプールを作成するときに選択したINSTANCE_TYPE
がサポートする最大 GPUs によって制限されます。詳細については、 CREATE COMPUTE POOL をご参照ください。
Snowflakeが仕様ファイルに明示的に含まれるリソースを割り当てることができない場合は、サービスを作成することはできます(CREATE SERVICE を使用)が、サービスステータスには、リソース不足のためにサービスをスケジュールできないことが示されます。
例1
以下の仕様では、 containers.resources
フィールドにコンテナーのリソース要件を説明します。
spec:
containers:
- name: resource-test-gpu
image: ...
resources:
requests:
memory: 2G
cpu: 0.5
nvidia.com/gpu: 1
limits:
memory: 4G
nvidia.com/gpu: 1
この例では、Snowflakeはコンテナーに対して、少なくとも2 GB のメモリ、1個の GPU および半個の CPU コアを割り当てるようにリクエストされます。同時に、コンテナーは4 GB を超えるメモリと1個を超える GPU を使用することが禁止されます。
例2
2つのノードのコンピューティングプールを作成します。各ノードに16 GB のメモリと1個の GPU があります。
CREATE COMPUTE POOL tutorial_compute_pool MIN_NODES = 2 MAX_NODES = 2 INSTANCE_FAMILY = gpu_nv_s
Snowflakeにサービスのインスタンスを2つ実行するように依頼するサービスを作成します。
CREATE SERVICE echo_service MIN_INSTANCES=2 MAX_INSTANCES=2 IN COMPUTE POOL tutorial_compute_pool FROM @<stage_path> SPEC=<spec-file-stage-path>;
MIN_INSTANCES
とMAX_INSTANCES
の両方を2に設定します。したがって、Snowflakeはサービスのインスタンスを2つ実行します。
アプリケーションの仕様にリソース要件を明示的に含めない場合、Snowflakeはこれらのインスタンスを同じノードで実行するか、コンピューティングプール内の異なるノードで実行するかを決定します。
リソース要件を含めるようにし、コンテナー用に10 GB のメモリをリクエストします。
- name: resource-test image: ... resources: requests: memory: 10G
コンピューティングプールノードには16 GB のメモリがあり、Snowflakeは同じノード上で2つのコンテナーを実行できません。Snowflakeは2つのサービスインスタンスをコンピューティングプールの別々のノードで実行します。
コンテナー用に1 GB のメモリと1個の GPU をリクエストします。
spec: containers: - name: resource-test-gpu image: ... resources: requests: memory: 2G nvidia.com/gpu: 1 limits: nvidia.com/gpu: 1
コンテナーごとに1個の GPU をリクエストしており、各ノードには1個の GPU しかありません。この場合、メモリには問題がありませんが、Snowflakeは1つのノードに両方のサービスをスケジュールすることができません。この要件により、Snowflakeは2つのコンピューティングプールノードで2つのサービスインスタンスを実行することになります。
containers.secrets
フィールド¶
secrets: # optional list
- snowflakeSecret:
secretKeyRef:
envVarName: # specify this or directoryPath
directoryPath: # specify this or envVarName
containers.secrets
を使用して シークレット オブジェクトをSnowflakeに渡し、サービスまたはジョブが外部エンドポイント(Snowflake外部)と通信するときにコンテナーが認証に使用できるようにします。詳細については、 Snowflakeシークレット使用によるコンテナー認証情報の引き渡し をご参照ください。
snowflakeSecret
(必須): Snowflake シークレット オブジェクト名。secretKeyRef
: シークレット内のキーの名前。このフィールドが入力されていると、Snowflakeはこのキー参照に関連付けられた値をコンテナーに渡します。環境変数としてマウントされた基本認証シークレットに必要です。このフィールドを指定するのは、コンテナーの環境変数にシークレットを渡すときのみです。envVarName
: シークレットを保持する環境変数の名前。これか、directoryPath
フィールドのどちらかが必要です。directoryPath
: シークレットをコピーするコンテナー内のディレクトリパス。Snowflakeは、指定されたこのディレクトリにあるシークレットキーごとに1つのファイルを入力します。directoryPath
を指定する場合は、secretKeyRef
は指定しないでください。これか、envVarName
フィールドのどちらかが必要です。
詳細については、 Snowflakeシークレットのコンテナーへの引き渡し をご参照ください。
spec.endpoints
フィールド(オプション)¶
spec.endpoints
フィールドを使用して、アプリケーションが公開する TCP ネットワークポートの名前のリストを指定します。Snowpark Container Servicesは、多くのエンドポイントにゼロを公開する可能性があります。以下のフィールドを使用してエンドポイントを説明します。
name
: エンドポイントの一意の名前。サービス関数内でエンドポイントを参照する場合は、この名前を指定します。port
: アプリケーションがリッスンしているネットワークポート。protocol
: エンドポイントがサポートするプロトコル。サポートされている値は、 TCP、 HTTP、および HTTPS です。デフォルトでは、プロトコルは HTTP です。このエンドポイントがパブリックまたはサービス関数のターゲットである場合、プロトコルは HTTP または HTTPS にする必要があります(サービスの使用 を参照)。public
: このエンドポイントをインターネットからアクセスできるようにする場合は、このフィールドをtrue
に設定します。
注釈
Snowflakeは、パブリックアクセスに対して認証および承認チェックを実行し、サービスを使用する権限のあるSnowflakeユーザーのみがアクセスできるようにします。
例
以下は、 チュートリアル1 で使用したアプリケーション仕様です。
spec:
container:
- name: echo
image: <image-name>
env:
SERVER_PORT: 8000
CHARACTER_NAME: Bob
readinessProbe:
port: 8000
path: /healthcheck
endpoint:
- name: echoendpoint
port: 8000
public: true
このアプリケーションコンテナーは1つのエンドポイントを公開します。また、オプションの public
フィールドも含まれており、Snowflake外部(インターネットアクセス)からのエンドポイントへのアクセスを有効にします。デフォルトでは、 public
は false
です。
spec.volumes
フィールド(オプション)¶
このセクションでは、 spec.volumes
と spec.containers.volumeMounts
の両フィールドについて説明します。 volumes
は共有ファイルシステムを定義します。 volumeMount
は、コンテナー内のどこにボリュームが出現するかを定義します。複数のコンテナーで同じボリュームを共有できます。したがって、 volumes
は spec
レベルのフィールドであり、 volumeMount
はコンテナー仕様の一部です。
これらのフィールドを使用して、ボリュームとボリュームマウントの両方を説明します。
コンテナーで利用可能なボリュームを指定するには
spec.volumes
を使用します。volumes
はリストです。つまり、複数のボリュームが存在する可能性があります。以下のフィールドを使用してボリュームを説明します。name
: ボリュームの一意の名前。これは、spec.containers.volumeMounts.name
によって参照されます。source
:local
、memory
、または"@<ステージ名>"
のいずれか。uid
: Snowflakeステージボリュームの場合、これはマウントされたファイルのユーザー識別子です。gid
: Snowflakeステージボリュームの場合、これはマウントされたファイルのグループ識別子です。size
: メモリボリュームの場合、これはボリュームのサイズです。
コンテナーのファイルシステムで、指定したボリュームがマウントされている場所を示すには
spec.containers.volumeMounts
を使用します。containers.volumeMounts
もリストです。つまり、各コンテナーは複数のボリュームマウントを持つことができる。以下のフィールドを使用してボリュームマウントを説明します。name
: マウントするボリュームの名前。単一のコンテナーは同じボリュームを複数回参照できます。mountPath
: コンテナーをマウントするためのボリュームへのファイルパス。
Snowflakeは、アプリケーションコンテナーが使用するボリューム型として、ローカルボリューム、メモリ、Snowflakeステージをサポートしています。
ローカルボリューム: サービスインスタンス内のコンテナーは、ローカルディスクを使用してファイルを共有できます。たとえば、アプリケーションにアプリケーションコンテナーとログアナライザーの2つのコンテナーがある場合、アプリケーションはローカルボリュームにログを書き込むことができ、ログアナライザーはログを読み取ることができます。
サービスの複数のインスタンスを実行している場合、ボリュームを共有できるのはサービスインスタンスに属するコンテナーだけであることに注意してください。異なるサービスインスタンスに属するコンテナーは、ボリュームを共有しません。
メモリ: RAM に格納されたファイルシステムをコンテナー用に使用できます。
Snowflakeステージ: Snowflakeステージを作成し、ステージングされたファイルへの便利なアクセスをコンテナーに付与できます。Snowflakeステージをマウントする場合は、以下の条件が適用されます。
外部ステージはサポートされていません。SSE 暗号化(内部ステージパラメーター を参照)を使用するSnowflake内部ステージのみがサポートされます。このようなステージを作るには、 CREATE STAGE を使用します。
CREATE STAGE my_stage ENCRYPTION = (type = 'SNOWFLAKE_SSE');
ステージまたはサブディレクトリ、たとえば
@my_stage
や@my_stage/folder
をステージでマウントすることができます。ステージで、@my_stage/folder/file
のようなファイルをマウントすることはできません。サービスロールは、マウントされたステージへのアクセス向けとしてコンテナーに付与される権限を決定します。サービスロールは、サービス/ジョブを作成するために使用されるロールです。また、サービス/ジョブがSnowflakeとのすべてのやり取りで使用するロールでもあります。
たとえば、ステージでサービスロールが WRITE 権限を持っていない場合、そのステージのマウントは読み取り専用になります。つまり、コンテナーができるのはステージからファイルを読み取ることのみです。サービスロールがステージで WRITE 権限を持っている場合、そのステージのマウントは読み取りと書き込みの両方をサポートします。Snowflakeは、ファイルの更新を非同期でアップロードします。
Snowflakeステージをマウントするコンテナーは通常、ルートユーザーとして実行されます。しかし、コンテナーが非ルートユーザーとして実行されることもあります。例:
アプリケーションがサードパーティライブラリを使用する場合、ライブラリはコンテナー内でアプリケーションコードを実行するために非ルートユーザーを使用します。
セキュリティなどの他の理由から、コンテナー内で非ルートユーザーとしてアプリケーションを実行することもあります。
ファイルユーザー権限に関連する潜在的なエラーを避けるために、コンテナーの UID (ユーザー ID)と GID (グループ ID)を仕様の一部として設定することが重要です。これは特に、コンテナー内でアプリケーションの起動や実行に特定のユーザーとグループを使用するコンテナーに関係があります。適切な UID と GID を設定すると、非ルートユーザーとして実行するコンテナーを使用できます。例:
spec: ... volumes: - name: stagemount source: "@test" uid: <UID-value> gid: <GID-value>
Snowflakeはこの情報を使用して、適切な権限でステージをマウントします。
コンテナーの UID と GID を取得するには、
docker run
を使用してコンテナーをローカルで実行します。docker container list
コマンドを使用してコンテナー ID を検索します。サンプル出力の一部は次のとおりです。CONTAINER ID IMAGE COMMAND —---------------------------------------------------------- a6a1f1fe204d tutorial-image "/usr/local/bin/entr…"
コンテナー内で
docker id
コマンドを実行し、 UID と GID を取得します。docker exec -it <container-id> id
サンプル出力:
uid=0(root) gid=0(root) groups=0(root)
例
機械学習アプリケーションには、以下の2つのコンテナーが含まれています。
メインアプリケーション用
app
コンテナーログを収集し、Amazon S3にアップロードする
logger-agent
コンテナー。
これらのコンテナーは、以下の2つのボリュームを使用します。
local
ボリューム: このアプリケーションは、ログエージェントが読み取るログを書き込みます。Snowflakeステージ、
@model_stage
: メインアプリケーションはこのステージからファイルを読み取ります。
以下の仕様例では、 app
コンテナーは、 logs
と models
の両方のボリュームをマウントし、 logging-agent
コンテナーは logs
ボリュームのみをマウントします。
spec: containers: - name: app image: <image1-name> volumeMounts: - name: logs mountPath: /opt/app/logs - name: models mountPath: /opt/models - name: logging-agent image: <image2-name> volumeMounts: - name: logs mountPath: /opt/logs volumes: - name: logs source: local - name: models source: "@model_stage"
サービスの複数のインスタンスが実行されている場合、サービスインスタンス内の logging-agent
と app
コンテナーは logs
ボリュームを共有します。 logs
ボリュームはサービスインスタンス間では共有されません。
これらのボリュームに加えて、 app
コンテナーが2 GB メモリボリュームも使用する場合は、仕様を修正して volumes
リストにボリュームを含め、 app
コンテナー volumeMounts
リストに別のボリュームマウントも追加します。
spec: containers: - name: app image: <image1-name> volumeMounts: - name: logs mountPath: /opt/app/logs - name: models mountPath: /opt/models - name: my-mem-volume mountPath: /dev/shm - name: logging-agent image: <image2-name> volumeMounts: - name: logs mountPath: /opt/logs volumes: - name: logs source: local - name: models source: "@model_stage" - name: "my-mem-volume" source: memory size: 2G
ボリューム source
として memory
を指定する場合は、メモリサイズを示す volumes.size
フィールドも指定する必要があることに注意してください。指定できるメモリサイズの単位については、 単位について をご参照ください。
spec.logExporters
フィールド(オプション)¶
spec.logExporters
を使用して、Snowflakeがアプリケーションログを収集する方法を構成します。Snowflakeは、出力をアプリケーションコンテナー内のコードから標準出力または標準エラーに収集します。
Snowflakeはこれらのログをアカウント内の イベントテーブル にエクスポートします。詳細については、 ローカルコンテナーログへのアクセス をご参照ください。 spec.logExporters.eventTableConfig
を使用して、どのログをイベントテーブルに保存するかを示します。
logExporters:
eventTableConfig:
logLevel: < INFO | ERROR | NONE >
サポートされている logLevel
値は次のとおりです。
INFO
: すべてのユーザーログをエクスポートします。ERROR
: エラーログのみをエクスポートします。Snowflakeは標準エラーストリームからログのみをエクスポートします。NONE
(デフォルト): イベントテーブルにログをエクスポートしません。
単位について¶
サービス仕様は、複数の場所で数値を取得します。Snowpark Container Servicesは、これらの値を表現するためのさまざまな単位をサポートしています。大きな値と小さな値には、表示のように2進数と10進数の単位を使うことができます。以下のリストでは、「#」は整数値を表します。
2進数単位:
numberKi
はnumber*1024
を意味します。たとえば、memory: 4Ki
はmemory: 4096
と等価です。numberMi
はnumber*1024^2
を意味します。numberGi
はnumber*1024^3
を意味します。
10進数単位:
numberk
はnumber*10^3
を意味します。たとえば、memory: 4k
はmemory: 4000
と等価です。numberM
はnumber*10^6
を意味します。numberG
はnumber*10^9
を意味します。
分数単位:
numberm
はnumber*0.001
を意味します。たとえば、cpu: 500m
はcpu: 0.5
と等価です。