Tutoriel 3 : CrĂ©er et gĂ©rer les Snowpark Container Services¶

Introduction¶

Snowpark Container Services est une offre de conteneurs entiĂšrement gĂ©rĂ©e, conçue pour faciliter le dĂ©ploiement, la gestion et la mise Ă  l’échelle des applications conteneurisĂ©es au sein de l’écosystĂšme Snowflake. GrĂące Ă  cette fonctionnalitĂ©, vous pouvez exĂ©cuter des charges de travail conteneurisĂ©es directement dans Snowflake.

Dans ce tutoriel, vous apprendrez à utiliser Snowflake Python APIs pour gérer les composants dans Snowpark Container Services.

Important

Snowpark Container Services est gĂ©nĂ©ralement disponible pour les comptes Snowflake dans AWS. La prise en charge en avant-premiĂšre est disponible pour les comptes dans Azure. Pour plus d’informations, voir Services de conteneurs Snowpark – RĂ©gions disponibles.

Conditions préalables¶

Avant de commencer ce tutoriel, vous devez suivre ces Ă©tapes :

  1. Installez Docker Desktop.

    Ce tutoriel fournit des instructions qui nĂ©cessitent Docker Desktop. Pour des instructions d’installation, voir https://docs.docker.com/get-docker/.

  2. Suivez les instructions de configuration commune, qui comprennent les Ă©tapes suivantes :

    • Configurez votre environnement de dĂ©veloppement.

    • Installez le paquet Snowflake Python APIs.

    • Configurez votre connexion Snowflake.

    • Importez tous les modules nĂ©cessaires aux tutoriels d’API Python.

    • CrĂ©ez un objet d’API Root.

    Note

    Si vous avez déjà terminé la configuration commune, vous pouvez ignorer cette étape et commencer le tutoriel.

AprĂšs avoir rempli ces conditions prĂ©alables, vous ĂȘtes prĂȘt Ă  commencer Ă  utiliser l’API pour gĂ©rer Snowpark Container Services.

Configurez votre environnement de développement¶

Si vous utilisiez un notebook pour les prĂ©cĂ©dents tutoriels Snowflake Python APIs, vous passez Ă  un nouveau notebook dans ce tutoriel. Le notebook contiendra un exemple de code qui exĂ©cute un serveur Web NGINX utilisant Snowpark Container Services, qui s’exĂ©cutent tous dans Snowflake.

  1. Ouvrez un nouveau notebook Ă  l’aide de votre Ă©diteur de code prĂ©fĂ©rĂ© ou en exĂ©cutant la commande jupyter notebook.

  2. Dans la premiĂšre cellule de votre notebook, exĂ©cutez le code suivant :

    from snowflake.core.database import Database
    from snowflake.core.schema import Schema
    
    database = root.databases.create(Database(name="spcs_python_api_db"), mode="orreplace")
    schema = database.schemas.create(Schema(name="public"), mode="orreplace")
    
    Copy

    En utilisant la connexion Snowflake et l’objet root que vous avez créé prĂ©cĂ©demment dans la configuration commune, vous crĂ©ez une base de donnĂ©es nommĂ©e spcs_python_api_db et un schĂ©ma nommĂ© public dans cette base de donnĂ©es. Vous enregistrez Ă©galement les rĂ©fĂ©rences qui reprĂ©sentent ces objets nouvellement créés. Vos composants Snowpark Container Services vivront dans cette base de donnĂ©es et ce schĂ©ma.

Aperçu des Snowpark Container Services¶

