チュートリアル:NGINXおよびNGINX Plusで.NET CoreとKestrelをプロキシする方法

NGINX | 2017年2月14日

約2年前、Microsoft®は、LinuxおよびMacシステム上で.NETアプリケーションをネイティブに開発、実行できるフレームワークである「.NET Core」を発表しました。ASP.NET Coreには、内部Webサーバーライブラリである「Kestrel」が含まれています。

Kestrelに関するドキュメントは、Microsoft WebサイトおよびGitHubリポジトリで公開されています。通常、KestrelはIISやNGINXなどの本番環境用Webサーバーの背後で実行します。このチュートリアルでは、NGINXおよびNGINX Plusの背後にKestrelを実装する方法について説明します。

このチュートリアルでは、以下の方法について説明します。

インストールと設定が完了したら:

  • .NET CoreとKestrel:
    • 動的アプリケーションコードを実行
    • ローカルIPアドレスで待ち受け、HTTPリクエストに応答する
  • リバースプロキシとして動作するNGINXまたはNGINX Plus:
    • IPv6およびIPv4経由のHTTP/2トラフィックを受け入れる
    • .NETアプリケーションのSSLオフロードを提供
    • 静的ファイルを配信
    • アクセスログを提供
    • キャッシュ機能を追加
  • NGINX Plus:
    • リアルタイムのアクティビティ監視とメトリクスを提供
    • アクティブヘルスチェックにより、アプリが正常に動作していることを確認

.NET Coreアプリケーションのデプロイアーキテクチャは、Node.jsまたはGoアプリケーションのデプロイアーキテクチャと似ています。NGINXは、.NETアプリケーションの本番環境へのデプロイとスケーリングを容易にするトラフィック管理機能を提供します。複数の.NETアプリケーションを同じマシンまたは異なるマシンで実行でき、NGINXまたはNGINX Plusがアプリケーション間の負荷分散とインテリジェントなトラフィックルーティングを行います。

手順

以下の手順では、.NET Coreを使用して「Hello World」アプリをすばやく構築し、Linux上で実行したうえで、高度なトラフィック管理機能を備えたNGINXまたはNGINX Plusリバースプロキシの背後にデプロイする方法を説明します。

  1. .NET Core、NGINX、NGINX Plusをインストール
  2. 「Hello World」アプリを実行
  3. Kestrel HTTP Serverを実行
  4. .NETアプリケーションをリバースプロキシするようにNGINXまたはNGINX Plusを構成する
  5. NGINX Plusのライブアクティビティモニタリングとアクティブヘルスチェックを設定する

.NET Core、NGINX、NGINX Plusのインストール

  1. .NET Coreは、Microsoft Webサイトの「手順」に従ってインストールします。この例ではUbuntu 16.04を使用します。以下のコマンドは執筆時点では正しいものですが、Kestrelは現在も開発中のため、変更される可能性があります。必要に応じて「.NET Coreドキュメント」を参照してください。
$ sudo apt-get install apt-transport-https$ sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
$ sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
$ sudo apt-get update
$ sudo apt-get install dotnet-dev-1.0.0-preview2-003131
  1. NGINXをインストールします:
$ sudo apt-get install nginx
  1. ライブアクティビティ監視、アクティブヘルスチェック、またはその両方を使用する場合は、NGINX Plusをインストールします。手順については、「NGINX Plus Admin Guide」を参照してください。
    1. プロジェクトの依存関係にKestrelを追加するため、./project.jsonファイルを編集します。
{  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        }, "Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
      },
      "imports": "dnxcore50"
    }
  }
}
  1. シンプルなアプリ用のこのコードを、次の名前の新しいファイルにコピーします。Program.csこのアプリはlocalhostのポート5000でKestrelを実行し、現在の日付と時刻を返します。
using System;using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .Configure(app =>
                {
                    app.Run(async (context) => await context.Response.WriteAsync("Current date: " + DateTime.Now + "n"));
                })
                .Build();

            host.Run();
        }
    }
}
  1. .NET Coreサーバーを起動するには、dotnet runコマンドを実行します:
