Azure Kubernetes Service に言語検出コンテナーをデプロイする

言語検出コンテナーをデプロイする方法について説明します。 この手順では、ローカルの Docker コンテナーを作成し、コンテナーを独自のプライベート コンテナー レジストリにプッシュし、Kubernetes クラスターでコンテナーを実行して、Web ブラウザーでテストする方法を示します。

前提条件

この手順には、ローカルでインストールして実行する必要があるいくつかのツールが必要です。 Azure Cloud Shell は使用しないでください。

  • Azure サブスクリプションを使用してください。 Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。
  • この手順で使用するサンプルのクローンを作成できるよう、オペレーティング システム用の Git を使用してください。
  • Azure CLI
  • Docker エンジン。Docker CLI がコンソール ウィンドウで動作することを確認します。
  • kubectl
  • 適切な価格レベルの Azure リソース。 すべての価格レベルでこのコンテナーを使用するわけではありません。
    • F0 または Standard 価格レベルのみの 言語リソース。
    • S0 価格レベルの Azure AI サービス リソース。

サンプルの実行

この手順では、言語検出用の Azure AI サービス コンテナーのサンプルを読み込んで実行します。 このサンプルには、クライアント アプリケーション用と Azure AI サービス コンテナー用の 2 つのコンテナーがあります。 これらのイメージを両方とも Azure Container Registry にプッシュします。 独自のレジストリに設定したら、これらのイメージにアクセスしてコンテナーを実行する Azure Kubernetes Service を作成します。 コンテナーの実行中に、kubectl CLI を使用してコンテナーのパフォーマンスを監視します。 HTTP 要求を使用してクライアント アプリケーションにアクセスし、結果を確認します。

Kubernetes でのコンテナーの実行の概念を示す図

サンプルのコンテナー

このサンプルには 2 つのコンテナー イメージがあり、その 1 つはフロントエンドの Web サイトのイメージです。 2 つ目のイメージは、テキストの検出された言語 (カルチャ) を返す言語検出コンテナーです。 完了したら、両方のコンテナーが外部 IP からアクセス可能になります。

言語フロントエンド コンテナー

この Web サイトは、言語検出エンドポイントの要求を行う独自のクライアント側アプリケーションに相当します。 この手順が完了したら、http://<external-IP>/<text-to-analyze> を使用してブラウザーで Web サイトのコンテナーにアクセスして、検出された言語の文字の文字列を取得します。 この URL の例は http://132.12.23.255/helloworld! です。 ブラウザーでの結果は English です。

言語コンテナー

言語検出コンテナーは、この特定の手順では、外部の要求にアクセスできます。 このコンテナーは、標準の Azure AI サービス コンテナーに固有の言語検出 API を使用できるように、一切変更されていません。

