将语言检测容器部署到 Azure Kubernetes 服务Deploy the Language detection container to Azure Kubernetes Service

了解如何部署语言检测容器。Learn how to deploy the language detection container. 此过程说明如何创建本地 Docker 容器,将容器推送到自己的专用容器注册表,在 Kubernetes 群集中运行容器,以及在 Web 浏览器中对其进行测试。This procedure shows you how create the local Docker containers, push the containers to your own private container registry, run the container in a Kubernetes cluster, and test it in a web browser.

先决条件Prerequisites

此过程要求必须在本地安装和运行多个工具。This procedure requires several tools that must be installed and run locally. 请勿使用 Azure Cloud Shell。Do not use Azure Cloud shell.

  • 使用 Azure 订阅。Use an Azure subscription. 如果没有 Azure 订阅,可在开始前创建一个试用帐户If you don't have an Azure subscription, create a trial account before you begin.
  • 适用于操作系统的 Git,以便克隆此过程中使用的示例Git for your operating system so you can clone the sample used in this procedure.
  • Azure CLIAzure CLI.
  • Docker 引擎并验证 Docker CLI 是否可在控制台窗口中工作。Docker engine and validate that the Docker CLI works in a console window.
  • kubectlkubectl.
  • 具有适当定价层的 Azure 资源。An Azure resource with the correct pricing tier. 并非所有定价层都适用于此容器:Not all pricing tiers work with this container:
    • 仅具有 F0 或标准定价层的文本分析资源 。Text Analytics resource with F0 or Standard pricing tiers only.
    • 具有 S0 定价层的认知服务资源 。Cognitive Services resource with the S0 pricing tier.

运行示例Running the sample

此过程加载并运行认知服务容器示例以进行语言检测。This procedure loads and runs the Cognitive Services Container sample for language detection. 该示例有两个容器,一个用于客户端应用程序,另一个用于认知服务容器。The sample has two containers, one for the client application and one for the Cognitive Services container. 需要将这些映像都推送到自己的 Azure 容器注册表。You need to push both these images to your own Azure Container Registry. 这些映像推送到自己的注册表后,请创建 Azure Kubernetes 服务来访问这些映像和运行容器。Once they are on your own registry, create an Azure Kubernetes Service to access these images and run the containers. 容器在运行时,请使用 kubectl CLI,监视容器性能 。When the containers are running, use the kubectl CLI to watch the containers performance. 使用 HTTP 请求访问客户端应用程序,并查看结果。Access the client application with an HTTP request and see the results.

运行示例容器的概念性想法

示例容器The sample containers

该示例有两个容器映像,一个用于前端网站。The sample has two container images, one for the frontend website. 第二个映像是可返回检测到的文本语言(区域性)的语言检测容器。The second image is the language detection container returning the detected language (culture) of text. 完成后,这两个容器都可以从外部 IP 进行访问。Both containers are accessible from an external IP when you are done.

语言前端容器The language-frontend container

此网站相当于自己的进行语言检测终结点的请求的客户端应用程序。This website is equivalent to your own client-side application that makes requests of the language detection endpoint. 完成此过程后,使用 http://<external-IP>/<text-to-analyze> 在浏览器中访问网站容器,即可获得检测到的字符串语言。When the procedure is finished, you get the detected language of a string of characters by accessing the website container in a browser with http://<external-IP>/<text-to-analyze>. 此 URL 的示例为 http://132.12.23.255/helloworld!An example of this URL is http://132.12.23.255/helloworld!. 浏览器中的结果为 EnglishThe result in the browser is English.

语言容器The language container

在此特定过程中,任何外部访问请求都可以访问语言检测容器。The language detection container, in this specific procedure, is accessible to any external request. 容器未以任何方式更改,因此标准的特定于的认知服务容器的语言检测 API 可供使用。The container hasn't been changed in any way so the standard Cognitive Services container-specific language detection API is available.

