はじめに
Azure SQL Database に接続する WCF サービスを、Windows コンテナのプロセス分離モードで動かすところまで漕ぎつけた。
一連の実験もいよいよ今回で最後。Azure SQL Database に接続する WCF サービスを、Azure Kubernetes Service(以下 AKS) で動かすことに挑戦した。
WCFサービス作成
AKS で動かす WCF サービスを作成。前回の WCF サービスとほぼ同じ。名前空間とポートが違うだけ。接続文字列を環境変数で受け取るのがポイント。
using System; using System.Data.SqlClient; using System.ServiceModel; using System.Threading; namespace WcfAks { class Program { static void Main(string[] args) { if (string.IsNullOrEmpty(TestService.ConnectionString)) { Console.WriteLine("環境変数 CONNECTION_STRING を設定してください。"); return; } var host = new ServiceHost(typeof(TestService)); try { var binding = new NetTcpBinding(); binding.Security.Mode = SecurityMode.None; host.AddServiceEndpoint( typeof(ITestService), binding, "net.tcp://localhost:443/TestService"); host.Open(); foreach (var endpoint in host.Description.Endpoints) { Console.WriteLine(endpoint.ListenUri); } Thread.Sleep(-1); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); host.Close(); } } } [ServiceContract] public interface ITestService { [OperationContract] string Test(); } [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class TestService : ITestService { public static string ConnectionString { get; } static TestService() { ConnectionString = Environment.GetEnvironmentVariable("CONNECTION_STRING"); } public string Test() { try { using (var connection = new SqlConnection(ConnectionString)) { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandText = @"SELECT @@VERSION"; return (string)command.ExecuteScalar(); } } } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); throw; } } } }
WCFクライアント作成
AKS でホストした WCF サービスにアクセスするクライアントを作成。こちらも前回とほとんど同じ。名前空間とポートが違うだけ。 IP アドレスが現時点では不明なので、外から渡せるようにしておく。
using System; using System.ServiceModel; using System.ServiceModel.Channels; using WcfAks; namespace ConsoleClient { class Program { static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("ホスト名または IP アドレスを指定してください。"); return; } var host = args[0]; var factory = new ChannelFactory<ITestService>( new NetTcpBinding(SecurityMode.None), $"net.tcp://{host}:443/TestService"); var channel = factory.CreateChannel(); var result = channel.Test(); Console.WriteLine(result); Console.WriteLine("Enter で終了"); Console.ReadLine(); ((IChannel)channel).Close(); } } } namespace WcfAks { [ServiceContract] public interface ITestService { [OperationContract] string Test(); } }
Dockerfile 作成
Windows コンテナをビルドするために Dockerfile を作成。
FROM mcr.microsoft.com/dotnet/framework/wcf:4.8-windowsservercore-ltsc2019 WORKDIR /app EXPOSE 443 COPY ./WcfAks/bin/Release/ . ENTRYPOINT ["WcfAks.exe"]
AKS 上でホストとなる Windows ノードのバージョンが 1809 のようだったので、ベースイメージを 1809 のものに変更している。 WCF サービスの待ち受けポートが 443 に変わったので、EXPOSE で指定するポートは 443。
イメージをビルド
docker build -t tnakamura/wcfaks:1.0 .
リソースグループの作成
Azure 上に実験用のリソースグループを作成する。今回は Azure ポータルではなく、Azure CLI を使って作業してみた。
az group create --name wcfaks --location japaneast
Azure Container Registry の作成
AKS で動かすコンテナのイメージは Azure Container Registry(以下 ACR) から pull したいので、実験用の ACR を作成。
az acr create -g wcfaks -n tnakamuraacr --sku basic
作成した ACR にログイン
az acr login -n tnakamuraacr
tnakamura/wcfaks にタグを設定
予め作成しておいたイメージを ACR に push するために、タグを設定する必要がある。
docker tag tnakamura/wcfaks:v1 tnakamuraacr.azurecr.io/wcfaks:v1
ACR にイメージをプッシュ
docker push tnakamuraacr.azurecr.io/wcfaks:v1
AKS クラスタの作成
Windows コンテナを動かすための AKS クラスタを作成。
az aks create --resource-group wcfaks \ --name wcfAKSCluster \ --node-count 1 \ --generate-ssh-keys \ --attach-acr tnakamuraacr \ --enable-addons monitoring \ --windows-admin-password <password> \ --windows-admin-username azureuser \ --vm-set-type VirtualMachineScaleSets \ --network-plugin azure
--attach-acr
で先ほど作成した ACR をアタッチすることで、AKS が ACR からコンテナイメージを pull できるようになる。
Windows Serverノードプールを追加
Windows コンテナを動かせるのは Windows ノードだけなので、Windows ノードを追加する必要がある。
az aks nodepool add --resource-group wcfaks \ --cluster-name wcfAKSCluster \ --os-type Windows \ --name npwin \ --node-count 1
最初から Windows ノードを作成できるようになったらいいんだけどね…。
kubectlをインストール
Kubernetes の操作は kubectl を使う。
az aks install-cli
作成したAKSクラスタへの接続
az aks get-credentials --resource-group wcfaks --name wcfAKSCluster
Kubernetesのマニフェストファイルを作成
上記のドキュメントのマニフェストファイルをベースに、イメージ名や環境変数、ポートを変更。
apiVersion: apps/v1 kind: Deployment metadata: name: sample labels: app: sample spec: replicas: 1 template: metadata: name: sample labels: app: sample spec: nodeSelector: "beta.kubernetes.io/os": windows containers: - name: sample image: tnakamuraacr.azurecr.io/wcfaks:v1 env: - name: CONNECTION_STRING value: "Azure SQL Database の接続文字列" resources: limits: cpu: 1 memory: 800M requests: cpu: .1 memory: 300M ports: - containerPort: 443 selector: matchLabels: app: sample --- apiVersion: v1 kind: Service metadata: name: sample spec: type: LoadBalancer ports: - protocol: TCP port: 443 selector: app: sample
アプリケーションをデプロイ
kubectl apply -f wcfaks.yaml
イメージサイズが大きいせいで Pod が動くまで時間がかかるため、kubectl get pods --watch
で確認しながら気長に待つ。
WCFクライアントから接続
まずは kubectl get services
で、ロードバランサーの外部 IP アドレスを確認。
判明した IP アドレスを引数に、クライアントを起動。
SQL Server のバージョンが表示された。ということは、AKS で動いている WCF サービスが Azure SQL Database に無事接続できたことになる。
AKS クラスタ削除
用済みなので、リソースグループごと削除。
az group delete --name wcfaks --yes --no-wait
おわりに
Azure SQL Database に接続する WCF サービスの Windows コンテナを Azure Kubernetes Service で動かすことに成功した。Windows コンテナ関連の実験で設定していたゴールに、ついに到達。達成感ハンパない。
Kubernetes は入門したばかりなので、Kubernetes を習得することを次の目標にしよう