Avant de poursuivre le tutoriel, passez briĂšvement en revue les principaux composants de Snowpark Container Services. Pour exĂ©cuter des applications conteneurisĂ©es dans Snowpark Container Services, vous travaillez gĂ©nĂ©ralement avec les objets suivants :

  • RĂ©fĂ©rentiel d’images : fournit une unitĂ© de stockage oĂč vous pouvez tĂ©lĂ©charger les images de votre application dans votre compte Snowflake.

    Snowpark Container Services fournit un service de registre d’images conforme Ă  OCIv2 qui permet aux clients OCI (tels que la CLI Docker et SnowSQL) d’accĂ©der Ă  un registre d’images dans votre compte Snowflake. GrĂące Ă  ces clients, vous pouvez charger les images de vos applications vers un rĂ©fĂ©rentiel.

    Pour plus d’informations, voir Utilisation d’un registre et d’un rĂ©fĂ©rentiel d’images.

  • Pool de calcul : reprĂ©sente un ensemble de ressources de calcul (nƓuds de machine virtuelle).

    Ces ressources de calcul sont analogues, mais pas Ă©quivalentes, aux entrepĂŽts virtuels Snowflake. Le service (dans ce cas, votre service NGINX) s’exĂ©cutera dans le pool de calcul. Les services Ă  forte intensitĂ© de calcul nĂ©cessitent des pools de calcul trĂšs puissants avec de nombreux cƓurs et de nombreux GPUs, tandis que les services moins intensifs peuvent s’exĂ©cuter dans des pools de calcul plus petits avec moins de cƓurs.

    Pour plus d’informations, voir Utilisation de pools de calcul.

  • Service : fournit un moyen d’exĂ©cuter un conteneur d’application.

    Au minimum, les services nĂ©cessitent une spĂ©cification et un pool de calcul. Une spĂ©cification contient les informations nĂ©cessaires Ă  l’exĂ©cution du conteneur d’application, telles que le chemin d’accĂšs Ă  une image de conteneur et les points de terminaison que les services exposeront. La spĂ©cification est Ă©crite en YAML. Le pool de calcul est l’ensemble des ressources de calcul dans lesquelles le service s’exĂ©cutera.

    Pour plus d’informations, voir Utilisation des services.

Passez aux étapes suivantes pour créer et configurer ces objets.

CrĂ©er un rĂ©fĂ©rentiel d’images¶

Dans cette section, vous crĂ©ez d’abord un rĂ©fĂ©rentiel d’images Ă  l’aide de Snowflake Python APIs. Ensuite, vous allez chercher une image de l’application NGINX Ă  partir de Docker Hub et tĂ©lĂ©charger l’image dans le rĂ©fĂ©rentiel d’images Ă  l’aide de la CLI Docker.

Créer un référentiel et obtenir des informations sur le référentiel

  1. Dans la cellule suivante de votre notebook, exĂ©cutez le code suivant :

    from snowflake.core.image_repository import ImageRepository
    
    my_repo = ImageRepository("MyImageRepository")
    schema.image_repositories.create(my_repo)
    
    Copy

    Dans cet exemple de code, vous crĂ©ez un rĂ©fĂ©rentiel d’images dans la base de donnĂ©es et le schĂ©ma que vous avez créés prĂ©cĂ©demment dans ce tutoriel.

  2. Pour confirmer que le rĂ©fĂ©rentiel a Ă©tĂ© créé avec succĂšs en rĂ©cupĂ©rant ses dĂ©tails et en imprimant son nom, exĂ©cutez le code suivant :

    my_repo_res = schema.image_repositories["MyImageRepository"]
    my_repo = my_repo_res.fetch()
    print(my_repo.name)
    
    Copy
  3. Vous aurez besoin d’informations sur le rĂ©fĂ©rentiel (l’URL du rĂ©fĂ©rentiel et le nom d’hĂŽte du registre) avant de pouvoir construire et charger l’image.

    Pour obtenir l’URL du rĂ©fĂ©rentiel, dans votre cellule suivante, exĂ©cutez le code suivant :

    repositories = schema.image_repositories
      for repo_obj in repositories.iter():
        print(repo_obj.repository_url)
    
    Copy
    • L’attribut repository_url dans la sortie fournit l’URL. Par exemple :

      <orgname>-<acctname>.registry.snowflakecomputing.com/spcs_python_api_db/public/myimagerepository
      
    • Le nom d’hĂŽte dans l’URL du rĂ©fĂ©rentiel est le nom d’hĂŽte du registre. Par exemple :

      <orgname>-<acctname>.registry.snowflakecomputing.com
      

