Развертывание контейнера распознавания языка в Службе Azure Kubernetes
Узнайте, как развертывать контейнер распознавания языка. В статье описано, как создавать локальные контейнеры Docker, отправлять их в закрытый реестр контейнеров и запускать в кластере Kubernetes, а также тестировать в веб-браузере.
Необходимые компоненты
Для выполнения этой процедуры необходимо установить и запустить несколько средств локально. Не используйте Azure Cloud Shell.
- Используйте подписку Azure. Если у вас нет подписки Azure, создайте бесплатную учетную запись, прежде чем приступить к работе.
- Git для вашей операционной системы, чтобы клонировать пример для этой процедуры.
- Azure CLI.
- Модуль Docker, для которого нужно проверить работоспособность Docker CLI в окне консоли.
- kubectl.
- Ресурс Azure с правильной ценовой категорией. Не все ценовые категории работают с этим контейнером:
- Ресурс Язык с ценовой категорией F0 или "Стандартный".
- Ресурс служб искусственного интеллекта Azure с ценовой категорией S0.
Выполнение примера
Эта процедура загружает и запускает пример контейнера служб ИИ Azure для обнаружения языка. В примере есть два контейнера, один для клиентского приложения и один для контейнера служб ИИ Azure. Мы отправим оба этих образа в Реестр контейнеров Azure. Разместив их в собственном реестре, создайте Службу Azure Kubernetes для доступа к образам и выполнения контейнеров. Когда контейнеры будут запущены, используйте интерфейс командной строки kubectl для контроля производительности контейнеров. Создайте HTTP-запрос к клиентскому приложению и проверьте результаты его выполнения.
Примеры контейнеров
Этот пример содержит два образа контейнеров, один из которых отвечает за интерфейсный веб-сайт. Второй образ — это контейнер распознавания языка, который возвращает сведения о языке (региональных параметрах), обнаруженном для текста. Когда вы завершите работу, оба эти контейнера будут доступны по внешнему IP-адресу.
Контейнер интерфейса для распознавания языка
Этот веб-сайт выполняет те же функции, что и клиентское приложение, то есть направляет запросы к конечной точки распознавания языка. Когда процедура будет завершена, вы сможете определить язык для строки символов, обращаясь к контейнеру веб-сайта через браузер по адресу http://<external-IP>/<text-to-analyze>
. Пример URL-адреса: http://132.12.23.255/helloworld!
. В браузере отображается результат English
.
Контейнер распознавания языка
В нашем примере контейнер распознавания языка доступен для любых внешних запросов. Контейнер не был изменен каким-либо образом, поэтому доступен стандартный API обнаружения языков для служб искусственного интеллекта Azure.
Для этого используется запрос POST для распознавания языка. Как и во всех контейнерах ИИ Azure, вы можете узнать больше о контейнере из размещенных сведений Swagger. http://<external-IP>:5000/swagger/index.html
Порт 5000 — это порт по умолчанию, используемый с контейнерами ИИ Azure.
Создание службы Реестра контейнеров Azure
Чтобы развернуть контейнер в Службе Azure Kubernetes, должны быть доступны образы контейнеров. Создайте собственную службу Реестра контейнеров Azure для размещения образов.
Вход в Azure CLI
az login
Создайте группу ресурсов с именем
cogserv-container-rg
, в которой будут размещены все созданные в этой процедуре ресурсы.az group create --name cogserv-container-rg --location westus
Создайте Реестр контейнеров Azure, указав для него имя с постфиксом
registry
, напримерpattyregistry
. Не используйте в имени символы дефиса или подчеркивания.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" }
Войдите в реестр контейнеров Перед отправкой образов в реестр необходимо выполнить вход.
az acr login --name pattyregistry
Получение образа Docker для веб-сайта
Пример кода, используемый в этой процедуре, находится в репозитории примеров контейнеров ИИ Azure. Клонируйте этот репозиторий, чтобы получить локальную копию примера.
git clone https://github.com/Azure-Samples/cognitive-services-containers-samples
Разместив репозиторий на локальном компьютере, найдите веб-сайт в каталоге \dotnet\Language\FrontendService. Этот веб-сайт выступает в качестве клиентского приложения, то есть вызывает API распознавания языка, размещенный в контейнере распознавания языка.
Создайте образ Docker для этого веб-сайта. Убедитесь, что в консоли открыт каталог \FrontendService, в котором находится Dockerfile, и выполните следующую команду:
docker build -t language-frontend -t pattiyregistry.azurecr.io/language-frontend:v1 .
Чтобы отслеживать версию реестра контейнеров, добавьте тег в формате версии, например
v1
.Отправьте образ в реестр контейнеров. Это может занять несколько минут.
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 для распознавания языка
Вытяните последнюю версию образа Docker на локальный компьютер. Это может занять несколько минут. Если существует более новая версия этого контейнера, замените значение
1.1.006770001-amd64-preview
номером новой версии.docker pull mcr.microsoft.com/azure-cognitive-services/language:1.1.006770001-amd64-preview
Присвойте образу тег реестра контейнеров. Проверьте номер последней версии и подставьте его вместо
1.1.006770001-amd64-preview
, если он уже изменился.docker tag mcr.microsoft.com/azure-cognitive-services/language pattiyregistry.azurecr.io/language:1.1.006770001-amd64-preview
Отправьте образ в реестр контейнеров. Это может занять несколько минут.
docker push pattyregistry.azurecr.io/language:1.1.006770001-amd64-preview
Получение учетных данных Реестра контейнеров
Следующие шаги позволяют получить сведения, необходимые для подключения реестр контейнеров к Службе Azure Kubernetes, которую вы создадите далее в этой процедуре.
Создание субъекта-службы.
az ad sp create-for-rbac
Сохраните из результата значение
appId
, которое вы присвоите параметру<appId>
(уполномоченный объект) на шаге 3. Сохраните значениеpassword
, которое вы присвоите параметру<client-secret>
(секрет клиента) в следующем разделе.{ "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" }
Получите идентификатор реестра контейнеров.
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 в этом разделе.
Чтобы правильно предоставить кластеру AKS права доступа для использования образов, хранящихся в реестре контейнеров, создайте назначение роли. Замените
<appId>
и<acrId>
значениями, полученными на двух предыдущих шагах.az role assignment create --assignee <appId> --scope <acrId> --role Reader
Создание Службы Azure Kubernetes
Создание кластера Kubernetes. Все значения параметров, кроме имени взяты из предыдущих разделов. Выберите имя, которое описывает понять, кто и зачем его создал, например
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" }
Создается служба, которая пока не содержит контейнер веб-сайта или контейнер распознавания языка.
Получите учетные данные кластера Kubernetes.
az aks get-credentials --resource-group cogserv-container-rg --name patty-kube
Загрузка определения оркестрации в службу Kubernetes
В этом разделе используется интерфейс командной строки kubectl для взаимодействия со Службой Azure Kubernetes.
Перед загрузкой определения оркестрации убедитесь, что 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
Скопируйте следующий файл и присвойте ему имя
language.yml
. Этот файл имеет разделservice
и разделdeployment
для контейнеров соответствующих типов: контейнер веб-сайтаlanguage-frontend
и контейнер распознаванияlanguage
.# 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
Измените строки развертывания интерфейса распознавания языка в файле
language.yml
, используя данные из следующей таблицы, чтобы добавить имена образов реестров контейнеров, секрет клиента и параметры Языковой службы.Параметры развертывания интерфейса распознавания языка Характер использования Строка 32
Свойствоimage
Расположение образа интерфейса в Реестре контейнеров <container-registry-name>.azurecr.io/language-frontend:v1
Строка 44
Свойствоname
Секрет реестра контейнеров для образа. Называется <client-secret>
в предыдущем разделе.Измените строки развертывания распознавания языка в файле
language.yml
, используя данные из следующей таблицы, чтобы добавить имена образов реестров контейнеров, секрет клиента и параметры Языковой службы.Параметры развертывания распознавания языка Характер использования Строка 78
Свойствоimage
Расположение образа распознавания языка в Реестре контейнеров <container-registry-name>.azurecr.io/language:1.1.006770001-amd64-preview
Строка 95
Свойствоname
Секрет реестра контейнеров для образа. Называется <client-secret>
в предыдущем разделе.Строка 91
СвойствоapiKey
Ключ ресурса языковой службы Строка 92
Свойствоbilling
Конечная точка выставления счетов для ресурса Языковой службы. https://westus.api.cognitive.microsoft.com/text/analytics/v2.1
Параметр apiKey и конечная точка выставления счетов задаются в определении оркестрации Kubernetes, поэтому контейнеру веб-сайта не нужно знать их значения или передавать их в запросе. Контейнер веб-сайта обращается к контейнеру распознавания языка по имени оркестратора
language
.Загрузите файл определения оркестрации для этого примера из той папки, в которой вы создали и сохранили
language.yml
.kubectl apply -f language.yml
Ответ:
service "language-frontend" created deployment.apps "language-frontend" created service "language" created deployment.apps "language" created
Получение внешних IP-адресов контейнеров
Убедитесь, что для обоих контейнеров запущены службы language-frontend
и language
, а затем получите их внешний 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
имеет значение pending, выполните ту же команду еще один или несколько раз, пока не получите значение IP-адреса, прежде чем переходить к следующему шагу.
Тестирование контейнера распознавания языка
Откройте браузер и перейдите по внешнему IP-адресу контейнера language
, который вы получили в предыдущем разделе: http://<external-ip>:5000/swagger/index.html
. Для проверки конечной точки распознавания языка вы можете использовать функцию API Try it
.
Тестирование контейнера с клиентским приложением
В адресную строку браузера введите внешний IP-адрес контейнера language-frontend
, используя следующий формат: http://<external-ip>/helloworld
. Для текста helloworld
распознается английский язык: English
.
Очистка ресурсов
Когда вы закончите работу с кластером, удалите группу ресурсов Azure.
az group delete --name cogserv-container-rg