AKSとCustom Vision APIをコンテナアプリとして動かす

概要

2020年11月28日に「オープンソースカンファレンス2020 Online/Fukuoka」にエンジニアフレンドリーシティ福岡xAI Meetup 枠でお話させていただきました内容のKubernetes回りのお話です。

発表時のスライドは以下です。

www.slideshare.net

発表時には触れていなかったKubernetes (AKS) へデプロイする時に使うYAMLファイルについてです。
そしてコンテナレジストリもACR (Azure Container Registry) を使っています。
AKSで後から使うようにするには以下コマンドで接続します。

az aks update -n {AKS_Name} -g {AKS_RG_Name} --attach-acr {ACR_Name}

Webアプリ側

発表時に使用していたのはWeb画面からAzure BLOBへアップロードしてBLOBのファイルURLをCustomVisionへ渡して、画像を解析する。
解析した結果を画面に返すといったものでした。
.NET Coreで開発されており(共同登壇した石橋さん作です)、Dockerコンテナー化してAKSへデプロイします。
DockerfileはVisual Studioで自動生成できるのでそれほど難しくはありません。
ソリューションエクスプローラーから右クリックして[追加]→[Dockerサポート]とするだけで自動的にDockerfileを作ってくれます。
便利!

Dockerfileは以下のように作られます。

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["WebCustomVision/WebCustomVision.csproj", "WebCustomVision/"]
RUN dotnet restore "WebCustomVision/WebCustomVision.csproj"
COPY . .
WORKDIR "/src/WebCustomVision"
RUN dotnet build "WebCustomVision.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "WebCustomVision.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebCustomVision.dll"]

次にKubernetesへデプロイするためのYAMLを作ります。
外部へ公開してアクセスする必要があるので、Serviceのtypeは「LoadBalancer」で作成します。
AKSだとLoadBalancerにしておくことで外部用IPアドレスをリソース[Azure Load Balancer]にパブリックIPアドレス付きで作成してくれます。
こちらも便利!
ただ、プロダクション環境で使用する場合はIngress コントローラーを使うようにしましょう。(nginx Ingress Controllerを使うなど)

使うYAMLは以下となります。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webcustomvision
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webcustomvision
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  minReadySeconds: 5 
  template:
    metadata:
      labels:
        app: webcustomvision
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: webcustomvision
        image: {ACR_Name}.azurecr.io/webcustomvision:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: webcustomvision
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: webcustomvision

Custom Vision (Docker化) 側

次はCustom VisionのDockerコンテナ側ですね。
ダウンロードしてくるとDockerfileが含まれるので、Dockerイメージを作成してACRへアップロードします。

docker build -t customvision ./
docker tag customvision:latest {ACR_Name}.azurecr.io/customvision:latest
az acr login --name {ACR_Name}
docker push {ACR_Name}.azurecr.io/customvision:latest

ACRへpush出来たらAKSへデプロイします。
デプロイ用のYAMLは以下となります。
Serviceのtypeは内部のみで使うのでClusterIPにしています。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: customvision
spec:
  replicas: 1
  selector:
    matchLabels:
      app: customvision
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  minReadySeconds: 5 
  template:
    metadata:
      labels:
        app: customvision
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: customvision
        image: {ACR_Name}.azurecr.io/customvision:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: customvision
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: customvision

Webアプリ内からの接続は上記のappのnameを指定することで接続できます。
ぜひお試しあれ。