对于此容器,该 API 是进行语言检测的 POST 请求。For this container, that API is a POST request for language detection. 与所有认知服务容器一样,可以从容器的托管 Swagger 信息 (http://<external-IP>:5000/swagger/index.html) 了解有关容器的详细信息。As with all Cognitive Services containers, you can learn more about the container from its hosted Swagger information, http://<external-IP>:5000/swagger/index.html.

端口 5000 是用于认知服务容器的默认端口。Port 5000 is the default port used with the Cognitive Services containers.

创建 Azure 容器注册表服务Create Azure Container Registry service

若要将容器部署到 Azure Kubernetes 服务,需要能够访问容器映像。To deploy the container to the Azure Kubernetes Service, the container images need to be accessible. 创建自己的 Azure 容器注册表服务以托管映像。Create your own Azure Container Registry service to host the images.

  1. 登录 Azure CLISign in to the Azure CLI

    az cloud set -n AzureChinaCloud
    az login
    
  2. 创建名为 cogserv-container-rg 的资源组来保存此过程中创建的每一个资源。Create a resource group named cogserv-container-rg to hold every resource created in this procedure.

    az group create --name cogserv-container-rg --location chinaeast2
    
  3. 使用名字后加 registry 这一格式(如 pattyregistry)创建自己的 Azure 容器注册表。Create your own Azure Container Registry with the format of your name then registry, such as pattyregistry. 请勿在名称中使用短划线或下划线字符。Do not use dashes or underline characters in the name.

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

    保存结果,以获取 loginServer 属性 。Save the results to get the loginServer property. 这将是托管容器地址的一部分,稍后将在 language.yml 文件中使用。This will be part of the hosted container's address, used later in the language.yml file.

    > 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": "chinaeast2",
        "loginServer": "pattyregistry.azurecr.cn",
        "name": "pattyregistry",
        "provisioningState": "Succeeded",
        "resourceGroup": "cogserv-container-rg",
        "sku": {
            "name": "Basic",
            "tier": "Basic"
        },
        "status": null,
        "storageAccount": null,
        "tags": {},
        "type": "Microsoft.ContainerRegistry/registries"
    }
    
  4. 登录容器注册表。Sign in to your container registry. 需登录后才能将映像推送到注册表。You need to login before you can push images to your registry.

    az acr login --name pattyregistry
    

获取网站 Docker 映像Get website Docker image

  1. 此过程中使用的示例代码位于认知服务容器样本存储库中。The sample code used in this procedure is in the Cognitive Services containers samples repository. 克隆存储库以生成示例的本地副本。Clone the repository to have a local copy of the sample.

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

    如果存储库已在本地计算机上,请在 \dotnet\Language\FrontendService 目录中查找网站。Once the repository is on your local computer, find the website in the \dotnet\Language\FrontendService directory. 该网站用作客户端应用程序,可调用语言检测容器中托管的语言检测 API。This website acts as the client application calling the language detection API hosted in the language detection container.

  2. 为网站生成 Docker 映像。Build the Docker image for this website. 运行以下命令时,确保控制台位于 Dockerfile 所在的\FrontendService 目录中:Make sure the console is in the \FrontendService directory where the Dockerfile is located when you run the following command:

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

    若要在容器注册表上跟踪版本,请添加具有版本格式的标记,如 v1To track the version on your container registry, add the tag with a version format, such as v1.

  3. 将映像推送到容器注册表。Push the image to your container registry. 这可能需要几分钟的时间。This may take a few minutes.

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

    如果收到 unauthorized: authentication required 错误,请使用 az acr login --name <your-container-registry-name> 命令登录。If you get an unauthorized: authentication required error, login with the az acr login --name <your-container-registry-name> command.

    该过程完成后,结果应类似于以下内容:When the process is done, the results should be similar to:

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

获取语言检测 Docker 映像Get language detection Docker image

  1. 将 Docker 映像的最新版本拉取到本地计算机上。Pull the latest version of the Docker image to the local machine. 这可能需要几分钟的时间。This may take a few minutes. 如果有此容器的较新版本,请将值从 1.1.006770001-amd64-preview 更改到较新版本。If there is a newer version of this container, change the value from 1.1.006770001-amd64-preview to the newer version.

    docker pull mcr.microsoft.com/azure-cognitive-services/language:1.1.006770001-amd64-preview
    
  2. 使用容器注册表标记图像。Tag image with your container registry. 查找最新版本,如果有更新的版本,请替换版本 1.1.006770001-amd64-previewFind the latest version and replace the version 1.1.006770001-amd64-preview if you have a more recent version.

    docker tag mcr.microsoft.com/azure-cognitive-services/language pattiyregistry.azurecr.cn/language:1.1.006770001-amd64-preview
    
  3. 将映像推送到容器注册表。Push the image to your container registry. 这可能需要几分钟的时间。This may take a few minutes.

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

