Snowpark Container Services : utilisation des tâches

Snowpark Container Services vous permet de déployer, de gérer et d’adapter facilement des applications conteneurisées. Après avoir créé une application et chargé l’image de l’application dans un référentiel de votre compte Snowflake, vous pouvez exécuter vos conteneurs d’application en tant que service ou tâche. Cette rubrique explique comment utiliser des services.

Un service est de longue durée et, comme un service Web, ne se termine pas automatiquement. Une fois que vous avez créé un service, Snowflake gère le service en cours d’exécution. Par exemple, si un conteneur de service s’arrête, pour quelque raison que ce soit, Snowflake redémarre ce conteneur afin que le service fonctionne sans interruption. Si votre service a besoin de plus de ressources, par exemple plus de puissance de calcul, Snowflake fournit des nœuds supplémentaires dans le pool de calcul.

Opérations de services de base

Snowpark Container Services fournit un ensemble de commandes SQL que vous pouvez utiliser pour créer et gérer un service. Ces commandes comprennent, entre autres : CREATE SERVICE, ALTER SERVICE, DROP SERVICE, SHOW SERVICES et DESC[RIBE] SERVICE.

Les informations minimales requises pour créer un service incluent :

  • Une spécification de service : cette spécification fournit à Snowflake les informations nécessaires à l’exécution de votre service. La spécification est un fichier YAML. Vous pouvez définir la spécification directement dans une instruction CREATE SERVICE, ou charger la spécification vers une zone de préparation Snowflake et faire référence aux informations de la zone de préparation dans l’instruction CREATE SERVICE.

    Dans la plupart des cas, au cours du développement, vous pouvez choisir la spécification en ligne. Cependant, lorsque vous déployez le service dans un environnement de production, il est conseillé d’appliquer le principe de séparation des préoccupations et de charger la spécification dans une zone de préparation.

  • Un pool de calcul : Snowflake exécute votre service dans le pool de calcul spécifié.

Exemples

  • Créer un service à l’aide d’une spécification en ligne :

    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
       $$;
    
    Copy
  • Créer un service en utilisant les informations de la zone de préparation :

    CREATE SERVICE echo_service
      IN COMPUTE POOL tutorial_compute_pool
      FROM @tutorial_stage
      SPECIFICATION_FILE='echo_spec.yaml';
    
    Copy

Après avoir créé un service, vous pouvez utiliser la commande ALTER SERVICE pour suspendre ou reprendre le service.

Créer plusieurs instances de service et configurer la mise à l’échelle automatique

Par défaut, Snowflake exécute une instance du service dans le pool de calcul spécifié. Pour gérer des charges de travail importantes, vous pouvez exécuter plusieurs instances de service en définissant les propriétés MIN_INSTANCES et MAX_INSTANCES, qui spécifient le nombre minimum d’instances du service au début et le nombre maximum d’instances que Snowflake peut ajouter en cas de besoin.

Exemple

CREATE SERVICE echo_service
   IN COMPUTE POOL tutorial_compute_pool
   FROM @tutorial_stage
   SPECIFICATION_FILE='echo_spec.yaml'
   MIN_INSTANCES=2
   MAX_INSTANCES=4;
Copy

Lorsque plusieurs instances de service sont en cours d’exécution, Snowflake fournit automatiquement un équilibreur de charge pour répartir les requêtes entrantes.

Pour configurer Snowflake afin qu’il évalue automatiquement le nombre d’instances de service en cours d’exécution, procédez comme suit :

  1. Spécifiez les exigences en matière de mémoire et de CPU pour votre instance de service dans le fichier de spécification du service. Pour plus d’informations, voir le champ container.resources.

    Exemple

    resources:
      requests:
       memory: <memory-reserved>
       cpu: <cpu-units>
    
    Copy
  2. Lors de l’exécution de la commande CREATE SERVICE, définissez les paramètres MIN_INSTANCES et MAX_INSTANCES. Vous pouvez également utiliser ALTER SERVICE pour modifier ces valeurs.

Snowflake commence par créer le nombre minimum d’instances de service sur le pool de calcul spécifié, puis augmente automatiquement le nombre d’instances en fonction des besoins. Snowflake utilise un seuil de 80 % (pour le CPU et la mémoire) afin d’augmenter ou de réduire le nombre d’instances de service.