Extraire l’image NGINX et la charger dans le rĂ©fĂ©rentiel

  1. Pour que Docker puisse charger une image en votre nom dans votre rĂ©fĂ©rentiel, vous devez d’abord authentifier Docker avec Snowflake.

    Pour authentifier Docker avec le registre Snowflake, ouvrez un terminal de ligne de commande et exĂ©cutez la commande docker login suivante en utilisant la CLI de Docker :

    docker login <registry_hostname> -u <username>
    
    Copy
    • registry_hostname : spĂ©cifiez le nom d’hĂŽte dans repository_url Ă  partir du rĂ©sultat de l’étape prĂ©cĂ©dente.

    • username : indiquez votre nom d’utilisateur Snowflake. Docker vous demandera votre mot de passe.

    Exemple

    docker login myorg-myacct.registry.snowflakecomputing.com -u admin
    
    Copy
  2. RĂ©cupĂ©rez la version intermĂ©diaire AMD64 de l’image NGINXde Docker Hub:

    docker pull --platform linux/amd64 amd64/nginx
    
    Copy
  3. Étiquetez l’image amd64/nginx avec l’URL du rĂ©fĂ©rentiel d’images Snowflake :

    docker tag docker.io/amd64/nginx:latest <repository_url>/<image_name>
    
    Copy

    Exemple

    docker tag docker.io/amd64/nginx:latest myorg-myacct.registry.snowflakecomputing.com/spcs_python_api_db/public/myimagerepository/amd64/nginx:latest
    
    Copy

    Une balise est un identificateur personnalisĂ©, lisible par l’homme, que vous pouvez Ă©ventuellement utiliser pour identifier une version ou une variante spĂ©cifique d’une image.

  4. Chargez l’image dans le rĂ©fĂ©rentiel de votre compte Snowflake :

    docker push <repository_url>/<image_name>
    
    Copy

    Exemple

    docker push myorg-myacct.registry.snowflakecomputing.com/spcs_python_api_db/public/myimagerepository/amd64/nginx:latest
    
    Copy

Créer un pool de calcul¶

Pour dĂ©finir et crĂ©er un pool de calcul, dans la cellule suivante de votre notebook, exĂ©cutez le code suivant :

new_compute_pool_def = ComputePool(
    name="MyComputePool",
    instance_family="CPU_X64_XS",
    min_nodes=1,
    max_nodes=2,
)

new_compute_pool = root.compute_pools.create(new_compute_pool_def)
Copy

Dans cette cellule, vous dĂ©finissez un pool de calcul Ă  l’aide du constructeur ComputePool en fournissant des valeurs pour les attributs suivants :

  • instance_family : la famille d’instances identifie le type de machine Ă  provisionner pour les nƓuds du pool de calcul.

    Chaque type de machine fournit une quantitĂ© diffĂ©rente de ressources de calcul Ă  ses pools de calcul. Dans cette cellule, vous utilisez le plus petit type de machine disponible, CPU_X64_XS. Pour plus d’informations, voir CREATE COMPUTE POOL.

  • min_nodes : le nombre minimum de nƓuds pour dĂ©marrer un pool de calcul.

  • max_nodes : le nombre maximal de nƓuds que le pool de calcul peut contenir.

    Lorsque vous crĂ©ez un pool de calcul, Snowflake le lance avec le nombre minimum de nƓuds spĂ©cifiĂ©. Snowflake gĂšre ensuite automatiquement la mise Ă  l’échelle et crĂ©e de nouveaux nƓuds, jusqu’au nombre maximal spĂ©cifiĂ©, lorsque les nƓuds en cours d’exĂ©cution ne peuvent pas supporter de charge de travail supplĂ©mentaire.

Ensuite, vous créez le pool de calcul en transmettant la définition du pool de calcul à compute_pools.create().

Créez un service¶