获取容器注册表凭据Get Container Registry credentials

需要执行以下步骤来获取所需信息,以便将容器注册表与稍后此过程中要创建的 Azure Kubernetes 服务进行连接。The following steps are needed to get the required information to connect your container registry with the Azure Kubernetes Service you create later in this procedure.

  1. 创建服务主体。Create service principal.

    az ad sp create-for-rbac --skip-assignment
    

    为步骤 3 中代理人参数 <appId> 的保存结果 appId 值。Save the results appId value for the assignee parameter in step 3, <appId>. 为下一节中 client-secret 参数 <client-secret> 保存 passwordSave the password for the next section's client-secret parameter <client-secret>.

    > az ad sp create-for-rbac --skip-assignment
    {
      "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. 获取容器注册表 ID。Get your container registry ID.

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

    为下一步中范围参数值 <acrId> 保存输出。Save the output for the scope parameter value, <acrId>, in the next step. 输出如下所示:It looks like:

    > az acr show --resource-group cogserv-container-rg --name pattyregistry --query "id" --o table
    /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/cogserv-container-rg/providers/Microsoft.ContainerRegistry/registries/pattyregistry
    

    为本节中步骤 3 保存完整值。Save the full value for step 3 in this section.

  3. 若要授予 AKS 群集使用容器注册表中存储的映像的适当访问权限,请创建角色分配。To grant the correct access for the AKS cluster to use images stored in your container registry, create a role assignment. <appId><acrId> 替换为在前两个步骤中收集的值。Replace <appId> and <acrId> with the values gathered in the previous two steps.

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

创建 Azure Kubernetes 服务Create Azure Kubernetes Service

  1. 创建 Kubernetes 群集。Create the Kubernetes cluster. 所有参数值都来自前一部分,name 参数除外。All the parameter values are from previous sections except the name parameter. 选择一个名称,指明其创建者及其用途,例如 patty-kubeChoose a name that indicates who created it and its purpose, such as 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
    

    这个步骤可能需要几分钟的时间。This step may take a few minutes. 结果为:The result is:

    > az aks create --resource-group cogserv-container-rg --name patty-kube --node-count 2  --service-principal <appId>  --client-secret <client-secret>  --generate-ssh-keys
    {
      "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.chinaeast2.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": "chinaeast2",
      "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_chinaeast2",
      "provisioningState": "Succeeded",
      "resourceGroup": "cogserv-container-rg",
      "servicePrincipalProfile": {
        "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "keyVaultSecretRef": null,
        "secret": null
      },
      "tags": null,
      "type": "Microsoft.ContainerService/ManagedClusters"
    }
    

    服务已创建,但还没有网站容器或语言检测容器。The service is created but it doesn't have the website container or language detection container yet.

  2. 获取 Kubernetes 群集的凭据。Get credentials of the Kubernetes cluster.

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

将业务流程定义加载到 Kubernetes 服务中Load the orchestration definition into your Kubernetes service

本部分使用 kubectl CLI 与 Azure Kubernetes 服务通信 。This section uses the kubectl CLI to talk with the Azure Kubernetes Service.

  1. 在加载业务流程定义之前,请检查 kubectl 是否有权访问节点 。Before loading the orchestration definition, check kubectl has access to the nodes.

    kubectl get nodes
    

    响应如下所示:The response looks like:

    > kubectl get nodes
    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. 复制以下文件并将其命名为 language.ymlCopy the following file and name it language.yml. 该文件含有一个 service 部分和一个 deployment 部分,各自用于两种容器类型,即 language-frontend 网站容器和 language 检测容器。The file has a service section and a deployment section each for the two container types, the language-frontend website container and the language detection container.

    # 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. 根据下表更改 language.yml 的语言前端部署行,以添加自己的容器注册表映像名称、客户端密码和文本分析设置。Change the language-frontend deployment lines of language.yml based on the following table to add your own container registry image names, client secret, and text analytics settings.

    语言前端部署设置Language-frontend deployment settings 目的Purpose
    第 32 行Line 32
    image 属性image property
    容器注册表中的前端映像的映像位置Image location for the frontend image in your Container Registry
    <container-registry-name>.azurecr.cn/language-frontend:v1
    第 44 行Line 44
    name 属性name property
    映像的容器注册表机密,在上一节中称为 <client-secret>Container Registry secret for the image, referred to as <client-secret> in a previous section.
  4. 根据下表更改 language.yml 的语言部署行,以添加自己的容器注册表映像名称、客户端密码和文本分析设置。Change the language deployment lines of language.yml based on the following table to add your own container registry image names, client secret, and text analytics settings.

    语言部署设置Language deployment settings 目的Purpose
    第 78 行Line 78
    image 属性image property
    容器注册表中语言映像的映像位置Image location for the language image in your Container Registry
    <container-registry-name>.azurecr.cn/language:1.1.006770001-amd64-preview
    第 95 行Line 95
    name 属性name property
    映像的容器注册表机密,在上一节中称为 <client-secret>Container Registry secret for the image, referred to as <client-secret> in a previous section.
    第 91 行Line 91
    apiKey 属性apiKey property
    文本分析资源密钥Your text analytics resource key
    第 92 行Line 92
    billing 属性billing property
    文本分析资源的账单终结点。The billing endpoint for your text analytics resource.
    https://chinaeast2.api.cognitive.azure.cn/text/analytics/v2.1

    由于 apiKey 和账单终结点已设置为 Kubernetes 业务流程定义的一部分,因此网站容器无需了解这些内容或将其作为请求的一部分传递 。Because the apiKey and billing endpoint are set as part of the Kubernetes orchestration definition, the website container doesn't need to know about these or pass them as part of the request. 网站容器按其业务流程协调程序名称 language 引用语言检测容器。The website container refers to the language detection container by its orchestrator name language.

  5. 从创建和保存 language.yml 的文件夹中加载此示例的业务流程定义文件。Load the orchestration definition file for this sample from the folder where you created and saved the language.yml.

    kubectl apply -f language.yml
    

    响应为:The response is:

    > kubectl apply -f language.yml
    service "language-frontend" created
    deployment.apps "language-frontend" created
    service "language" created
    deployment.apps "language" created
    

获取容器的外部 IPGet external IPs of containers

对于这两个容器,请验证 language-frontendlanguage 服务是否正在运行,并获取外部 IP 地址。For the two containers, verify the language-frontend and language services are running and get the external IP address.

kubectl get all
> 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

如果服务的 EXTERNAL-IP 显示为挂起,请重新运行该命令,直到显示 IP 地址,然后再转到下一步。If the EXTERNAL-IP for the service is shown as pending, rerun the command until the IP address is shown before moving to the next step.

测试语言检测容器Test the language detection container

打开浏览器并导航到上一节中 language 容器的外部 IP:http://<external-ip>:5000/swagger/index.htmlOpen a browser and navigate to the external IP of the language container from the previous section: http://<external-ip>:5000/swagger/index.html. 可以使用 API 的 Try it 功能来测试语言检测终结点。You can use the Try it feature of the API to test the language detection endpoint.

查看容器的 swagger 文档

测试客户端应用程序容器Test the client application container

使用以下格式将浏览器中的 URL 更改为 language-frontend 容器的外部 IP:http://<external-ip>/helloworldChange the URL in the browser to the external IP of the language-frontend container using the following format: http://<external-ip>/helloworld. helloworld 的英文区域性文本预测为 EnglishThe English culture text of helloworld is predicted as English.

清理资源Clean up resources

群集操作完成后,请删除 Azure 资源组。When you are done with the cluster, delete the Azure resource group.

az group delete --name cogserv-container-rg