À tout moment, une ou plusieurs instances de service peuvent être en cours d’exécution sur le pool de calcul spécifié. Snowflake surveille en permanence l’utilisation des ressources (mémoire ou CPU) dans le pool de calcul, en agrégeant les données d’utilisation de toutes les instances de service en cours d’exécution.

Lorsque l’utilisation agrégée des ressources (pour toutes les instances de service) dépasse 80 %, Snowflake déploie une instance de service supplémentaire dans le pool de calcul. Si l’utilisation des ressources agrégées tombe en dessous de 80 %, Snowflake procède à une diminution en supprimant une instance de service en cours d’exécution. Snowflake utilise une fenêtre de stabilisation de cinq minutes pour éviter les mises à l’échelle fréquentes.

Notez les comportements de mise à l’échelle suivants :

  • La mise à l’échelle des instances de service est limitée par les paramètres MIN_INSTANCES et MAX_INSTANCES configurés pour le service.

  • Si une mise à l’échelle est nécessaire et que les nœuds du pool de calcul n’ont pas la capacité de ressources nécessaire pour démarrer une autre instance de service, la mise à l’échelle automatique du pool de calcul peut être déclenchée. Pour plus d’informations, voir Mise à l’échelle automatique des nœuds d’un pool de calcul.

  • Si vous spécifiez les paramètres MAX_INSTANCES et MIN_INSTANCES lors de la création d’un service, mais que vous ne spécifiez pas les exigences en matière de mémoire et de CPU pour votre instance de service dans le fichier de spécification du service, aucune mise à l’échelle automatique ne se produit ; Snowflake démarre avec le nombre d’instances spécifié par la propriété MIN_INSTANCES et ne fera pas de mise à l’échelle automatique.

Liste des services

Vous pouvez utiliser diverses commandes SHOW SERVICES pour dresser la liste des services actuels :

  • SHOW SERVICES: répertorie les services de la base de données et du schéma actuels pour lesquels vous disposez d’autorisations.

  • SHOW SERVICES IN ACCOUNT : répertorie les services de votre compte Snowflake, quel que soit la base de données ou le schéma auquel ils appartiennent. Ceci est utile si vous avez des services Snowflake créés dans plusieurs bases de données et schémas dans votre compte. Comme toutes les autres commandes, SHOW SERVICES IN ACCOUNTS est limitée par les privilèges et ne renvoie que les services pour lesquels le rôle que vous utilisez dispose d’autorisations de visualisation.

  • SHOW SERVICES IN SCHEMA : répertorie les services dans le schéma spécifié.

Répertorier des services d’un pool de calcul spécifique se fait en deux étapes :

  1. Exécutez SHOW SERVICES pour obtenir une liste de services.

  2. Recherchez dans la liste de la requête précédente (à l’aide de RESULT_SCAN) les services du pool de calcul concerné.

Exemple

Dans l’exemple de script suivant, la commande SHOW SERVICES répertorie d’abord les services de la base de données et du schéma actuels dont le nom contient une chaîne de caractères spécifique.

Ensuite, la requête SELECT filtre le jeu de résultats pour ne renvoyer que les services du pool de calcul spécifié. Notez que la requête utilise la fonction RESULT_SCAN pour obtenir le jeu de résultats de la commande SHOW SERVICES précédente.

SHOW SERVICES like '%tutorial%' in account;
SELECT *
    FROM TABLE(RESULT_SCAN(last_query_id()))
    WHERE "compute_pool" = 'TUTORIAL_COMPUTE_POOL';
Copy

Suivi d’un service

Utilisez SYSTEM$GET_SERVICE_STATUS pour obtenir le statut d’exécution détaillé d’un service. Par exemple, vous pouvez appeler cette fonction pour déterminer si le service est toujours en cours d’exécution ou si le service n’a pas démarré. Si le service n’a pas démarré, la fonction fournit plus de détails sur l’échec.

Lorsque vous appelez cette fonction, indiquez le nom du service.

Exemple

CALL SYSTEM$GET_SERVICE_STATUS('echo_service');
Copy

