ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

Azure Custom Vision を Docker コンテナで使ってみた

先週の土曜日、Japan Azure User Group 9周年イベントで LT してきました。

jazug.connpass.com

タイトルからお察しの通り、懇親会でのネタ的な内容だったので、このスライドに大した話は書いてありません。

speakerdeck.com

せっかくなので、デモを構築した手順をまとめておきたいと思います。

Azure Custom Vision とは

Azure Custom Vision は、画像に任意のラベルを適用した判別モデルを構築できる Azure の AI サービスです。
似たようなサービスに Computer Vision もありますが、プリセットのラベルのみなので、自由にカスタマイズできるところが大きな違いです。

画像判別モデルを構築する

画像判別モデルは、Custom Vision Web サイトを利用して、画像のアップロード→トレーニング→評価の3ステップで構築できます。
このあたりの情報は多いので、公式ドキュメントなどを参照してください。
docs.microsoft.com

今回は、Dockerfile にエクスポートしたかったので、コンパクト ドメインを選択しました。プロジェクトを作成する際に、General (Compact) を選択します。
f:id:TonyTonyKun:20190910002839p:plain

プロジェクト作成後、五等分の花嫁の原作から集めてきた画像に、五つ子の名前をタグづけしてアップロードしました。

Dockerfileにエクスポートする

トレーニングした画像判別モデルをアプリケーションに組み込むには、いくつかの方法があります。
最もお手軽なのは、Custom Vision Web サイトで提供されるマネージドな API を呼び出すことですが、アプリケーションの形式に合わせて、画像判別モデルをエクスポートできます。

f:id:TonyTonyKun:20190910002919p:plain

今回は、Dockerfile を選択しました。コンテナ環境ならどこでもデプロイできます。Azure であれば、Web Apps とか Container Instances とか Kubernetes Services など、用途に合わせてサービスを選択することができます。
注意点として、コンテナ環境で動作するのですが、内部的に Azure 側への通信を行なっているため、完全なオフライン環境では動きません。
完全なオフライン環境で動かしたいときは、CoreML のような iOS 向けの形式を選択しましょう。

画像判別モデルを Docker コンテナでテストする

ダウンロードした ZIP を展開すると、Python で書かれたアプリケーションと Dockerfile が入った構成になっています。

f:id:TonyTonyKun:20190910002945p:plain

Dockerfile をビルドして、ローカルで実行します。

$ docker build -t thara0402/gotobun:2.0.0 .
$ docker run -it --rm -p 8080:80 thara0402/gotobun:2.0.0

あとは API を呼び出せば良いのですが、最近気に入っている Visual Studio Code の拡張にある REST Client を使いました。

f:id:TonyTonyKun:20190910003001p:plain

上記では、Azure Blob Storage にアップロードした画像 URL を渡していますが、/image で API を叩くと、画像データをそのまま POST することもできます。
原作から集めてきた未来の花嫁の画像を渡してテストしました。

まとめ

Azure Custom Vision は、画像に好きなラベルをつけて、自分だけの画像判別モデルを作ることができるサービスです。画像判別モデルは、アプリに合わせたフォーマットでエクスポートして組み込むこともできます。
少ない学習データ(最低5枚)でも大丈夫ですし、画像アップロード、トレーニング、評価の3ステップなので、何か自分の楽しめるネタで試してみるといいと思います。

気になる?未来の花嫁の予想結果ですが、長女か三女の可能性が高いようでした。ちなみに、五つ子の過去が明らかになる 11 巻は 9/17 に発売です。

五等分の花嫁(11) (講談社コミックス)

五等分の花嫁(11) (講談社コミックス)

Microsoft MVP for Microsoft Azure を再受賞しました

2019年7月1日付けで、Microsoft Most Valuable Professional (MVP) アワードを再受賞しました。受賞カテゴリは、Microsoft Azure です。

f:id:TonyTonyKun:20190725013523j:plain

昨年の主な活動内容

昨年は、Azure Kubernetes Service(AKS)の正式リリースに伴い、コミュニティでの登壇を主軸に技術情報を多く発信しました。今でこそ、日本語の情報も増えてきましたが、当時はまだ少なかったと記憶しています。
AKS を使いこなすには、コンテナーオーケストレーションの Kubernetes を理解する必要があるため、そもそもなぜコンテナーを使うのか、Kubernetes とは何かというところからの入門者向けの情報を提供しました。
このような基礎を踏まえた上で、

  • Azure がマネージドなサービスとして Kubernetes を提供するメリット
  • Azure で提供されている他のサービスにはない特徴として、サービスメッシュの Istio などの OSS と組み合わせて使えるメリット

といった AKS の魅力を伝え、多くの人に使ってもらえるサービスとなるように啓蒙活動を行ってきました。ACS の時代から記事を書いていますが、今でも活用できる内容が多いと思います。
gooner.hateblo.jp

あと、個人的に印象に残っているのは、Microsoft Tech Summit 2018 で「.NET 開発者のためのマイクロサービス入門」のセッションに登壇したことです。.NETユーザーの現状の課題、Cloud Nativeなプラットフォームのトレンドを踏まえた上で、AKSとASP.NET Coreで実装するマイクロサービスの構築から配置までのアーキテクチャ、および移行に向けて取り組むべきことをデモを交えて解説しました。
gooner.hateblo.jp

