Azure Kubernetes Service(以降、AKS)は Windows コンテナの使用できる構成を作成することができます。

(記事公開時点ではパブリックプレビュー)

Windows コンテナが使える AKS を用意して、アプリを動かしてみましょう。

アプリの作成からインフラの作成まで一通り必要な手順を書いてみましたので、この記事をベースに Windows コンテナの世界に入門していただけたらと思います。

また、アプリ開発、コンテナ作成、AKS 作成を一通り記載しているので、例えばアプリ開発は知識があるけどインフラはちょっと・・・という場合に部分的に参照していただけると嬉しいです。

Azure Cloud Shell とはなんぞや?などの細かい説明は省いていますので、適宜調べながら読み進めていただけたらと思います。

概要

  • (Windows 環境でしか動作しない)アプリケーションを作成します
  • アプリケーションを載せたコンテナイメージを作成します
  • コンテナイメージをコンテナレジストリ(ACR)に格納します
  • Windows コンテナが動作する AKS を作成します
  • マニフェストファイルを使用して、AKS 上でコンテナを動かします

Web アプリの作成

【作業環境の想定:手元の Windows PC】

Web 上に公開されているサンプルアプリを使っても良いんですが、現実は自社で作成したアプリなどを使用すると思うので、Web アプリの作成からサラッと見てみましょう。

Windows コンテナが必要なケースは、Windows でしか動作しないアプリ、例えば.NET Framework のアプリを使用している場合だと思われます。.NET Framework の ASP.NET MVC アプリを作っておきましょう。

下記サイトから Visual Studio のインストーラをダウンロードします。 https://visualstudio.microsoft.com/ja/downloads/

インストーラを起動し、「ASP.NET と Web 開発」を選択してインストールします。

インストールが成功したら、新規プロジェクトを起動して、C#の ASP.NET MVC アプリを作成しましょう。

ちょっと古めのアプリを載せる想定だと思いますので、.NET Framework は「4.5.2」辺りが良いでしょうか。プロジェクト名は適当で良いので、「MVC」のアプリを作成してください。

アプリが作成されたら、Visual Studio のソリューションエクスプローラーから、Views/Home/Index.cshtml を開き、適当な加工を加えて実行してみてください。例えば下記のような感じでザックリいきましょう。

@{
ViewBag.Title = "コンテナアプリのデモ";
}

<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">コンテナでWebアプリを動かしてみよう</p>
</div>

F5 キーでアプリの正常動作を確認したら、アプリケーションを発行しましょう。

Web アプリケーションのプロジェクトを右クリックし、「発行」を選ぶと、「公開先の選択」の画面が出ます。

ここで公開先に「フォルダ―」を選び、表示される通り「bin\Release\Publish」に公開する状態で「プロファイルの作成」を押してください。

プロファイルの作成が終わったら画面上に発行用のビューが出ているはずなので、「発行」ボタンを押してください。

これでアプリケーションの準備が完了しました!

サービスプリンシパルの作成

【作業環境の想定:Azure Cloud Shell】

VM での作業用に、権限を限定したサービスプリンシパルを作成して進めます。

下記のコマンドを実行し、AKS を作成する対象のサブスクリプション ID での Contributor 権限を持つサービスプリンシパルを作成します。

az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/【サブスクリプション ID】"

コマンドを実行すると、自動で生成された ID やパスワードが表示されますので、表示された値を安全な方法で保管してください。

作業用 VM の作成

【作業環境の想定:Azure ポータル、作業用 VM】

コンテナイメージの作成をするために VM を用意しましょう。

ちなみに記事執筆時点では、AKS 上で動作する Windows コンテナは Windows Server 2019 系列のものだけです。

記事執筆時点では AKS はプロセス分離モードしか使用できないため、Windows Server 2019 Datacenter 辺りの VM を用意することが必要です。

Azure ポータルから適当な Windows Server 2019 の VM を作成します。あまり性能は要らないはずですが、D2s v3 くらいのサイズにしておくと後悔が無いかと思います。設定はデフォルトで良いと思いますが、診断ログや自動停止などはお好みで。