Voici des exemples de sorties :

  • Exemple de sortie d’un service qui fonctionne avec une instance et un conteneur :

    [
       {
          "status":"READY",
          "message":"Running",
          "containerName":"echo",
          "instanceId":"0",
          "serviceName":"ECHO_SERVICE",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       }
    ]
    
    Copy

    instanceId est l’ID d’instance de service à laquelle appartient le conteneur. Si vous exécutez deux instances de ce service, la sortie comprend deux objets de ce type et fournit le statut du conteneur pour chaque instance de service. Dans ce cas, les IDs d’instance sont 0 et 1.

  • Exemple de sortie d’un service qui fonctionne avec une instance et trois conteneurs :

    [
       {
          "status":"READY",
          "message":"Running",
          "containerName":"some-proxy",
          "instanceId":"0",
          "serviceName":"example_service",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_service_image_proxy:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       },
       {
          "status":"READY",
          "message":"Running",
          "containerName":"some-server",
          "instanceId":"0",
          "serviceName":"example_service",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_server:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       },
       {
          "status":"READY",
          "message":"Running",
          "containerName":"movies",
          "instanceId":"0",
          "serviceName":"example_service",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_movies:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       }
    ]
    
    Copy

    La sortie comprend des informations sur le statut de chaque conteneur. Tous ces conteneurs appartiennent à l’instance de service unique qui possède l’ID d’instance 0.

SYSTEM$GET_SERVICE_STATUS prend un argument facultatif timeout_secs. Si timeout_secs n’est pas spécifié ou est spécifié avec la valeur 0, la fonction renvoie immédiatement le statut actuel. Si timeout_secs est spécifié, Snowflake attend que le service atteigne un état final (READY ou FAILED) dans le délai spécifié avant de renvoyer le statut du service. Si le service n’atteint pas l’état final dans le délai spécifié, Snowflake renvoie l’état actuel à la fin de l’intervalle de temps spécifié.

Le délai d’expiration que vous spécifiez est une approximation basée sur le moment où vous pensez que le service sera prêt, et cela peut aider à identifier des situations telles que lorsque Snowflake attend que d’autres services et tâches s’arrêtent et libèrent des ressources dans le pool de calcul spécifié avant de démarrer un autre service. La fonction SYSTEM$GET_SERVICE_STATUS suivante spécifie un délai d’expiration de 10 secondes :

call SYSTEM$GET_SERVICE_STATUS('echo_service', 10);
Copy

Accès aux journaux des conteneurs locaux

Snowflake collecte tout ce que le code de votre conteneur d’application envoie à la sortie standard ou aux erreurs standard. Vous devez vous assurer que votre code produit des informations utiles pour déboguer un service.

Snowflake propose deux façons d’accéder à ces journaux de conteneurs :

  • Utilisation de la fonction système SYSTEM$GET_SERVICE_LOGS : permet d’accéder aux journaux d’un conteneur spécifique. Après la sortie d’un conteneur, vous pouvez continuer à accéder aux journaux à l’aide de la fonction système pendant une courte période. Les fonctions du système sont surtout utiles pendant le développement et les tests, lorsque vous créez un service ou une tâche. Pour plus d’informations, voir SYSTEM$GET_SERVICE_LOGS.

  • Utilisation d’une table d’événements : une table d’événements vous permet d’accéder aux journaux de plusieurs conteneurs dans tous les services. Snowflake conserve les journaux dans la table d’événements pour un accès ultérieur. Les tables d’événements sont utilisées de préférence pour l’analyse rétrospective des services et des tâches. Pour plus d’informations, voir Utilisation d’une table d’événements.

Utilisation de SYSTEM$GET_SERVICE_LOGS

Vous fournissez le nom du service, l’ID d’instance, le nom du conteneur et, éventuellement, le nombre de lignes de journal les plus récentes à récupérer. Si une seule instance de service est en cours d’exécution, l’ID d’instance de service est 0. Par exemple, la commande GET_SERVICE_LOGS suivante récupère les 10 dernières lignes du journal d’un conteneur nommé echo qui appartient à l’instance 0 d’un service nommé echo_service :

CALL SYSTEM$GET_SERVICE_LOGS('echo_service', '0', 'echo', 10);
Copy

Si vous ne connaissez pas les informations sur le service (comme l’ID d’instance ou le nom du conteneur), vous pouvez d’abord exécuter GET_SERVICE_STATUS pour obtenir des informations sur les instances de service et les conteneurs en cours d’exécution dans chaque instance.

Exemple de sortie :