今年の活動目標

Azure Monitor for Container がすごく良くなってきているので、そのあたりも含めて AKS の実践的な情報を発信したいです。あとは、実践で活用するケースが増えてきた Durable Functions を含めた Azure Functions V2 ですかね。
もう1つは、Azure アーキテクチャセンターのドキュメント啓蒙やフィードバックにチャレンジしたいと考えています。とても良い内容のトピックが充実しているので、多くの人に知ってもらいたいです。
docs.microsoft.com

それと来年も MVP Global Summit(グロサミ)に参加できるのは、とても楽しみです。
gooner.hateblo.jp

そんな感じで今年も無事に MVP を更新できたので、引き続きよろしくお願いします。

Managed Service Identity を使って Azure Key Vault から接続文字列を取得する

Azure Key Vault は、アプリケーションが利用するシークレットを安全に保管してくれるサービスです。シークレットには、DBの接続文字列、API のアクセスキー、証明書などの情報があります。
アプリケーションで Azure Key Vault から接続文字列を取得するには、Azure Active Directory のサービスプリンシパルが必要となり、ソースコードに決め打ちしない構成やサービスプリンシパルの有効期間の管理など、少し手間がかかります。
Managed Service Identity(MSI)を使うことで、このあたりの煩わしさを解消できるようになっていたので、まとめておきます。

azure.microsoft.com

Azure Key Vault を作成する

Azure Portal を開いて、Azure Key Vault を作成します。特に説明は必要ないと思います。

f:id:TonyTonyKun:20190410202248p:plain

続いて、シークレットを作成します。今回は、SQL の接続文字列を想定したシークレット(SqlConnection)を追加しました。

f:id:TonyTonyKun:20190410202408p:plain

Azure Key Vault 側の準備は、これで完了です。

ローカル開発環境で接続文字列を取得する

Managed Service Identity(MSI)を利用すると、認証資格情報をアプリケーションに含めずに、Azure の各サービスへ認証を行うことができます。
今回は、ASP.NET Core で作成した Web アプリケーションで試してみます。Visual Studio のテンプレートから作成したシンプルな MVC アプリケーションです。
MSI を使って Azure Key Vault に接続するための2つの NuGet ライブラリをインストールします。

Install-Package Microsoft.Azure.KeyVault -Version 3.0.3
Install-Package Microsoft.Azure.Services.AppAuthentication -Version 1.0.3

HomeController クラスで、MSI を使って Azure Key Vault から接続文字列を取得するコードを書きます。
vaultBaseUrl は、先ほど作成した Azure Key Vault のURL です。AzureServiceTokenProvider を使って KeyVaultClient をインスタンス化している部分がポイントです。

public class HomeController : Controller
{
    public async Task<IActionResult> About()
    {
        var vaultBaseUrl = "https://xxx.vault.azure.net/";
        var provider = new AzureServiceTokenProvider();
        using (var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback)))
        {
            var secret = await client.GetSecretAsync(vaultBaseUrl, "SqlConnection");
            ViewData["Message"] = secret.Value;
        }

        return View();
    }
}

ローカル開発環境で Visual Studio からデバッグ実行してみます。Azure Key Vault に作成したシークレット(SqlConnection)の値が取得できたことがわかります。

f:id:TonyTonyKun:20190410202424p:plain

ここで疑問に思うのが、ローカル開発環境からシークレットを取得できた理由です。
最近の Visual Studio では、Azure サービス認証に登録されたアカウントのトークンを使って AzureServiceTokenProvider が生成されるようになっているので、Visual Studio から Azure Web Apps にデプロイなどの機能を使っていれば、特に意識せずに Azure Key Vault に作成したシークレットを取得することができます。

f:id:TonyTonyKun:20190420121207p:plain

環境によってこの方法が利用できない場合には、環境変数「AzureServicesAuthConnectionString」を使いましょう。設定する値については、こちらを参照してください。

Azure Web Apps で接続文字列を取得する

先ほど作成した ASP.NET Core の Web アプリケーションを Azure Web Apps にデプロイしてみます。
Azure Web Apps の MSI を有効にしておきます。このタイミングで、サービスプリンシパルが追加されます。

f:id:TonyTonyKun:20190410203001p:plain

続いて、Azure Key Vault の Access policies で、Azure Web Apps のサービスプリンシパルを許可します。必要最低限のパーミッションとして、シークレットの Get だけを許可しました。忘れずに Save ボタンで保存ましょう。

f:id:TonyTonyKun:20190410202454p:plain

ASP.NET Core の Web アプリケーションを Azure Web Apps にデプロイし、結果を確認します。

f:id:TonyTonyKun:20190410202505p:plain

Azure Key Vault に作成したシークレット(SqlConnection)の値が取得できたことがわかります。

まとめ

アプリケーションを開発する際には、DBの接続文字列、API のアクセスキー、証明書などのシークレットは手間をかけずに安全に管理したいところです。MSI と Azure Key Vault を組み合わせて使うことで、このあたりの煩わしさを解消できます。パブリックなリポジトリでシークレットを公開してしまう事故を防ぐためにも、しっかりとアーキテクチャで考慮しておきたい事項です。