VM が作成できたら、 VM の Windows Update を実施してください。

Windows Update の適用が完了したら、Docker EE の導入のため、PowerShell で下記のコマンドを実行します(VM が再起動します)。

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name Docker -ProviderName DockerMsftProvider -Force
Restart-Computer -Force

また、Azure が操作できるよう、az cli をインストールしましょう。下記のコマンドを実行します。

Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'

Dockerfile の作成

【作業環境の想定:作業用 VM】

作成した VM に下記の Dockerfile を用意します。

# escape=`

FROM mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2019

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

RUN Add-WindowsFeature Web-Server; `
    Add-WindowsFeature NET-Framework-45-ASPNET; `
    Add-WindowsFeature Web-Asp-Net45; `
    Remove-Item -Recurse C:\inetpub\wwwroot\*; `
    Invoke-WebRequest -Uri https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.6/ServiceMonitor.exe -OutFile C:\ServiceMonitor.exe

# Install Roslyn compilers and ngen binaries

RUN Invoke-WebRequest https://api.nuget.org/packages/microsoft.net.compilers.2.9.0.nupkg -OutFile c:\microsoft.net.compilers.2.9.0.zip; `
    Expand-Archive -Path c:\microsoft.net.compilers.2.9.0.zip -DestinationPath c:\RoslynCompilers; `
    Remove-Item c:\microsoft.net.compilers.2.9.0.zip -Force; `
    &C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\csc.exe /ExeConfig:c:\RoslynCompilers\tools\csc.exe | `
    &C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\vbc.exe /ExeConfig:c:\RoslynCompilers\tools\vbc.exe | `
    &C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\VBCSCompiler.exe /ExeConfig:c:\RoslynCompilers\tools\VBCSCompiler.exe | `
    &C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\csc.exe /ExeConfig:c:\RoslynCompilers\tools\csc.exe | `
    &C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\vbc.exe /ExeConfig:c:\RoslynCompilers\tools\vbc.exe | `
    &C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\VBCSCompiler.exe /ExeConfig:c:\RoslynCompilers\tools\VBCSCompiler.exe

ENV ROSLYN_COMPILER_LOCATION c:\\RoslynCompilers\\tools

WORKDIR C:\inetpub\wwwroot
COPY ${source:-Publish} .

EXPOSE 80

ENTRYPOINT ["C:\\ServiceMonitor.exe", "w3svc"]

Windows コンテナで IIS を使用するシンプルな Dockerfile です。

.NET Framework を動かすため、Windows ServerCore のベースイメージを使用します。

IIS を使用するため、必要な機能を追加し、ENTRYPOINT で使用する ServiceMonitor を導入しています。

C:\Work\Dockerfile に保存しましょう。

コンテナイメージの作成

【作業環境の想定:作業用 VM】

ビルドしたアプリを Dockerfile と同じ場所(C:\Work)にコピーしましょう。

Visual Studio のソリューションエクスプローラーでプロジェクトを右クリックし、「エクスプローラーでフォルダを開く」を選ぶと、プロジェクトの場所が表示されます。bin/Release/Publish フォルダをコピーし、VM の C:\Work 内に貼り付けしてください。

PowerShell 等で下記のコマンドを実行したら、testcontainer というイメージ名のコンテナイメージが作成されます。

cd C:\Work
docker build -t testcontainer .

結構時間がかかりますが、処理が終わったら完了です。

正常終了なら、メッセージの最後に下記のような内容が出るはずです。

Successfully built xxxxxxxx
Successfully tagged testcontainer:latest

軽くコンテナの動作を確認してみましょう。 下記のコマンドを実行し、コンテナイメージからコンテナを作成します。

docker run -itd testcontainer

コマンドから復帰したら、下記のコマンドで実行中のコンテナの IP アドレスを取得しましょう。

docker exec -it (docker ps -q -f "ancestor=testcontainer") powershell ipconfig

このコマンドで、docker ps で実行中のコンテナを検索し、その ID を取得し、その ID のコンテナにログインして ipconfig コマンドを実行しています。

得られた IPv4 Address の値に VM のブラウザからアクセスしてみましょう。

Visual Studio からデバッグ実行した時と同じ画面が見れましたか?

ACR の作成

【作業環境の想定:Azure ポータル】

Azure ポータルから ACR を作成します。

管理者ユーザーは無効、SKU は Basic で構いません。

ACR へのイメージのプッシュ

【作業環境の想定:作業用 VM】

コンテナイメージを作成した VM に戻り、ACR にコンテナイメージを Push します。

ACR にアクセスする場合、az コマンドに対して認証情報を設定する必要があります。

下記の PowerShell を実行してください。

az login --service-principal --username 【サービスプリンシパルの appId の値】 --password 【サービスプリンシパルの password の値】 --tenant 【サービスプリンシパルの tenant の値】
az acr login --name 【作成した ACR のレジストリ名】

成功したら、下記のコマンドを実行し、ACR へイメージをプッシュします。

docker tag testcontainer:latest 【作成した ACR のレジストリ名】.azurecr.io/testcontainer:latest
docker push 【作成した ACR のレジストリ名】.azurecr.io/testcontainer

Azure ポータルで ACR を開くと、リポジトリのビューにプッシュしたイメージが表示されます。

と言っても文字情報なので、今は「ふ~ん・・」としか言えないですね。

Windows コンテナが使用可能な AKS の作成

【作業環境の想定:Azure Cloud Shell】

下記の記事に従い、Windows コンテナが使用可能な AKS を作成しましょう。

https://docs.microsoft.com/ja-jp/azure/aks/windows-container-cli

手順を転記するとあまりに冗長なので省略します。 下記の記事まで、ほぼそのまま Azure Cloud Shell で実行してください。

https://docs.microsoft.com/ja-jp/azure/aks/windows-container-cli#connect-to-the-cluster

kubectl get nodes を実行してノードの一覧が表示されること、 kubectl get pods を実行して Pod が何もデプロイされていないことを確認します。

続いて、AKS が ACR からコンテナイメージをダウンロードできるよう、ACR を AKS にアタッチします。

az aks update -n myAKSCluster -g myResourceGroup --attach-acr 【ACR 名】

マニフェストファイルの作成

【作業環境の想定:Azure Cloud Shell】

Web アプリを使用するためのマニフェストファイルを用意します。 Azure Cloud Shell 上でそのまま vi コマンド等を使って作成してください。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: application
  labels:
    app: application
spec:
  replicas: 1
  template:
    metadata:
      name: application
      labels:
        app: application
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": windows
      containers:
        - name: application
          image: 【作成した ACR のレジストリ名】.azurecr.io/testcontainer:latest
          resources:
            limits:
              cpu: 400m
              memory: 800M
            requests:
              cpu: 400m
              memory: 800M
          ports:
            - containerPort: 80
  selector:
    matchLabels:
      app: application
---
apiVersion: v1
kind: Service
metadata:
  name: application
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
  selector:
    app: application

マニフェストファイルの適用と確認

【作業環境の想定:Azure Cloud Shell】

マニフェストファイルの適用をするため、Azure Cloud Shell から下記のコマンドを実行します。

kubectl apply -f 【作成したマニフェストファイル】

成功すると Pod が作成されますので、 kubectl get pods で作成した Pod の STATUS を確認しましょう。

10 分くらいして Pod の STATUS が ContainerCreating から Running になったら、Web アプリが見れることを確認しましょう。

下記のコマンドで、Pod に外からアクセスするための Service の情報が取得できます。

kubectl get services

EXTERNAL-IP に記載されたグローバル IP に、手元の PC のブラウザからアクセスしてみてください。

上手くいきましたか?

まとめ

サクッとやれることを示したかったんですが、結構長大になってしまいました。

覚えることは多いですが、一つひとつの技術的な難易度はお試しで使う分にはあまり高くありませんので、まずはこの記事を参考に動くものを見ていただいて、それから順に深堀して勉強していただけたらと思います。

Windows コンテナの使える AKS を活用していただける方が増えると嬉しいです。