+--------------------------------------------------------------------------+
| SYSTEM$GET_SERVICE_LOGS                                                  |
|--------------------------------------------------------------------------|
| 10.16.6.163 - - [11/Apr/2023 21:44:03] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:08] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:13] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:18] "GET /healthcheck HTTP/1.1" 200 - |
+--------------------------------------------------------------------------+
1 Row(s) produced. Time Elapsed: 0.878s

La sortie SYSTEM$GET_SERVICE_LOGS a les limitations suivantes :

  • Elle fusionne simplement les flux de sortie et d’erreur standard, ce qui rend impossible la distinction entre les messages de sortie normaux et d’erreur.

  • Elle rapporte les données capturées pour un conteneur spécifique dans une instance de service unique.

  • Elle ne signale que les journaux d’un conteneur en cours d’exécution. La fonction ne peut pas récupérer les journaux d’un conteneur précédent qui a été redémarré ou d’un conteneur d’un service qui est arrêté ou supprimé.

  • La fonction renvoie jusqu’à 100 KB de données.

Utilisation d’une table d’événements

Snowflake peut capturer et enregistrer la sortie standard et les erreurs standard de vos conteneurs dans la table d’événements configurée pour votre compte. Pour plus d’informations, voir Vue d’ensemble de la journalisation et du traçage.

Par exemple, la requête SELECT suivante récupère les événements de services et de tâches Snowflake enregistrés au cours de l’heure écoulée :

SELECT TIMESTAMP, RESOURCE_ATTRIBUTES, RECORD_ATTRIBUTES, VALUE
FROM <current-event-table-for-your-account>
WHERE timestamp > dateadd(hour, -1, current_timestamp())
AND RESOURCE_ATTRIBUTES:"snow.executable.type" = 'SnowparkContainers'
ORDER BY timestamp DESC
LIMIT 10;
Copy

Snowflake recommande d’inclure un horodatage dans la clause WHERE des requêtes de tables d’événements, comme le montre cet exemple. Ceci est particulièrement important en raison du volume potentiel de données générées par les différents composants de Snowflake. En appliquant des filtres, vous pouvez extraire un sous-ensemble de données plus restreint, ce qui améliore les performances de la requête.

Vous contrôlez le niveau des journaux (tous, erreurs uniquement ou aucun) que vous souhaitez conserver dans une table d’événements en utilisant le champ spec.logExporters dans le fichier de spécification du service.

La table d’événements comprend les colonnes suivantes, qui fournissent des informations utiles sur les journaux collectés par Snowflake depuis votre conteneur :

  • TIMESTAMP : indique quand Snowflake a collecté le journal.

  • RESOURCE_ATTRIBUTES : chaque objet de cette colonne identifie le service Snowflake et le conteneur du service qui a généré le journal. Par exemple, il fournit des détails tels que le nom du service, le nom du conteneur et le nom du pool de calcul qui ont été spécifiés lors de l’exécution du service.

    {
    "snow.containers.compute_pool.id": 549816068,
    "snow.containers.compute_pool.name": "TUTORIAL_COMPUTE_POOL",
    "snow.containers.container.name": "echo",
    "snow.containers.instance.name": "0",
    "snow.containers.restart.id": "cd0cf2",
    "snow.database.id": 549816076,
    "snow.database.name": "TUTORIAL_DB",
    "snow.executable.id": 980991015,
    "snow.executable.name": "ECHO_SERVICE",
    "snow.executable.type": "SnowparkContainers",
    "snow.schema.id": 549816076,
    "snow.schema.name": "DATA_SCHEMA"
    }
    
    Copy
  • RECORD_ATTRIBUTES : pour un service Snowflake, il identifie une source d’erreur (sortie standard ou erreur standard).

    { "log.iostream": "stdout" }
    
    Copy
  • VALUE : la sortie standard et l’erreur standard sont divisées en lignes, et chaque ligne génère un enregistrement dans la table d’événements.

    "echo-service [2023-10-23 17:52:27,429] [DEBUG] Sending response: {'data': [[0, 'Joe said hello!']]}"
    

Configuration d’une table d’événements

Pour plus d’informations, voir Vue d’ensemble de la journalisation et du traçage.

Utilisation d’un service

Vous pouvez autoriser à un rôle l’utilisation de services futurs (services non encore créés). Par exemple :

GRANT USAGE ON FUTURE SERVICES IN [DATABASE <name> | SCHEMA <name>]TO ROLE <name>
Copy

