Amazon Linux 2 で .NET 6をセットアップし、KestrelのみでHTTPアクセスさせてみた

2022.04.14

いわさです。

API Gatewayのバックエンドに簡易的なAPIを用意したかったのですが、せっかくなので最近使えるようになった.NET 6でテスト用のAPIサーバーを作成してみることにしました。

通常はプロセスマネージャー、リバースプロキシとしてApacheやNginxを前段に配置すると思いますが、今回はそのあたりは割愛し、外部ホストを許可させてALBのターゲットグループからKestrel単独でトラフィックを処理してもらいます。
今回は検証用のEC2を構築し、.NET 6やら何やらパッとセットアップして外部からすぐアクセス。みたいなのをコンセプトにしています。

もし、前段に配置する構成を取る場合は以下を参考に構築すると良いです。

やってみた

.NET SDK インストール

Amazon Linux 2標準では、.NET 6はインストールされていません。
そこで、以下のCentOS 7へのセットアップ手順に従って導入します。

今回はx86の手順ですが、ARMの場合はパッケージマネージャーを使用したセットアップがサポートされていないため他の方法をとる必要があります。

$ sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm を取得中
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:packages-microsoft-prod-1.0-1    ################################# [100%]

$ sudo yum install dotnet-sdk-6.0 -y
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
packages-microsoft-com-prod                                                                                                                                        | 3.0 kB  00:00:00     
packages-microsoft-com-prod/primary_db                                                                                                                             | 559 kB  00:00:00     
依存性の解決をしています

:

インストール:
  dotnet-sdk-6.0.x86_64 0:6.0.202-1                                                                                                                                                       

依存性関連をインストールしました:
  aspnetcore-runtime-6.0.x86_64 0:6.0.4-1          aspnetcore-targeting-pack-6.0.x86_64 0:6.0.4-1  dotnet-apphost-pack-6.0.x86_64 0:6.0.4-1  dotnet-host.x86_64 0:6.0.4-1               
  dotnet-hostfxr-6.0.x86_64 0:6.0.4-1              dotnet-runtime-6.0.x86_64 0:6.0.4-1             dotnet-runtime-deps-6.0.x86_64 0:6.0.4-1  dotnet-targeting-pack-6.0.x86_64 0:6.0.4-1 
  netstandard-targeting-pack-2.1.x86_64 0:2.1.0-1 

完了しました!

$ dotnet --version
6.0.202

まずは、.NET6をインストールすることができました。

テンプレートから作成とビルド

おなじみのdotnet newコマンドでテンプレートからプロジェクトを作成します。
今回はASP.NET Core Web APIテンプレートを使用します。

$ mkdir hoge
$ cd hoge/
$ dotnet new webapi --no-https

.NET 6.0 へようこそ!
---------------------
SDK バージョン: 6.0.202

:

作成後の操作を処理しています...
/home/ec2-user/hoge/hoge.csproj で ' dotnet restore ' を実行しています...
  復元対象のプロジェクトを決定しています...
  /home/ec2-user/hoge/hoge.csproj を復元しました (3.09 sec)。
正常に復元されました。

ここでのポイントとしては、今回はALBからEC2へはHTTP通信させようとしています。
よって、no-httpsオプションでHTTPS機能をオプトアウトしたテンプレートを使っています。
このあたりはどの経路を暗号化させたいか次第なので、あるべきはここでは論じません。

テンプレート作成後は、手を加えずに実行モジュールを作成します。
dotnet publishコマンドでアプリケーションと依存関係をフォルダーに発行することが出来ます。

$ dotnet publish -c Release
.NET 向け Microsoft (R) Build Engine バージョン 17.1.1+a02f73656
Copyright (C) Microsoft Corporation.All rights reserved.

  復元対象のプロジェクトを決定しています...
  復元対象のすべてのプロジェクトは最新です。
  hoge -> /home/ec2-user/hoge/bin/Release/net6.0/hoge.dll
  hoge -> /home/ec2-user/hoge/bin/Release/net6.0/publish/

実行

アプリケーションをdotnetで実行します。
デフォルトではリスナーはlocalhostにバインドされます。 ここでは、ALBがリバースプロキシになっているので、任意のホスト名でアクセス出来るように環境変数ASPNETCORE_URLSで動作をオーバーライドさせています。

$ export ASPNETCORE_URLS="http://*:5000"
$ dotnet /home/ec2-user/hoge/bin/Release/net6.0/publish/hoge.dll 
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://[::]:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/ec2-user/hoge/

Application Load Balancer

ALBはHTTP80ポートのリスナーを作成し、HTTP5000ポートでEC2へルーティングさせるように設定します。
ヘルスチェックも同じパスを参照させています。

動作確認

これで準備OKです。
ALBは外部ロードバランサーとして作成しているので、インターネット経由でアクセスしてみます。

$ curl http://hoge-web-alb-2032848155.ap-northeast-1.elb.amazonaws.com/WeatherForecast | jq
[
  {
    "date": "2022-04-15T02:21:07.8445394+00:00",
    "temperatureC": 34,
    "temperatureF": 93,
    "summary": "Sweltering"
  },
  {
    "date": "2022-04-16T02:21:07.8445423+00:00",
    "temperatureC": 10,
    "temperatureF": 49,
    "summary": "Chilly"
  },
  {
    "date": "2022-04-17T02:21:07.8445431+00:00",
    "temperatureC": 8,
    "temperatureF": 46,
    "summary": "Warm"
  },
  {
    "date": "2022-04-18T02:21:07.8445439+00:00",
    "temperatureC": 15,
    "temperatureF": 58,
    "summary": "Warm"
  },
  {
    "date": "2022-04-19T02:21:07.8445447+00:00",
    "temperatureC": 20,
    "temperatureF": 67,
    "summary": "Sweltering"
  }
]

デフォルトで作成されるコントローラーからレスポンスを得ることが出来ました。

さいごに

本日はAmazon Linux 2に.NET 6で簡易的なWebアプリを構築してみました。

普段は検証用に簡易的なAPIサーバーを作成するときはApache+PHPが多いのですが、クラウドにホストさせた状態でAWS .NET SDKなどを使いたい時に役立つのではと思っています。