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 :
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/.
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.
Ouvrez un nouveau notebook Ă lâaide de votre Ă©diteur de code prĂ©fĂ©rĂ© ou en exĂ©cutant la commande
jupyter notebook
.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")
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éespcs_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
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)
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.
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)
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)
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
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>
registry_hostname
: spĂ©cifiez le nom dâhĂŽte dansrepository_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
RĂ©cupĂ©rez la version intermĂ©diaire AMD64 de lâimage NGINXde Docker Hub:
docker pull --platform linux/amd64 amd64/nginx
Ă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>
Exemple
docker tag docker.io/amd64/nginx:latest myorg-myacct.registry.snowflakecomputing.com/spcs_python_api_db/public/myimagerepository/amd64/nginx:latest
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.
Chargez lâimage dans le rĂ©fĂ©rentiel de votre compte Snowflake :
docker push <repository_url>/<image_name>
Exemple
docker push myorg-myacct.registry.snowflakecomputing.com/spcs_python_api_db/public/myimagerepository/amd64/nginx:latest
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)
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.
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"]
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.
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)
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 constructeurService
, 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 despec
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éfinissantmin_instances
etmax_instances
sur1
.
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))
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.
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
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
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']}")
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 :
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))
Pour reprendre le service, exécutez le code suivant :
nginx_service.resume() sleep(3) print(nginx_service.get_service_status(timeout=5))
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.
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()
Pour supprimer le pool de calcul et le service, exécutez le code suivant :
new_compute_pool_def.drop() nginx_service.drop()
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. |