Après avoir créé un service, vous pouvez utiliser l’une des trois méthodes suivantes pour communiquer avec lui :

  • Fonction de service : créer une fonction de service (UDF) associée au service. Ensuite, utilisez la fonction de service pour communiquer avec un service à partir d’une requête SQL. Pour un exemple, voir le tutoriel 1.

  • Entrée : utiliser les points de terminaison publics exposés par le service pour accéder au service depuis l’extérieur de Snowflake. Dans ce cas, Snowflake gère le contrôle d’accès. Pour un exemple, voir le tutoriel 1.

  • Communications de service à service : utilisez un nom DNS de service attribué par Snowflake pour les communications de service à service. Pour un exemple, voir le tutoriel 3.

Les sections suivantes fournissent des détails.

Fonctions de service : utilisation d’un service à partir d’une requête SQL

Une fonction de service est une fonction définie par l’utilisateur (UDF) que vous créez à l’aide de CREATE FUNCTION. Cependant, au lieu d’écrire directement le code de l’UDF, vous associez l’UDF à votre service. Par exemple, dans le tutoriel 1, vous créez un service nommé echo_service qui expose un point de terminaison (echoendoint) tel que défini dans la spécification du service :

spec:

  endpoints:
  - name: echoendpoint
    port: 8080
Copy

echoendpoint est un nom de point de terminaison convivial qui représente le port correspondant (8080). Pour communiquer avec ce point de terminaison de service, vous créez une fonction de service en fournissant les paramètres SERVICE et ENDPOINT comme indiqué :

CREATE FUNCTION my_echo_udf (text varchar)
   RETURNS varchar
   SERVICE=echo_service
   ENDPOINT=echoendpoint
   AS '/echo';
Copy

Le paramètre AS fournit le chemin HTTP vers le code de service. Vous obtenez cette valeur de chemin à partir du code du service (par exemple, voir service.py dans le tutoriel 1).

@app.post("/echo")
def echo():
...
Copy

Lorsque vous invoquez la fonction de service, Snowflake dirige la requête vers le point de terminaison et le chemin du service associé.

Note

Une fonction de service est utilisée pour communiquer avec un service, et non avec une tâche. En d’autres termes, vous ne pouvez associer qu’un service (et non une tâche) à une fonction de service.

Lorsque vous exécutez plusieurs instances de votre service, vous pouvez créer une fonction de service en spécifiant le paramètre facultatif MAX_BATCH_ROWS pour limiter la taille du lot, c’est-à-dire le nombre maximum de lignes que Snowflake envoie par lot au service. Par exemple, supposons que MAX_BATCH_ROWS soit 10 et que vous appeliez la fonction de service my_echo_udf avec 100 lignes d’entrée. Snowflake divise les lignes d’entrée en lots, chaque lot ayant au plus 10 lignes, et envoie une série de requêtes au service avec le lot de lignes dans le corps de la requête. La configuration de la taille des lots peut être utile lorsque le traitement prend un temps non négligeable, de même que la répartition des lignes sur tous les serveurs disponibles.

Vous pouvez utiliser ALTER FUNCTION pour modifier une fonction de service. La commande ALTER FUNCTION suivante modifie le point de terminaison de service auquel elle s’associe et la taille du lot :

ALTER FUNCTION my_echo_udf(VARCHAR)
   SET SERVICE=other_service
   ENDPOINT=otherendpoint
   MAX_BATCH_ROWS=100
Copy

Format d’échange de données

Pour l’échange de données entre une fonction de service et un conteneur, Snowflake suit le même format que celui utilisé par les fonctions externes (voir Formats de données). Par exemple, supposons que vous ayez des lignes de données stockées dans une table (input_table) :

"Alex", "2014-01-01 16:00:00"
"Steve", "2015-01-01 16:00:00"

Pour envoyer ces données à votre service, vous invoquez la fonction de service en lui transmettant ces lignes en tant que paramètres :

SELECT service_func(col1, col2) FROM input_table;
Copy

Snowflake envoie une série de requêtes au conteneur, avec des lots de lignes de données dans le corps de la requête dans ce format :

{
   "data":[
      [
         0,
         "Alex",
         "2014-01-01 16:00:00"
      ],
      [
         1,
         "Steve",
         "2015-01-01 16:00:00"
      ],
      …
      [
         <row_index>,
         "<column1>",
         "<column2>"
      ],
   ]
}
Copy

Le conteneur renvoie ensuite la sortie dans le format suivant :