À l’aide du rĂ©fĂ©rentiel d’images et du pool de calcul que vous avez configurĂ©s, vous pouvez dĂ©sormais dĂ©finir et crĂ©er votre service. Un service fait rĂ©fĂ©rence Ă  une collection de conteneurs exĂ©cutĂ©s dans un pool de calcul, qui sont tous orchestrĂ©s dans Snowflake.

  1. Pour rĂ©cupĂ©rer le rĂ©fĂ©rentiel contenant votre image de conteneur, dans la cellule suivante de votre notebook, exĂ©cutez le code suivant :

    image_repository = schema.image_repositories["MyImageRepository"]
    
    Copy

    Ce rĂ©fĂ©rentiel se trouve dans votre compte Snowflake, rĂ©pertoriĂ© comme une zone de prĂ©paration dans le schĂ©ma PUBLIC. Vous avez besoin de cette rĂ©fĂ©rence pour rĂ©cupĂ©rer les informations de l’image du conteneur Ă  l’étape suivante.

  2. Pour dĂ©finir et crĂ©er votre service, dans votre cellule suivante, exĂ©cutez le code suivant :

    from textwrap import dedent
    from io import BytesIO
    from snowflake.core.service import Service, ServiceSpecInlineText
    
    specification = dedent(f"""\
        spec:
          containers:
          - name: web-server
            image: {image_repository.fetch().repository_url}/amd64/nginx:latest
          endpoints:
          - name: ui
            port: 80
            public: true
        """)
    
    service_def = Service(
        name="MyService",
        compute_pool="MyComputePool",
        spec=ServiceSpecInlineText(spec_text=specification),
        min_instances=1,
        max_instances=1,
    )
    
    nginx_service = schema.services.create(service_def)
    
    Copy

    Cette cellule dĂ©finit la spĂ©cification du service et le service, puis crĂ©e le service pour votre serveur Web NGINX. Les dĂ©finitions de la spĂ©cification et du service ont les propriĂ©tĂ©s suivantes :

    • specification – Vous dĂ©finissez la spĂ©cification Ă  l’aide d’un littĂ©ral de chaĂźne formatĂ© Python (f-string). La chaĂźne est formatĂ©e comme YAML.

      La spĂ©cification contient le nom du conteneur, un chemin vers l’image du conteneur et les points de terminaison que le service exposera pour l’accĂšs public. Dans cet exemple, vous dĂ©finissez la spĂ©cification en ligne, mais vous pouvez Ă©galement dĂ©finir une spĂ©cification en tant que rĂ©fĂ©rence Ă  un fichier .yml dans une zone de prĂ©paration.

    • service_def – Vous dĂ©finissez un service avec le constructeur Service , transmettant un nom pour le service, le pool de calcul dans lequel il s’exĂ©cutera, un chemin vers la spĂ©cification et le nombre total d’instances pour le service.

      Dans cette cellule, vous utilisez ServiceSpecInlineText pour définir la valeur de spec parce que vous définissez la spécification en ligne comme une chaßne f. Vous pouvez spécifier le service pour exécuter plusieurs instances, mais dans cet exemple, vous spécifiez une seule instance du service à exécuter en définissant min_instances et max_instances sur 1.

  3. Pour vĂ©rifier le statut du service, dans votre cellule suivante, exĂ©cutez le code suivant :

    from pprint import pprint
    
    pprint(nginx_service.get_service_status(timeout=5))
    
    Copy

    Le rĂ©sultat devrait ĂȘtre similaire Ă  ceci :

    {'auto_resume': True,
    'auto_suspend_secs': 3600,
    'instance_family': 'CPU_X64_XS',
    'max_nodes': 1,
    'min_nodes': 1,
    'name': 'MyService'}
    

Utilisez votre service¶

