本記事はFIXERが提供する「cloud.config Tech Blog」に掲載された「自作のWindowsアプリをAKSに載せるキホン技 #Azure リレー」を再編集したものです。
こんにちは、名古屋事業所勤務の松枝です。
Azure Kubernetes Service(AKS)はWindowsコンテナの使用できる構成を作成することができます(記事公開時点ではパブリックプレビュー)。
Windowsコンテナが使えるAKSを用意して、アプリを動かしてみましょう。
アプリの作成からインフラの作成まで一通り必要な手順を書いてみましたので、この記事をベースにWindowsコンテナの世界に入門していただけたらと思います。
また、アプリ開発、コンテナ作成、AKS作成を一通り記載しているので、例えばアプリ開発は知識があるけどインフラはちょっと… という場合に部分的に参照していただけると嬉しいです。
Azure Cloud Shellとはなんぞや?などの細かい説明は省いていますので、適宜調べながら読み進めていただけたらと思います。
概要
・(Windows環境でしか動作しない)アプリケーションを作成します
・アプリケーションを載せたコンテナイメージを作成します
・コンテナイメージをコンテナレジストリ(ACR)に格納します
・Windowsコンテナが動作するAKSを作成します
・マニフェストファイルを使用して、AKS上でコンテナを動かします
ウェブアプリの作成
<作業環境の想定:手元のWindows PC>
ウェブ上に公開されているサンプルアプリを使っても良いんですが、現実は自社で作成したアプリなどを使用すると思うので、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を開き、適当な加工を加えて実行してみてください。例えば下記のような感じでザックリいきましょう。
F5キーでアプリの正常動作を確認したら、アプリケーションを発行しましょう。
ウェブアプリケーションのプロジェクトを右クリックし、「発行」を選ぶと、「公開先の選択」の画面が出ます。
ここで公開先に「フォルダ―」を選び、表示される通り「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内に貼り付けしてください。
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>
ウェブアプリを使用するためのマニフェストファイルを用意します。
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になったら、ウェブアプリが見れることを確認しましょう。
下記のコマンドで、Podに外からアクセスするためのServiceの情報が取得できます。
kubectl get services
EXTERNAL-IPに記載されたグローバルIPに、手元のPCのブラウザーからアクセスしてみてください。
上手くいきましたか?
まとめ
サクッとやれることを示したかったんですが、結構長大になってしまいました。
覚えることは多いですが、ひとつひとつの技術的な難易度はお試しで使う分にはあまり高くありませんので、まずはこの記事を参考に動くものを見ていただいて、それから順に深堀して勉強していただけたらと思います。
Windowsコンテナの使えるAKSを活用していただける方が増えると嬉しいです。
FIXER Inc. 松枝 宏樹
名古屋事業所所属。
得意分野はC#、ASP.NET、terraformなど。
最近はdocker、K8s関連を勉強中。