{
   "data":[
      [0, "a"],
      [1, "b"],
      …
      [ row_index,  output_column1]
   ]
}
Copy

L’exemple de sortie présenté suppose que le résultat est une table à une colonne avec des lignes (« a », « b »…).

Lorsque plusieurs instances de service sont en cours d’exécution, vous pouvez créer une fonction de service à l’aide du paramètre MAX_BATCH_ROWS afin de répartir les lignes d’entrée à traiter sur tous les serveurs disponibles.

Privilèges requis pour créer et gérer des fonctions de service

Pour créer et gérer des fonctions de service, un rôle doit disposer des privilèges suivants :

  • Pour créer une fonction de service : le rôle actuel doit avoir le privilège USAGE sur le service auquel il est fait référence.

  • Pour modifier une fonction de service : vous pouvez modifier une fonction de service et l’associer à un autre service. Le rôle actuel doit avoir le privilège USAGE sur le nouveau service.

  • Pour utiliser une fonction de service : le rôle actuel doit avoir le privilège USAGE sur la fonction de service, et le rôle de propriétaire de la fonction de service doit avoir le privilège USAGE sur le service associé.

L’exemple de script suivant montre comment vous pouvez accorder l’autorisation d’utiliser une fonction de service :

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');
Copy

Entrée : utilisation d’un service en dehors de Snowflake

Un service peut exposer un ou plusieurs points de terminaison comme étant publics pour permettre aux utilisateurs d’utiliser le service à partir du Web public.

Note

Pour les avant-premières publique et privée, le ACCOUNTADMIN de votre compte Snowflake doit exécuter la commande suivante :

CREATE SECURITY INTEGRATION SNOWSERVICES_INGRESS_OAUTH
TYPE=oauth
OAUTH_CLIENT=snowservices_ingress
ENABLED=true;
Copy

Marquez le point de terminaison comme public dans votre fichier de spécification de service :

spec
  ...
  endpoints
  - name: <endpoint name>
    port: <port number>
    public: true
Copy

Pour plus d’informations sur les spécifications de service, voir Référence de spécification.

Accès et authentification des points de terminaison publics

Snowpark Container Services requiert Snowflake OAuth pour authentifier les requêtes vers les points de terminaison publics. Par exemple, il vous sera demandé de vous connecter en utilisant un nom d’utilisateur et un mot de passe. En coulisses, votre connexion génère un jeton OAuth de Snowflake. Le jeton OAuth est ensuite utilisé pour envoyer une demande au point de terminaison de service.

Note

  • Parce que Snowpark Containers utilise Snowflake OAuth pour activer l’entrée, le rôle par défaut de l’utilisateur ne peut pas être l’un des rôles privilégiés, y compris ACCOUNTADMIN, SECURITYADMIN et ORGADMIN. Pour plus d’informations, voir Blocage de rôles spécifiques pour les empêcher d’utiliser l’intégration.

  • Tout le monde ne peut pas accéder aux points de terminaison publics exposés par un service. Seuls les utilisateurs du même compte Snowflake ayant un rôle avec le privilège USAGE sur un service peuvent accéder aux points de terminaison publics du service.

Vous pouvez accéder au point de terminaison public à l’aide d’un navigateur ou de manière programmatique :

  • Accès à un point de terminaison public en utilisant un navigateur : Lorsqu’un navigateur est utilisé pour accéder à un point de terminaison public, une redirection automatique est effectuée pour l’authentification de l’utilisateur. Vous pouvez explorer le tutoriel 1 pour tester cette expérience.

  • Accéder à un point de terminaison public de manière programmatique : L’exemple de code Python suivant utilise le Connecteur Snowflake pour Python pour générer un jeton de session qui représente votre identité. Le code utilise ensuite le jeton de session pour se connecter au point de terminaison public.

    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
    
    Copy

    Dans le code :

    • Si vous ne connaissez pas les informations de votre compte (<orgname>-<acctname>), consultez le tutoriel Configuration commune.

    • Vous pouvez obtenir le ingress_url du point de terminaison public exposé par le service en utilisant SHOW ENDPOINTS.

En-têtes spécifiques à l’utilisateur dans les demandes d’entrée

Lorsqu’une requête pour un point de terminaison arrive, Snowflake transmet automatiquement les en-têtes suivants avec la requête HTTP au conteneur.