AprÚs avoir créé le service, Snowpark Container Services prendra quelques minutes pour provisionner les points de terminaison nécessaires pour accéder au service.

  1. Pour vĂ©rifier le statut des points de terminaison, dans la cellule suivante de votre notebook, exĂ©cutez le code suivant :

    import json, time
    
    while True:
        public_endpoints = nginx_service.fetch().public_endpoints
        try:
            endpoints = json.loads(public_endpoints)
        except json.JSONDecodeError:
            print(public_endpoints)
            time.sleep(15)
        else:
            break
    
    Copy

    L’exemple de code n’est pas spĂ©cifique Ă  Snowpark Container Services ou Snowflake Python APIs – cela fournit simplement un moyen pratique de vĂ©rifier si les points de terminaison sont prĂȘts. Notez que vous rĂ©cupĂ©rez les points de terminaison en appelant .fetch().public_endpoints sur votre objet de service.

    Le rĂ©sultat devrait ĂȘtre similaire Ă  ceci :

    Endpoints provisioning in progress... check back in a few minutes
    Endpoints provisioning in progress... check back in a few minutes
    Endpoints provisioning in progress... check back in a few minutes
    
  2. Une fois les points de terminaison provisionnés, vous pouvez ouvrir les points de terminaison publics dans votre navigateur.

    Dans votre cellule suivante, exĂ©cutez le code suivant :

    import webbrowser
    
    print(f"Visiting {endpoints['ui']} in your browser. You might need to log in there.")
    webbrowser.open(f"https://{endpoints['ui']}")
    
    Copy

    Le rĂ©sultat devrait ĂȘtre similaire Ă  ceci :

    Visiting myorg-myacct.snowflakecomputing.app in your browser. You might need to log in there.
    

    En cas de succĂšs, vous verrez la page de rĂ©ussite NGINX dans votre navigateur lors de la visite du point de terminaison :

    Capture d'écran de la page de réussite du serveur Web NGINX dans un navigateur
  3. Vous pouvez utiliser l’API Python pour gĂ©rer votre nouveau service.

    Par exemple, pour suspendre le service puis vĂ©rifier son statut, exĂ©cutez le code suivant :

    from time import sleep
    
    nginx_service.suspend()
    sleep(3)
    print(nginx_service.get_service_status(timeout=5))
    
    Copy
  4. Pour reprendre le service, exĂ©cutez le code suivant :

    nginx_service.resume()
    sleep(3)
    print(nginx_service.get_service_status(timeout=5))
    
    Copy

Avec seulement quelques lignes de Python, vous avez pu exécuter un serveur Web NGINX dans Snowflake utilisant Snowpark Container Services.

Nettoyage¶

Snowflake facture les nƓuds de pool de calcul actifs sur votre compte. Pour Ă©viter des frais indĂ©sirables, suspendez d’abord le service et le pool de calcul, puis supprimez les deux objets.

  1. Pour suspendre le pool de calcul et le service, dans la cellule suivante de votre notebook, exĂ©cutez le code suivant :

    new_compute_pool_def.suspend()
    nginx_service.suspend()
    
    Copy
  2. Pour supprimer le pool de calcul et le service, exĂ©cutez le code suivant :

    new_compute_pool_def.drop()
    nginx_service.drop()
    
    Copy

Quelle est la prochaine Ă©tape ?¶

FĂ©licitations ! Dans ce tutoriel, vous avez appris les principes fondamentaux de la gestion des composants dans Snowpark Container Services en utilisant Snowflake Python APIs.

Résumé¶

En chemin, vous avez rĂ©alisĂ© ces Ă©tapes :

  • CrĂ©er un rĂ©fĂ©rentiel d’images dans lequel vous tĂ©lĂ©chargez les images de votre application.

  • CrĂ©er un pool de calcul dans lequel votre service s’exĂ©cute.

  • CrĂ©er un service pour exĂ©cuter votre conteneur d’application.

  • Utiliser et gĂ©rer votre service.

  • Nettoyer vos objets de ressources Snowpark Container Services en les suspendant et en les supprimant.

Ressources supplémentaires¶

Pour plus d’exemples d’utilisation de l’API pour gĂ©rer d’autres types d’objets dans Snowflake, consultez les guides de dĂ©veloppement suivants :

Guide

Description

Gestion des bases de données, schémas, tables et vues Snowflake avec Python

Utilisez l’API pour crĂ©er et gĂ©rer des bases de donnĂ©es, des schĂ©mas et des tables.

Gestion des utilisateurs, des rĂŽles et des attributions Snowflake avec Python

Utilisez l’API pour crĂ©er et gĂ©rer les utilisateurs, les rĂŽles et les autorisations.

Gestion des ressources de chargement et de déchargement de données avec Python

Utilisez l’API pour crĂ©er et gĂ©rer les ressources de chargement et de dĂ©chargement de donnĂ©es, y compris les volumes externes, les canaux et les zones de prĂ©paration.

Gestion des tĂąches et des graphiques de tĂąches Snowflake avec Python

Utilisez l’API pour crĂ©er, exĂ©cuter et gĂ©rer des tĂąches et des graphiques de tĂąches.