Tutorial 3: Crie e gerencie serviços de contêiner do Snowpark

Introdução

O Snowpark Container Services é uma oferta de contêiner totalmente gerenciada, projetada para facilitar a implementação, o gerenciamento e o dimensionamento de aplicativos em contêineres dentro do ecossistema Snowflake. Com esse recurso, você pode executar cargas de trabalho em contêineres diretamente no Snowflake.

Neste tutorial, você aprenderá como usar o Snowflake Python APIs para gerenciar componentes no Snowpark Container Services.

Importante

O Snowpark Container Services está geralmente disponível para contas Snowflake no AWS.O suporte em versão preliminar está disponível para contas no Azure. Para obter mais informações, consulte Snowpark Container Services – Regiões disponíveis.

Pré-requisitos

Antes de iniciar este tutorial, é necessário concluir estas etapas:

  1. Instale o Docker Desktop.

    Este tutorial fornece instruções que exigem o Docker Desktop. Para instruções de instalação, consulte https://docs.docker.com/get-docker/.

  2. Siga as instruções comuns de configuração, que incluem as seguintes etapas:

    • Configure seu ambiente de desenvolvimento.

    • Instale o pacote Snowflake Python APIs.

    • Configure sua conexão Snowflake.

    • Importe todos os módulos necessários para os tutoriais da API Python.

    • Crie um objeto Root da API.

    Nota

    Se você já concluiu a configuração comum, é possível pular esta etapa e começar o tutorial.

Após concluir esses pré-requisitos, você estará pronto para começar a usar a API para gerenciar o Snowpark Container Services.

Configure seu ambiente de desenvolvimento

Se você estava usando um notebook nos tutoriais do Snowflake Python APIs anteriores, mude para um novo notebook neste tutorial. O notebook conterá um código de amostra que executa um servidor Web NGINX usando o Snowpark Container Services, tudo executado no Snowflake.

  1. Abra um novo notebook usando seu editor de código preferido ou executando o comando jupyter notebook.

  2. Na primeira célula de seu notebook, execute o seguinte código:

    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

    Usando a conexão e o objeto root Snowflake que você criou anteriormente na configuração comum, você cria um banco de dados nomeado spcs_python_api_db e um esquema nomeado public nesse banco de dados. Você também salva referências que representam esses objetos recém-criados. Seus componentes do Snowpark Container Services ficarão neste banco de dados e esquema.

Visão geral de Snowpark Container Services

Antes de continuar com o tutorial, revise brevemente os principais componentes do Snowpark Container Services. Para executar aplicativos em contêineres no Snowpark Container Services, você normalmente trabalha com os seguintes objetos:

  • Repositório de imagens: Fornece uma unidade de armazenamento onde você pode carregar as imagens de seu aplicativo na sua conta Snowflake.

    O Snowpark Container Services fornece um serviço de registro de imagem compatível com OCIv2 que permite que clientes OCI (como Docker CLI e SnowSQL) acessem um registro de imagem em sua conta Snowflake. Usando esses clientes, é possível carregar as imagens de seu aplicativo para um repositório.

    Para obter mais informações, consulte Como trabalhar com um registro e repositório de imagens.

  • Pool de computação: representa um conjunto de recursos de computação (nós de máquina virtual).

    Esses recursos de computação são análogos, mas não equivalentes, aos warehouses virtuais do Snowflake. O serviço (neste caso, seu serviço NGINX) será executado no pool de computação. Serviços de uso intensivo de computação exigem pools de computação de alta potência com muitos núcleos e GPUs, enquanto serviços menos intensivos podem ser executados em pools de computação menores com menos núcleos.

    Para obter mais informações, consulte Como trabalhar com pools de computação.

  • Serviço: Fornece uma maneira de executar um contêiner de aplicativo.

    No mínimo, os serviços exigem uma especificação e um pool de computação. Uma especificação contém as informações necessárias para executar o contêiner do aplicativo, como o caminho para uma imagem de contêiner e os pontos de extremidade que os serviços irão expor. A especificação está escrita em YAML. O pool de computação é o conjunto de recursos de computação nos quais o serviço será executado.

    Para obter mais informações, consulte Como trabalhar com serviços de trabalho.

Continue para as próximas etapas para criar e definir esses objetos.

Criação de um repositório de imagens

Nesta seção, primeiro você cria um repositório de imagens usando o Snowflake Python APIs. Em seguida, você busca uma imagem do aplicativo NGINX do Docker Hub e carrega a imagem no repositório de imagens usando Docker CLI.

