はじめに
Azure SQL Database に接続する WCF サービスを、Windows コンテナのプロセス分離モードで動かすところまで漕ぎつけた。
tnakamura.hatenablog.com
一連の実験もいよいよ今回で最後。Azure SQL Database に接続する WCF サービスを、Azure Kubernetes Service(以下 AKS) で動かすことに挑戦した。
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
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
az aks get-credentials --resource-group wcfaks --name wcfAKSCluster
docs.microsoft.com
上記のドキュメントのマニフェストファイルをベースに、イメージ名や環境変数、ポートを変更。
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 に無事接続できたことになる。
用済みなので、リソースグループごと削除。
az group delete --name wcfaks --yes --no-wait
おわりに
Azure SQL Database に接続する WCF サービスの Windows コンテナを Azure Kubernetes Service で動かすことに成功した。Windows コンテナ関連の実験で設定していたゴールに、ついに到達。達成感ハンパない。
Kubernetes は入門したばかりなので、Kubernetes を習得することを次の目標にしよう