このコンテナーの場合、その API は言語検出の POST 要求です。 すべての Azure AI コンテナーと同様、コンテナーの詳細については、ホストされている Swagger 情報 (http://<external-IP>:5000/swagger/index.html) を参照してください。

ポート 5000 は、Azure AI コンテナーで使用される既定のポートです。

Azure Container Registry サービスを作成する

Azure Kubernetes Service にコンテナーをデプロイするには、コンテナー イメージがアクセス可能である必要があります。 このイメージをホストする、独自の Azure Container Registry サービスを作成します。

  1. Azure CLI にサインインする

    az login
    
  2. cogserv-container-rg という名前のリソース グループを作成して、この手順で作成したすべてのリソースを保持します。

    az group create --name cogserv-container-rg --location westus
    
  3. ご自分の名前とその後に registry が続く形式 (pattyregistry など) で、独自の Azure Container Registry を作成します。 名前にダッシュや下線の文字を使用しないでください。

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

    結果を保存して、loginServer プロパティを取得します。 これは、後で language.yml ファイルで使用する、ホストされているコンテナーのアドレスの一部となります。

    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. コンテナー レジストリにサイン インします。 レジストリにイメージをプッシュする前に、ログインする必要があります。

    az acr login --name pattyregistry
    

Web サイトの Docker イメージを取得する

  1. この手順で使用するサンプル コードは、Azure AI コンテナーのサンプル リポジトリにあります。 リポジトリを複製して、サンプルのローカル コピーを作成します。

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

    リポジトリがローカル コンピューターに作成されたら、\dotnet\Language\FrontendService ディレクトリで Web サイトを検索します。 この Web サイトは、言語検出コンテナーでホストされる言語検出 API を呼び出すクライアント アプリケーションとして機能します。

  2. この Web サイトの Docker イメージをビルドします。 次のコマンドを実行するときに、Dockerfile がある \FrontendService ディレクトリにコンソールがあることを確認します。

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

    コンテナー レジストリのバージョンを追跡するには、バージョン形式 (v1 など) を含むタグを追加します。

  3. コンテナー レジストリにイメージをプッシュします。 これには数分かかることがあります。

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

    unauthorized: authentication required エラーが表示された場合、az acr login --name <your-container-registry-name> コマンドを使用してログインします。

    プロセスが完了すると、結果は次の例のようになります。

    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
    

言語検出 Docker イメージを取得する

  1. ローカル コンピューターに最新バージョンの Docker イメージをプルします。 これには数分かかることがあります。 このコンテナーの新しいバージョンがある場合は、値を 1.1.006770001-amd64-preview から新しいバージョンに変更します。

    docker pull mcr.microsoft.com/azure-cognitive-services/language:1.1.006770001-amd64-preview
    
  2. コンテナー レジストリを含むイメージをタグ付けします。 最新バージョンを検索し、より新しいバージョンがある場合はバージョン 1.1.006770001-amd64-preview を置き換えます。

    docker tag mcr.microsoft.com/azure-cognitive-services/language pattiyregistry.azurecr.io/language:1.1.006770001-amd64-preview
    
  3. コンテナー レジストリにイメージをプッシュします。 これには数分かかることがあります。

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

コンテナー レジストリの資格情報を取得する

次の手順は、この手順で後で作成する Azure Kubernetes Service で、コンテナー レジストリへの接続に必要な情報を取得するために必要です。

  1. サービス プリンシパルを作成します。

    az ad sp create-for-rbac
    

    手順 3 で割り当てたパラメーター <appId> の結果の値 appId を保存します。 次のセクションの client-secret パラメーター <client-secret> のために password を保存します。

    {
      "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 を取得します。

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

    次の手順で、スコープ パラメーター値、<acrId> の出力を保存します。 次のように表示されます。

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

    このセクションの手順 3 の完全な値を保存します。

  3. コンテナー イメージに格納されているイメージを使用するために、AKS クラスターに適切なアクセス権を付与するには、ロールの割り当てを作成します。 <appId><acrId> を、前の 2 つの手順で収集した値に置き換えます。

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

Azure Kubernetes Service を作成する

  1. Kubernetes クラスターを作成します。 name パラメーターを除き、すべてのパラメーター値は前のセクションと同じです。 作成したユーザーとその目的を示す名前 (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
    

    この手順には数分かかることがあります。 結果は次のとおりです。

    {
      "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"
    }
    

    サービスが作成されますが、Web サイトのコンテナーや言語検出コンテナーはまだありません。

  2. Kubernetes クラスターの資格情報を取得します。

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

Kubernetes サービスにオーケストレーションの定義を読み込む

このセクションでは、kubectl CLI を使用して Azure Kubernetes Service と通信します。

  1. オーケストレーションの定義を読み込む前に、kubectl がノードにアクセスできることを確認します。

    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.yml という名前を付けます。 このファイルには、2 種類のコンテナー (language-frontend Web サイトのコンテナーとlanguage 検出コンテナー) のそれぞれに、service セクションと deployment セクションがあります。

    # 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 の言語フロントエンドのデプロイの行を変更して、独自のコンテナー レジストリのイメージ名、クライアント シークレット、および言語サービスの設定を追加します。

    言語フロントエンドのデプロイ設定 目的
    行 32
    image プロパティ
    コンテナー レジストリ内のフロントエンド イメージのイメージの場所
    <container-registry-name>.azurecr.io/language-frontend:v1
    行 44
    name プロパティ
    イメージの Container Registry シークレット (前のセクションでは <client-secret> と呼ばれています)。
  4. 次の表に基づいて language.yml の言語のデプロイの行を変更して、独自のコンテナー レジストリのイメージ名、クライアント シークレット、および言語サービスの設定を追加します。

    言語のデプロイの設定 目的
    行 78
    image プロパティ
    コンテナー レジストリ内の言語イメージのイメージの場所
    <container-registry-name>.azurecr.io/language:1.1.006770001-amd64-preview
    行 95
    name プロパティ
    イメージの Container Registry シークレット (前のセクションでは <client-secret> と呼ばれています)。
    行 91
    apiKey プロパティ
    言語サービスのリソース キー
    行 92
    billing プロパティ
    言語サービス リソースの課金エンドポイント。
    https://westus.api.cognitive.microsoft.com/text/analytics/v2.1

    apiKey課金エンドポイントは、Kubernetes オーケストレーションの定義の一部として設定されているため、Web サイト コンテナーがこれらについて認識したり要求の一部として渡したりする必要はありません。 Web サイト コンテナーは、そのオーケストレーター名 language によって言語検出コンテナーを示します。

  5. このサンプルのオーケストレーションの定義ファイルを、language.yml を作成して保存したフォルダーから読み込みます。

    kubectl apply -f language.yml
    

    応答は次のとおりです。

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

コンテナーの外部 IP を取得する

2 つのコンテナーについて、language-frontendlanguage のサービスが実行中であることを確認し、外部 IP アドレスを取得します。

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 アドレスが表示されるまでコマンドを再実行します。

言語検出コンテナーをテストする

ブラウザーを開いて、前のセクションの language コンテナーの外部 IP (http://<external-ip>:5000/swagger/index.html) に移動します。 API の Try it 機能を使用して、言語検出エンドポイントをテストすることができます。

コンテナーの Swagger ドキュメントを示すスクリーンショット

クライアント アプリケーション コンテナーをテストする

http://<external-ip>/helloworld の形式を使用して、ブラウザーで URL を language-frontend コンテナーの外部 IP に変更します。 helloworld の英語のカルチャ テキスト は English と予測されます。

リソースをクリーンアップする

クラスターの作業が終了したら、Azure リソース グループを削除します。

az group delete --name cogserv-container-rg

次のステップ

Azure AI コンテナー