Crie um repositório e obtenha informações sobre o repositório

  1. Na próxima célula do notebook, execute o seguinte código:

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

    Neste exemplo de código, você cria um repositório de imagens no banco de dados e no esquema que criou anteriormente neste tutorial.

  2. Para confirmar se o repositório foi criado com sucesso, buscando seus detalhes e imprimindo seu nome, execute o seguinte código:

    my_repo_res = schema.image_repositories["MyImageRepository"]
    my_repo = my_repo_res.fetch()
    print(my_repo.name)
    
    Copy
  3. Você precisará de informações sobre o repositório (o URL do repositório e o nome de host do registro) antes de poder carregar a imagem.

    Para obter o URL do repositório, na próxima célula, execute o seguinte código:

    repositories = schema.image_repositories
      for repo_obj in repositories.iter():
        print(repo_obj.repository_url)
    
    Copy
    • O atributo repository_url na saída fornece o URL. Por exemplo:

      <orgname>-<acctname>.registry.snowflakecomputing.com/spcs_python_api_db/public/myimagerepository
      
    • O nome de host no URL de repositório é o nome de host do registro. Por exemplo:

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

Obtenha a imagem NGINX e carregue-a no repositório

  1. Para que o Docker carregue uma imagem em seu repositório em seu nome, primeiro é necessário autenticar o Docker com o Snowflake.

    Para autenticar o Docker com o registro Snowflake, abra um terminal de linha de comando e execute o seguinte comando docker login usando Docker CLI:

    docker login <registry_hostname> -u <username>
    
    Copy
    • registry_hostname: Especifique o nome de host em repository_url a partir do resultado da etapa anterior.

    • username: Especifique seu nome de usuário Snowflake. O Docker solicitará sua senha.

    Exemplo

    docker login myorg-myacct.registry.snowflakecomputing.com -u admin
    
    Copy
  2. Obtenha a compilação AMD64 da imagem NGINX do Docker Hub:

    docker pull --platform linux/amd64 amd64/nginx
    
    Copy
  3. Marque a imagem amd64/nginx com o URL do repositório de imagens Snowflake:

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

    Exemplo

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

    Uma tag é um identificador personalizado e legível que você pode usar opcionalmente para identificar uma versão ou variante específica de uma imagem.

  4. Faça upload da imagem para o repositório em sua conta Snowflake.

    docker push <repository_url>/<image_name>
    
    Copy

    Exemplo

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

Criação de um pool de computação

Para definir e criar um pool de computação, na próxima célula do notebook, execute o seguinte código:

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

Nesta célula, você define um pool de computação usando o construtor ComputePool, fornecendo valores para os seguintes atributos:

  • instance_family: A família de instância identifica o tipo de máquina que você deseja provisionar para os nós no pool de computação.

    Cada tipo de máquina fornece uma quantidade diferente de recursos de computação para seus pools de computação. Nesta célula, você usa o menor tipo de máquina disponível, CPU_X64_XS. Para obter mais informações, consulte CREATE COMPUTE POOL.

  • min_nodes: O número mínimo de nós para iniciar o pool de computação.

  • max_nodes: O número máximo de nós para os quais o pool de computação pode ser dimensionado.

    Quando você cria um pool de computação, o Snowflake o inicia com o número mínimo de nós especificado. O Snowflake então gerencia o dimensionamento automaticamente e cria novos nós – até o número máximo especificado – quando os nós em execução não podem assumir nenhuma carga de trabalho adicional.

Em seguida, você cria o pool de computação passando a definição do pool de computação para compute_pools.create().

Criação de um serviço

Usando o repositório de imagens e o pool de computação que você definiu, agora é possível definir e criar seu serviço. Um serviço se refere a uma coleção de contêineres em execução em um pool de computação, todos orquestrados no Snowflake.

  1. Para recuperar o repositório com sua imagem de contêiner, na próxima célula do notebook, execute o seguinte código:

    image_repository = schema.image_repositories["MyImageRepository"]
    
    Copy

    Este repositório está em sua conta Snowflake, listado como um estágio no esquema PUBLIC. Você precisa dessa referência para buscar as informações da imagem do contêiner na próxima etapa.

  2. Para definir e criar seu serviço, na próxima célula, execute o seguinte código:

    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(specification),
        min_instances=1,
        max_instances=1,
    )
    
    nginx_service = schema.services.create(service_def)
    
    Copy

    Esta célula define a especificação do serviço e o serviço e, em seguida, cria o serviço para seu servidor Web NGINX. As definições para a especificação e o serviço têm as seguintes propriedades:

    • specification – Você define a especificação usando um literal de cadeia de caracteres formatada (f-string) em Python. A cadeia de caracteres é formatada como YAML.

      A especificação contém o nome do contêiner, um caminho para a imagem do contêiner e os pontos de extremidade que o serviço exporá para acesso público. Neste exemplo, você define a especificação em linha, mas também é possível definir uma especificação como uma referência a um arquivo .yml em um estágio.

    • service_def – Você define um serviço com o construtor Service, passando um nome para o serviço, o pool de computação no qual ele será executado, um caminho para a especificação e o número total de instâncias do serviço.

      Nesta célula, você usa ServiceSpecInlineText para definir o valor de spec pois você define a especificação em linha como uma f-string. É possível especificar o serviço para executar várias instâncias, mas neste exemplo você especifica apenas uma instância do serviço a ser executada configurando min_instances e max_instances como 1.

  3. Para verificar o status do serviço, na próxima célula, execute o seguinte código:

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

    A saída deve ser semelhante a esta:

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

Use seu serviço

Após criar o serviço, o Snowpark Container Services levará alguns minutos para provisionar os pontos de extremidade necessários para acessar o serviço.

  1. Para verificar o status dos pontos de extremidade, na próxima célula do notebook, execute o seguinte código:

    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

    O exemplo de código não é específico para o Snowpark Container Services ou Snowflake Python APIs – ele simplesmente fornece uma maneira prática de verificar se os pontos de extremidade estão prontos. Observe que você busca os pontos de extremidade chamando .fetch().public_endpoints em seu objeto de serviço.

    A saída deve ser semelhante a esta:

    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. Depois que os pontos de extremidade forem provisionados, será possível abrir os pontos de extremidade públicos no navegador.

    Na próxima célula, execute o seguinte código:

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

    A saída deve ser semelhante a esta:

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

    Se for bem-sucedido, você verá a seguinte página de sucesso do NGINX em seu navegador ao visitar o ponto de extremidade:

    Captura de tela da página de sucesso do servidor Web NGINX em um navegador
  3. É possível usar a API Python para gerenciar seu novo serviço.

    Por exemplo, para suspender o serviço e depois verificar seu status, execute o seguinte código:

    from time import sleep
    
    nginx_service.suspend()
    sleep(3)
    print(nginx_service.get_service_status(timeout=5))
    
    Copy
  4. Para retomar o serviço, execute o seguinte código:

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

Com apenas algumas linhas de Python, você conseguiu executar um servidor Web NGINX no Snowflake usando o Snowpark Container Services.

Limpeza

O Snowflake cobra por nós de pool de computação ativos em sua conta. Para evitar cobranças indesejadas, primeiro suspenda o serviço e o pool de computação e, em seguida, elimine ambos os objetos.

  1. Para suspender o pool de computação e o serviço, na próxima célula do notebook, execute o seguinte código:

    new_compute_pool_def.suspend()
    nginx_service.suspend()
    
    Copy
  2. Para descartar o pool de computação e o serviço, execute o seguinte código:

    new_compute_pool_def.drop()
    nginx_service.drop()
    
    Copy

Qual é o próximo passo?

Parabéns! Neste tutorial, você aprendeu os fundamentos para gerenciar componentes no Snowpark Container Services usando o Snowflake Python APIs.

Resumo

Ao longo do caminho, você concluiu estas etapas:

  • Crie um repositório de imagens onde você carrega as imagens de seu aplicativo.

  • Crie um pool de computação onde seu serviço será executado.

  • Crie um serviço para executar seu contêiner de aplicativo.

  • Use e gerencie seu serviço.

  • Limpe seus objetos de recurso do Snowpark Container Services suspendendo-os e descartando-os.

Recursos adicionais

Para obter mais exemplos de uso da API para gerenciar outros tipos de objetos no Snowflake, consulte os seguintes guias do desenvolvedor:

Guia

Descrição

Gerenciamento de bancos de dados, esquemas, tabelas e exibições Snowflake com Python

Use a API para criar e gerenciar bancos de dados, esquemas e tabelas.

Gerenciamento de usuários, funções e concessões Snowflake com Python

Use a API para criar e gerenciar usuários, funções e concessões.

Gerenciamento de recursos de carregamento e descarregamento de dados com Python

Use a API para criar e gerenciar recursos de carregamento e descarregamento de dados, incluindo volumes externos, canais e estágios.

Gerenciamento de tarefas e gráficos de tarefas do Snowflake com Python

Use a API para criar, executar e gerenciar tarefas e gráficos de tarefas.