Sf-Context-Current-User: <user_name>
Sf-Context-Current-User-Email: <email>
Copy

Le code de votre conteneur peut éventuellement lire ces en-têtes, savoir qui est l’appelant et appliquer une personnalisation spécifique au contexte pour différents utilisateurs.

Communications de service à service

Les services peuvent communiquer entre eux en utilisant le nom DNS que Snowflake attribue automatiquement à chaque service. Pour un exemple, voir le tutoriel 3.

Le format du nom DNS est le suivant :

<service-name>.<schema-name>.<db-name>.snowflakecomputing.internal

Utilisez SHOW SERVICES (ou DESCRIBE SERVICE) pour obtenir le nom DNS d’un service. Le nom DNS qui précède est un nom complet. Les services créés dans le même schéma peuvent communiquer en utilisant uniquement <service-name>. Les services qui se trouvent dans la même base de données, mais dans des schémas différents doivent fournir le nom du schéma, par exemple <service-name>.<schema-name>.

Snowflake autorise les communications réseau entre les services créés par le même rôle et bloque les communications réseau entre les services créés par des rôles différents. Si vous souhaitez empêcher vos services de communiquer entre eux (pour des raisons de sécurité, par exemple), utilisez différents rôles Snowflake pour créer ces services.

Les noms DNS présentent les limitations suivantes :

  • Les noms de votre base de données, de votre schéma ou de votre service doivent être des étiquettes DNS valides. (Voir aussi https://www.ietf.org/rfc/rfc1035.html#section-2.3.1). Sinon, la création d’un service échouera.

  • Snowflake remplace le trait de soulignement (_) dans les noms (base de données, schéma et nom de service) par un tiret (-) dans le nom DNS.

  • Après avoir créé un service, ne modifiez pas le nom de la base de données ou du schéma, car Snowflake ne mettra pas à jour le nom DNS du service.

  • Un nom DNS est uniquement destiné aux communications internes au sein de Snowflake entre les services fonctionnant dans le même compte. Il n’est pas accessible depuis Internet.

Mise à jour du code de votre service

Après avoir créé un service, utilisez ALTER SERVICE pour mettre à jour le code du service. Vous chargez d’abord le code d’application modifié dans votre référentiel d’images, puis vous appelez ALTER SERVICE en fournissant la spécification du service, soit en ligne, soit en spécifiant le chemin d’accès à un fichier de spécification dans la zone de préparation Snowflake. Par exemple :

  • Fournissez la spécification en ligne (une spécification partielle est affichée).

    ALTER SERVICE echo_service
    FROM SPECIFICATION $$
    spec:
      
      
    $$;
    
    Copy
  • Indiquer le chemin d’accès au fichier de la zone de préparation Snowflake :

    ALTER SERVICE echo_service
    FROM @tutorial_stage
    SPECIFICATION_FILE='echo_spec.yaml';
    
    Copy

Dès réception de la requête, Snowflake redéploie le service en utilisant le nouveau code.

ALTER SERVICE utilise toujours la version la plus récente de l’image provenant de votre référentiel. Par exemple, si vous chargez plusieurs versions d’une image nommée « echo_service:latest » ou « echo_service:sometag », Snowflake utilisera la dernière version de l’image chargée.

Vous pouvez utiliser la commande DESCRIBE SERVICE pour trouver la version de l’image que le service exécute. Si vous êtes le propriétaire du service, la sortie DESCRIBE SERVICE comprend la spécification du service, où vous obtenez le résumé de l’image (SHA256 de l’image). Par exemple :

spec:
containers:
- name: "echo"
   image: "orgname-acctname.registry-dev.snowflakecomputing.com/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
Copy

Note

Si vous suspendez et reprenez un service, Snowflake déploie la même version d’image, il ne s’agit pas d’une opération de mise à jour du service.

Privilèges

Privilège

Utilisation

Remarques

USAGE

Communiquer avec un service. Nécessaire pour créer une fonction de service, utiliser des points de terminaison publics et se connecter à partir d’un autre service.

MONITOR

Surveiller un service et obtenir son statut d’exécution.

OPERATE

Suspendre ou reprendre un service.

OWNERSHIP

Avoir le contrôle total du service. Un seul rôle peut détenir ce privilège sur un objet spécifique à la fois.

ALL [ PRIVILEGES ]

Accorder tous les privilèges, sauf OWNERSHIP, sur le service.