$ dotnet runProject app (.NETCoreApp,Version=v1.0) will be compiled because inputs were modified
Compiling app for .NETCoreApp,Version=v1.0

Compilation succeeded.
    0 Warning(s)
    0 Error(s)

Time elapsed 00:00:01.9047678

Hello World!
Hosting environment: Production
Content root path: /app/bin/Debug/netcoreapp1.0
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
  1. 接続性とHTTPをテストするために、curlコマンドを実行します:
$ curl -v localhost:5000* Rebuilt URL to: localhost:5000/
*   Trying ::1...
* Connected to localhost (::1) port 5000 (#0)
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 14 Feb 2017 19:50:59 GMT
< Transfer-Encoding: chunked
< Server: Kestrel
<
Current date: 02/14/17 12:50:59 PM
* Connection #0 to host localhost left intact
  1. SSL証明書をインストールします。証明書を取得する方法はいくつかあります。ここでは、SSLを使用するサンプル.NET Coreアプリをすぐに起動できるよう、次のopensslコマンドで自己署名証明書と関連する鍵を生成します。証明書と鍵はNGINXの標準の場所である/etc/nginxにインストールしますが、別の場所を選択することもできます。
$ openssl req -x509 -subj /CN=localhost -days 365 -set_serial 2 -newkey rsa:4096 -keyout /etc/nginx/cert.key -nodes -out /etc/nginx/cert.pemGenerating a 4096 bit RSA private key
.........++
............................++
writing new private key to '/etc/nginx/cert.key'
-----
  • 信頼できる認証局(CA)から購入する
  • 社内のIT部門またはCAに生成を依頼する
  • 既存のIISサーバーからエクスポートする
  • 無料のCA(認証局)を使用する(例:Let’s Encrypt)
  • 自己署名証明書を直接生成する
  1. HTTP仮想サーバー用のデフォルトのNGINXおよびNGINX Plus設定ファイルで、リバースプロキシを設定します。NGINXおよびNGINX Plusのメイン設定ファイルは/etc/nginx/nginx.confです。ただし、一部のNGINXディストリビューション(およびNGINX Plus)では、実際の設定の大部分をメインファイルに記述せず、代わりに/etc/nginxのサブディレクトリに、機能ごとの小さなファイルを作成するという規則に従います。これらのディレクトリにある機能別ファイルの内容は、nginx.confメインファイルにincludeディレクティブを使用して読み込まれます。例:
include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;
  1. システム上のHTTP仮想サーバー用デフォルト設定ファイルが不明な場合は、includeディレクティブを/etc/nginx/nginx.confで確認してください。NGINXまたはNGINX Plusをリバースプロキシとして設定するには、HTTP仮想サーバー用デフォルト設定ファイルに、次の3つの設定ブロックを追加します。
server {    listen 80 default_server;
    listen [::]:80 default_server;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    ssl_certificate /etc/nginx/cert.pem;
    ssl_certificate_key /etc/nginx/cert.key;

    location / {
        proxy_pass http://dotnet;
        proxy_set_header Host $host;
    }
}

upstream dotnet {
    zone dotnet 64k;
    server 127.0.0.1:5000;
}
  • For NGINX Open Source builds provided by nginx.orgが提供するNGINX Open SourceビルドおよびNGINX Plusでは、ディレクトリは「/etc/nginx/conf.d」、HTTP仮想サーバーのデフォルトファイルは「default.conf」です。
  • Ubuntuで配布されるNGINX Open Sourceビルドの場合、ディレクトリは「/etc/nginx/sites-enabled」で、HTTP仮想サーバーのデフォルトファイルは「default」です。
  • 最初の「server」ブロックは、ポート80でHTTPリクエストを受け付け、HTTPSリクエスト用の仮想サーバーにリダイレクトします。
  • 2つ目の「server」ブロックは、ポート443でHTTPSリクエストを受け付け、ここでは「dotnet」と呼ぶ1台以上のアップストリーム(バックエンド)サーバーのグループにプロキシします。(ステップ1で自己署名SSL証明書を「/etc/nginx」以外のディレクトリにインストールした場合は、「ssl_certificate」ディレクティブと「ssl_certificate_key」ディレクティブのパスを正しいものに置き換えてください。)
  • The upstreamブロックでは、バックエンドサーバーのdotnetグループを定義します。「Kestrel HTTPサーバーの実行」では、Kestrelをlocalhost:5000に設定しました。これは、そのポートでIPv4とIPv6の両方のトラフィックをリッスンすることを意味します。(Kestrelを一方のプロトコルのみに設定すると、動作が不安定になり、502エラーが発生する可能性があります。)同様に、NGINXとNGINX Plusは、localhostをIPv4アドレスとIPv6アドレス(127.0.0.1と::1)の両方に解決します。ここでは簡潔にするため、アップストリームサーバーを127.0.0.1ではなくlocalhostとして指定するのではなく、localhostではなく127.0.0.1として指定し、IPv4トラフィックのみをリッスンするようにします。IPv6を含む、より高度な設定に対応できる場合は、localhostを使用できます。
  1. 次のcurlコマンドを実行し、HTTPS経由で.NET Coreアプリに接続できることを確認します。(代わりに、ブラウザーでLinuxサーバーにアクセスすることもできます。)
$ curl -kv https://localhost* Rebuilt URL to: https://localhost/
*   Trying ::1...
* Connected to localhost (::1) port 443 (#0)
...[SKIPPED]...
< HTTP/1.1 200 OK
< Server: nginx/1.10.0 (Ubuntu)
< Date: Tue, 14 Feb 2017 20:22:07 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
<
Current date: 02/14/17 1:22:07 PM
  1. 注: 502 Bad Gatewayエラーが表示される場合、NGINXまたはNGINX Plusが.NETアプリケーションに接続できていません。アプリケーションが実行中で、ポート5000で応答を返していることを確認してください。nghttp2パッケージをインストールしている場合は、次のnghttpコマンドを実行して、HTTP/2経由の接続をテストすることもできます。かなり長い出力の冒頭付近にある、次の例でオレンジ色にハイライトされた行を確認してください。
$ nghttp -v https://localhost[  0.000] Connected
The negotiated protocol: h2
[  0.009] send SETTINGS frame 
          (niv=2)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[  0.009] send PRIORITY frame 
          (dep_stream_id=0, weight=201, exclusive=0)
  • レスポンスコードは「200 OK」です
  • アプリサーバーが他のソフトウェアではなくKestrelである
  • レスポンス本文に「Current date」という語句が含まれている
  • アプリが1秒のタイムアウト時間内に応答する

「Hello World」アプリを実行

任意の親ディレクトリに「Hello World」アプリをインストールし、初期化します:

$ cd parent-dir-for-apps
$ mkdir app
$ cd app
$ dotnet restore

アプリが動作していることを確認するには、dotnet runコマンドを実行します。

Kestrel HTTP Serverを実行する

この時点で、.NET CoreはLinux上で動作しており、KestrelをHTTPサーバーとして使用して動的データを配信しています。

NGINXまたはNGINX Plusを.NETアプリケーションのリバースプロキシとして構成する

NGINXまたはNGINX Plusを.NETアプリケーションのリバースプロキシとして使用すると、.NET Coreアプリケーションが稼働している同じマシン上で、SSL/TLSによるセキュリティ、HTTP/2のサポート、その他多くの機能を簡単に設定し、アプリケーションを高速に配信できます。以下の手順では、NGINXおよびNGINX Plusがシステムにすでにインストールされていることを前提としています。インストールされていない場合は、「Install .NET Core, NGINX, and NGINX Plus」を参照してください。

NGINX Plusのライブアクティビティモニタリングとアクティブヘルスチェックの設定

これで、NGINXまたはNGINX Plusと.NET Coreの基本設定は完了です。NGINXまたはNGINX Plusにより、.NET CoreアプリのHTTP処理、パッシブヘルスチェック、SSL/TLSによるセキュリティ、HTTP/2接続が提供されます。

NGINX Plusをインストールしている場合は、ライブアクティビティモニタリングとアクティブヘルスチェックという2つの機能を追加で設定できます。

ライブアクティビティモニタリングの設定

[編集者注 – このセクションは、当初ここで説明していた独立した拡張Statusモジュールを置き換え、非推奨とするNGINX Plus APIを参照するよう更新されています。]

以下のserverブロックを、HTTP仮想サーバー用のデフォルトのNGINX設定ファイルに追加します。統計情報とメトリクスへのアクセスを制限することを強く推奨します。ここでは、localhostおよびローカルネットワーク上のユーザーにのみアクセスを許可します。

ライブアクティビティ監視の詳細については、F5のブログ記事「3つの簡単なステップで実現するNGINX Plusのライブアクティビティ監視」および「NGINX Plus管理ガイド」をご覧ください。

server {    listen 8080;
    allow 127.0.0.1;   # Allow localhost to access the statistics
    allow 10.3.3.0/24; # Allow local network to access the statistics
    deny all;          # Prevent access from anywhere else

    root /usr/share/nginx/html;

    location / {
        return 302 /dashboard.html;
    }

    location /api {
        api write=on;
    }

    location = /dashboard.html {
        root /usr/share/nginx/html;
    }

    # Redirect requests made to the old dashboard
    location = /status.html {
        return 301 /dashboard.html;
    }
}

アクティブヘルスチェックの設定

アクティブヘルスチェックにより、NGINX Plusは正常に動作しているアプリケーションにのみトラフィックを送信します。NGINX Plusがアプリケーションに定期的に送信するHTTPリクエストと、アプリケーションが正常と見なされるために返す必要があるレスポンスの種類を定義します。

ここでは、アプリからのレスポンスが次の条件を満たす必要があります。

HTTP仮想サーバーのデフォルト設定ファイルで、次の「location」ブロックをメインの「server」ブロック(「.NETアプリケーションのリバースプロキシとしてNGINXまたはNGINX Plusを設定する」のステップ2で定義したHTTPSトラフィック用のブロック)に追加します。

location @healthcheck {    proxy_pass http://dotnet;
    proxy_set_header Host localhost;
    health_check match=currentdate;
    proxy_connect_timeout 1s;
    proxy_read_timeout 1s;
}

さらに、次の「match」ブロックを「server」ブロックおよび「upstream」ブロックと同じ階層レベルに追加します。

match currentdate {    status 200;
    header Server = Kestrel;
    body ~ "Current date";
}

組み込みのライブアクティビティ監視ダッシュボードの[Upstreams]タブで、バックエンドアプリが正常に稼働していることを確認できます(ブラウザで//http://nginx-plus-server-address:8080/を開きます):

NGINX Plusのライブアクティビティ監視ダッシュボードには、NGINXがプロキシしているバックエンド.NETアプリケーションの稼働状態が表示されます

その他のNGINX構成オプションについては、Microsoftのドキュメントをご覧ください。

まとめ

ASP.NETで開発したアプリを本番環境に対応した形でデプロイするために、NGINXとNGINX Plusは、リバースプロキシに必要なトラフィック管理機能を提供します。NGINXとNGINX Plusは、セキュリティ、スケーラビリティ、認証、トラフィック制限に加え、HTTPリクエストを.NET Coreアプリケーションへインテリジェントにルーティングする機能を提供します。

NGINX Plusを実際にお試しいただくには、今すぐ30日間の無料トライアルを開始するか、ユースケースについてご相談ください。


共有

著者について

Nick Shadrin
Nick Shadrinソフトウェアアーキテクト

Nick Shadrinのその他のブログ記事

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります