Implementar um contentor de deteção de idioma no Azure Kubernetes Service

Saiba como implementar o contentor de deteção de idioma. Este procedimento mostra como criar os contentores do Docker locais, enviar os contentores para o seu próprio registo de contentor privado, executar o contentor num cluster do Kubernetes e testá-lo num browser.

Pré-requisitos

Este procedimento requer várias ferramentas que têm de ser instaladas e executadas localmente. Não utilize o Azure Cloud Shell.

  • Utilizar uma subscrição do Azure. Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.
  • Git para o seu sistema operativo para que possa clonar o exemplo utilizado neste procedimento.
  • CLI do Azure.
  • Motor do Docker e valide se a CLI do Docker funciona numa janela da consola.
  • kubectl.
  • Um recurso do Azure com o escalão de preço correto. Nem todos os escalões de preço funcionam com este contentor:
    • Recurso de idioma apenas com escalões de preço F0 ou Standard.
    • Recurso dos serviços de IA do Azure com o escalão de preço S0.

Executar o exemplo

Este procedimento carrega e executa o exemplo de contentor dos serviços de IA do Azure para deteção de idioma. O exemplo tem dois contentores, um para a aplicação cliente e outro para o contentor dos serviços de IA do Azure. Vamos enviar estas duas imagens para o Azure Container Registry. Assim que estiverem no seu próprio registo, crie um Azure Kubernetes Service para aceder a estas imagens e executar os contentores. Quando os contentores estiverem em execução, utilize a CLI do kubectl para watch o desempenho dos contentores. Aceda à aplicação cliente com um pedido HTTP e veja os resultados.

Um diagrama que mostra a ideia conceptual de executar um contentor no Kubernetes

Os contentores de exemplo

O exemplo tem duas imagens de contentor, uma para o site de front-end. A segunda imagem é o contentor de deteção de idioma que devolve o idioma (cultura) de texto detetado. Ambos os contentores estão acessíveis a partir de um IP externo quando terminar.

O contentor language-front-end

Este site é equivalente à sua própria aplicação do lado do cliente que faz pedidos do ponto final de deteção de idioma. Quando o procedimento estiver concluído, obtém o idioma detetado de uma cadeia de carateres ao aceder ao contentor do site num browser com http://<external-IP>/<text-to-analyze>. Um exemplo deste URL é http://132.12.23.255/helloworld!. O resultado no browser é English.

O contentor de idiomas

O contentor de deteção de idiomas, neste procedimento específico, está acessível a qualquer pedido externo. O contentor não foi alterado de forma alguma, pelo que a API de deteção de idioma específica dos serviços do Azure AI padrão está disponível.

Para este contentor, essa API é um pedido POST para deteção de idioma. Tal como acontece com todos os contentores de IA do Azure, pode saber mais sobre o contentor a partir das informações do Swagger alojadas, http://<external-IP>:5000/swagger/index.html.

A porta 5000 é a porta predefinida utilizada com os contentores de IA do Azure.

Criar Azure Container Registry serviço

Para implementar o contentor no Azure Kubernetes Service, as imagens de contentor têm de estar acessíveis. Crie o seu próprio serviço Azure Container Registry para alojar as imagens.

  1. Iniciar sessão na CLI do Azure

    az login
    
  2. Crie um grupo de recursos com o nome cogserv-container-rg para conter todos os recursos criados neste procedimento.

    az group create --name cogserv-container-rg --location westus
    
  3. Crie o seu próprio Azure Container Registry com o formato do seu nome e, em seguidaregistry, , como pattyregistry. Não utilize traços nem carateres de sublinhado no nome.

    az acr create --resource-group cogserv-container-rg --name pattyregistry --sku Basic
    

    Guarde os resultados para obter a propriedade loginServer . Isto fará parte do endereço do contentor alojado, utilizado mais tarde no language.yml ficheiro.

    az acr create --resource-group cogserv-container-rg --name pattyregistry --sku Basic
    
    {
        "adminUserEnabled": false,
        "creationDate": "2019-01-02T23:49:53.783549+00:00",
        "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/cogserv-container-rg/providers/Microsoft.ContainerRegistry/registries/pattyregistry",
        "location": "westus",
        "loginServer": "pattyregistry.azurecr.io",
        "name": "pattyregistry",
        "provisioningState": "Succeeded",
        "resourceGroup": "cogserv-container-rg",
        "sku": {
            "name": "Basic",
            "tier": "Basic"
        },
        "status": null,
        "storageAccount": null,
        "tags": {},
        "type": "Microsoft.ContainerRegistry/registries"
    }
    
  4. Inicie sessão no seu registo de contentor. Tem de iniciar sessão antes de poder enviar imagens para o seu registo.

    az acr login --name pattyregistry
    

Obter imagem do Docker do site

  1. O código de exemplo utilizado neste procedimento está no repositório de exemplos de contentores de IA do Azure. Clone o repositório para ter uma cópia local do exemplo.

    git clone https://github.com/Azure-Samples/cognitive-services-containers-samples
    

    Assim que o repositório estiver no seu computador local, localize o site no diretório \dotnet\Language\FrontendService . Este site funciona como a aplicação cliente que chama a API de deteção de idioma alojada no contentor de deteção de idioma.

  2. Crie a imagem do Docker para este site. Certifique-se de que a consola está no diretório \FrontendService onde o Dockerfile está localizado quando executar o seguinte comando:

    docker build -t language-frontend -t pattiyregistry.azurecr.io/language-frontend:v1 .
    

    Para controlar a versão no seu registo de contentor, adicione a etiqueta com um formato de versão, como v1.

  3. Envie a imagem para o seu registo de contentor. Esta operação poderá demorar alguns minutos.

    docker push pattyregistry.azurecr.io/language-frontend:v1
    

    Se receber um unauthorized: authentication required erro, inicie sessão com o az acr login --name <your-container-registry-name> comando .

    Quando o processo estiver concluído, os resultados devem ser semelhantes a:

    The push refers to repository [pattyregistry.azurecr.io/language-frontend]
    82ff52ee6c73: Pushed
    07599c047227: Pushed
    816caf41a9a1: Pushed
    2924be3aed17: Pushed
    45b83a23806f: Pushed
    ef68f6734aa4: Pushed
    v1: digest: sha256:31930445deee181605c0cde53dab5a104528dc1ff57e5b3b34324f0d8a0eb286 size: 1580
    

Obter imagem do Docker de deteção de idioma

  1. Solicite a versão mais recente da imagem do Docker para o computador local. Esta operação poderá demorar alguns minutos. Se existir uma versão mais recente deste contentor, altere o valor de 1.1.006770001-amd64-preview para a versão mais recente.

    docker pull mcr.microsoft.com/azure-cognitive-services/language:1.1.006770001-amd64-preview
    
  2. Etiquetar imagem com o seu registo de contentor. Localize a versão mais recente e substitua a versão 1.1.006770001-amd64-preview se tiver uma versão mais recente.

    docker tag mcr.microsoft.com/azure-cognitive-services/language pattiyregistry.azurecr.io/language:1.1.006770001-amd64-preview
    
  3. Envie a imagem para o seu registo de contentor. Esta operação poderá demorar alguns minutos.

    docker push pattyregistry.azurecr.io/language:1.1.006770001-amd64-preview
    

Obter credenciais do Container Registry

São necessários os seguintes passos para obter as informações necessárias para ligar o registo de contentor ao Azure Kubernetes Service criar mais à frente neste procedimento.

  1. Criar principal de serviço.

    az ad sp create-for-rbac
    

    Guarde o valor de resultados appId do parâmetro assignee no passo 3, <appId>. Guarde o password para o parâmetro <client-secret>client-secret da próxima secção.

    {
      "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "displayName": "azure-cli-2018-12-31-18-39-32",
      "name": "http://azure-cli-2018-12-31-18-39-32",
      "password": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    }
    
  2. Obtenha o ID do registo de contentor.

    az acr show --resource-group cogserv-container-rg --name pattyregistry --query "id" --output table
    

    Guarde o resultado do valor do parâmetro de âmbito, <acrId>, no passo seguinte. Tem o seguinte aspeto:

    /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/cogserv-container-rg/providers/Microsoft.ContainerRegistry/registries/pattyregistry
    

    Guarde o valor completo do passo 3 nesta secção.

  3. Para conceder o acesso correto ao cluster do AKS para utilizar imagens armazenadas no seu registo de contentor, crie uma atribuição de função. Substitua <appId> e <acrId> pelos valores recolhidos nos dois passos anteriores.

    az role assignment create --assignee <appId> --scope <acrId> --role Reader
    

Criar Azure Kubernetes Service

  1. Crie o cluster do Kubernetes. Todos os valores dos parâmetros são de secções anteriores, exceto o parâmetro name. Escolha um nome que indique quem o criou e o seu objetivo, como patty-kube.

    az aks create --resource-group cogserv-container-rg --name patty-kube --node-count 2  --service-principal <appId>  --client-secret <client-secret>  --generate-ssh-keys
    

    Este passo pode demorar alguns minutos. O resultado é:

    {
      "aadProfile": null,
      "addonProfiles": null,
      "agentPoolProfiles": [
        {
          "count": 2,
          "dnsPrefix": null,
          "fqdn": null,
          "maxPods": 110,
          "name": "nodepool1",
          "osDiskSizeGb": 30,
          "osType": "Linux",
          "ports": null,
          "storageProfile": "ManagedDisks",
          "vmSize": "Standard_DS1_v2",
          "vnetSubnetId": null
        }
      ],
      "dnsPrefix": "patty-kube--65a101",
      "enableRbac": true,
      "fqdn": "patty-kube--65a101-341f1f54.hcp.westus.azmk8s.io",
      "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/cogserv-container-rg/providers/Microsoft.ContainerService/managedClusters/patty-kube",
      "kubernetesVersion": "1.9.11",
      "linuxProfile": {
        "adminUsername": "azureuser",
        "ssh": {
          "publicKeys": [
            {
              "keyData": "ssh-rsa AAAAB3NzaC...ohR2d81mFC
            }
          ]
        }
      },
      "location": "westus",
      "name": "patty-kube",
      "networkProfile": {
        "dnsServiceIp": "10.0.0.10",
        "dockerBridgeCidr": "172.17.0.1/16",
        "networkPlugin": "kubenet",
        "networkPolicy": null,
        "podCidr": "10.244.0.0/16",
        "serviceCidr": "10.0.0.0/16"
      },
      "nodeResourceGroup": "MC_patty_westus",
      "provisioningState": "Succeeded",
      "resourceGroup": "cogserv-container-rg",
      "servicePrincipalProfile": {
        "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "keyVaultSecretRef": null,
        "secret": null
      },
      "tags": null,
      "type": "Microsoft.ContainerService/ManagedClusters"
    }
    

    O serviço é criado, mas ainda não tem o contentor do site ou o contentor de deteção de idioma.

  2. Obtenha as credenciais do cluster do Kubernetes.

    az aks get-credentials --resource-group cogserv-container-rg --name patty-kube
    

Carregar a definição de orquestração para o seu serviço do Kubernetes

Esta secção utiliza a CLI kubectl para falar com o Azure Kubernetes Service.

  1. Antes de carregar a definição de orquestração, verifique se o kubectl tem acesso aos nós.

    kubectl get nodes
    

    A resposta tem o seguinte aspeto:

    NAME                       STATUS    ROLES     AGE       VERSION
    aks-nodepool1-13756812-0   Ready     agent     6m        v1.9.11
    aks-nodepool1-13756812-1   Ready     agent     6m        v1.9.11
    
  2. Copie o seguinte ficheiro e dê-lhe o nome language.yml. O ficheiro tem uma service secção e uma secção para cada um deployment dos dois tipos de contentor, o contentor do language-frontend site e o language contentor de deteção.

    # A service which exposes the .net frontend app container through a dependable hostname: http://language-frontend:5000
    apiVersion: v1
    kind: Service
    metadata:
      name: language-frontend
      labels:
        run: language-frontend
    spec:
      selector:
        app: language-frontend
      type: LoadBalancer
      ports:
      - name: front
        port: 80
        targetPort: 80
        protocol: TCP
    ---
    # A deployment declaratively indicating how many instances of the .net frontend app container we want up
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: language-frontend
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: language-frontend
        spec:
          containers:
          - name: language-frontend
            image: # < URI of the Frontend App image >
            ports:
            - name: public-port
              containerPort: 80
            livenessProbe:
              httpGet:
                path: /status
                port: public-port
              initialDelaySeconds: 30
              timeoutSeconds: 1
              periodSeconds: 10
          imagePullSecrets:
            - name: # < Name of the registry secret providing access to the frontend image >
          automountServiceAccountToken: false
    ---
    # A service which exposes the cognitive-service containers through a dependable hostname: http://language:5000
    apiVersion: v1
    kind: Service
    metadata:
      name: language
      labels:
        run: language
    spec:
      selector:
        app: language
      type: LoadBalancer
      ports:
      - name: language
        port: 5000
        targetPort: 5000
        protocol: TCP
    ---
    # A deployment declaratively indicating how many instances of the cognitive-service container we want up
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: language
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: language
        spec:
          containers:
          - name: language
            image: # < URI of the Language Image >
            ports:
            - name: public-port
              containerPort: 5000
            livenessProbe:
              httpGet:
                path: /status
                port: public-port
              initialDelaySeconds: 30
              timeoutSeconds: 1
              periodSeconds: 10
            args:
                - "eula=accept"
                - "apikey=" # < API Key for the Language Service >
                - "billing=" # < Language billing endpoint URI >
    
          imagePullSecrets:
            - name: # < Name of the registry secret providing access to the Language image >
    
          automountServiceAccountToken: false
    
  3. Altere as linhas de implementação de front-end de idioma de language.yml com base na tabela seguinte para adicionar os seus próprios nomes de imagens do registo de contentor, o segredo do cliente e as definições do Serviço de idiomas.

    Definições de implementação de front-end de idioma Objetivo
    Linha 32
    image propriedade
    Localização da imagem de front-end no Container Registry
    <container-registry-name>.azurecr.io/language-frontend:v1
    Linha 44
    name propriedade
    Segredo do Container Registry para a imagem, referido como <client-secret> numa secção anterior.
  4. Altere as linhas de implementação de idioma de language.yml com base na tabela seguinte para adicionar os seus próprios nomes de imagens do registo de contentor, o segredo do cliente e as definições do Serviço de idiomas.

    Definições de implementação de idioma Objetivo
    Linha 78
    image propriedade
    Localização da imagem do idioma no Container Registry
    <container-registry-name>.azurecr.io/language:1.1.006770001-amd64-preview
    Linha 95
    name propriedade
    Segredo do Container Registry para a imagem, referido como <client-secret> numa secção anterior.
    Linha 91
    apiKey propriedade
    A sua chave de recurso do Serviço de idiomas
    Linha 92
    billing propriedade
    O ponto final de faturação do recurso do Serviço de idiomas.
    https://westus.api.cognitive.microsoft.com/text/analytics/v2.1

    Uma vez que a apiKey e o ponto final de faturação estão definidos como parte da definição de orquestração do Kubernetes, o contentor do site não precisa de os conhecer nem de os transmitir como parte do pedido. O contentor do site refere-se ao contentor de deteção de idiomas pelo nome languagedo orquestrador .

  5. Carregue o ficheiro de definição de orquestração para este exemplo a partir da pasta onde criou e guardou o language.yml.

    kubectl apply -f language.yml
    

    A resposta é:

    service "language-frontend" created
    deployment.apps "language-frontend" created
    service "language" created
    deployment.apps "language" created
    

Obter IPs externos de contentores

Para os dois contentores, verifique se os language-frontend serviços e language estão em execução e obtenha o endereço IP externo.

kubectl get all
NAME                                     READY     STATUS    RESTARTS   AGE
pod/language-586849d8dc-7zvz5            1/1       Running   0          13h
pod/language-frontend-68b9969969-bz9bg   1/1       Running   1          13h

NAME                        TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)          AGE
service/kubernetes          ClusterIP      10.0.0.1      <none>          443/TCP          14h
service/language            LoadBalancer   10.0.39.169   104.42.172.68   5000:30161/TCP   13h
service/language-frontend   LoadBalancer   10.0.42.136   104.42.37.219   80:30943/TCP     13h

NAME                                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/language            1         1         1            1           13h
deployment.extensions/language-frontend   1         1         1            1           13h

NAME                                                 DESIRED   CURRENT   READY     AGE
replicaset.extensions/language-586849d8dc            1         1         1         13h
replicaset.extensions/language-frontend-68b9969969   1         1         1         13h

NAME                                DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/language            1         1         1            1           13h
deployment.apps/language-frontend   1         1         1            1           13h

NAME                                           DESIRED   CURRENT   READY     AGE
replicaset.apps/language-586849d8dc            1         1         1         13h
replicaset.apps/language-frontend-68b9969969   1         1         1         13h

Se o EXTERNAL-IP para o serviço for apresentado como pendente, execute novamente o comando até que o endereço IP seja apresentado antes de passar para o passo seguinte.

Testar o contentor de deteção de idioma

Abra um browser e navegue para o IP externo do language contentor a partir da secção anterior: http://<external-ip>:5000/swagger/index.html. Pode utilizar a Try it funcionalidade da API para testar o ponto final de deteção de idioma.

Uma captura de ecrã a mostrar a documentação do swagger do contentor

Testar o contentor da aplicação cliente

Altere o URL no browser para o IP externo do language-frontend contentor com o seguinte formato: http://<external-ip>/helloworld. O texto da cultura inglesa de helloworld é previsto como English.

Limpar os recursos

Quando terminar o cluster, elimine o grupo de recursos do Azure.

az group delete --name cogserv-container-rg

Passos seguintes

Contentores de IA do Azure