ROMANCE DAWN for the new world

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

Azure App Service の Sidecar にカスタムコンテナーをデプロイしてみた

Azure App Service on Linux に Sidecar パターンでコンテナーをデプロイできる機能が追加されました。
現時点では Public Preview のため、下記の制約があります。

  • Docker Container のみ(Windows Container は未対応)
  • Sidecar を構成できるのは App Service の新規作成のみ(既存リソースには未対応)
  • Sidecar を構成できるリージョンは限定されている(West Europe など)

techcommunity.microsoft.com

今回は最もシンプルな構成で試したかったので、ASP.NET Core の Web API をコンテナー化して Sidecar にデプロイしてみました。

Sidecar パターンとは

マイクロサービスで構成されるシステムを構築する場合、分散されたサービス群を管理するためのアーキテクチャや運用の複雑さが増す傾向にあります。
分散アーキテクチャのメリットを活かしながら複雑さを最小限に抑える手法として、Sidecar パターンを使ったアプリケーション構築が注目されています。
learn.microsoft.com
Sidecar パターンの良いところは、分散アーキテクチャの非機能要件をアプリケーションとは疎結合に切り離して実装できることです。あくまでメインアプリケーションを補助的にサポートするコンテナーであり、メインアプリケーションと同一ライフサイクルであることを考慮することが重要です。
例えば、下記のような機能が Sidecar パターンで多く実装されています。

  • ログやトレースなど可観測性に関する機能
  • リモートサービスを呼び出す際のリトライやサーキットブレーカーなど回復性に関する機能

Sidecar アプリケーションを作成する

ASP.NET Core でテキストのみを返すシンプルな Web API を作成します。

[Route("api/[controller]")]
[ApiController]
public class DemoController : ControllerBase
{
    [HttpGet]
    public ActionResult<string> Get()
    {
        var response = "Hello Sidecar!";
        return Ok(response);
    }
}

App Service 内部において、Sidecar を呼び出す側と呼び出される側でポート番号が重複しないように、Program.cs でポート番号を 2000 に変更しておきます。

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
    // Sidecar としてデプロイしたいので、ポート番号を 2000 に変更
    options.Listen(IPAddress.Parse("0.0.0.0"), 2000);
});

// HTTP でホストしたいので HTTPS リダイレクトは無効化
//app.UseHttpsRedirection();

Dockerfile においても、ポート番号 2000 を開けておきます。

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /code
COPY . .
RUN dotnet restore
RUN dotnet publish --output /output --configuration Release

FROM mcr.microsoft.com/dotnet/aspnet:8.0
EXPOSE 2000
COPY --from=build /output /app
WORKDIR /app
ENTRYPOINT ["dotnet", "sidecar-dotnetcore.dll"]

アプリケーションが完成したので、Docker Hub にプッシュしておきます。

$ docker build -t thara0402/sidecar-dotnetcore:0.3.0 ./
$ docker push thara0402/sidecar-dotnetcore:0.3.0

Sidecar を呼び出す側のアプリケーションを作成する

ASP.NET Core で Sidecar を呼び出すシンプルな Web API を作成します。

[Route("api/[controller]")]
[ApiController]
public class DemoController : ControllerBase
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IConfiguration _configuration;

    public DemoController(IHttpClientFactory httpClientFactory, IConfiguration configuration)
    {
        _httpClientFactory = httpClientFactory;
        _configuration = configuration;
    }

    [HttpGet]
    public async Task<ActionResult<string>> Get()
    {
        var sidecarUrl = _configuration["SIDECAR_URL"];

        var httpClient = _httpClientFactory.CreateClient();
        var response = await httpClient.GetStringAsync(sidecarUrl);
        return Ok(response);
    }
}

Sidecar の URL については、appsettings.json に切り出しておきました。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "SIDECAR_URL": "http://localhost:2000/api/Demo"
}

上記以外のコードや Dockerfile はテンプレート通りなので説明は割愛します。
アプリケーションが完成したので、Docker Hub にプッシュしておきます。

$ docker build -t thara0402/sidecar-primary-app:0.5.0 ./
$ docker push thara0402/sidecar-primary-app:0.5.0

Sidecar を構成した App Service をデプロイする

App Service on Linux に Sidecar パターンを構成していきます。リージョンは West Europe を指定しました。

App Service を作成後、 Deployment Center から Sidecar のコンテナーを追加します。


動作確認

Swagger UI から Sidecar の Web API を呼び出せることを確認できました。


まとめ

Azure App Service on Linux の Sidecar にカスタムコンテナーをデプロイしてみました。
Sidecar パターンは、App Service におけるマルチコンテナー対応の後継機能とも言われていますが、個人的には前述した Sidecar パターンの特性を活かしたユースケースで利用したほうがいいのではと感じています。
似たような機能に Webjobs もありますが、こちらはバックグラウンド タスクをスケジュール実行するユースケースに向いている機能となります。

今回のソースコードは、こちらのリポジトリで公開しています。
github.com