博客 | NGINX

教程: 使用 NGINX 和 NGINX Plus 代理 .NET Core 和 Kestrel

Nick Shadrin 缩略图
尼克·沙德林
2017 年 2 月 14 日发布

大约两年前,微软® 宣布推出.NET Core ,这是一个允许您在 Linux 和 Mac 系统上本地开发和运行 .NET应用的框架。 ASP.NET Core 包含Kestrel ,一个内部 Web 服务器库。

正如Microsoft 网站GitHub 存储库上的 Kestrel 文档所示,您通常在生产 Web 服务器(例如 IIS 或 NGINX)后面运行 Kestrel。在本教程中,我们将介绍如何在 NGINX 和 NGINX Plus 后面实现 Kestrel。

在本教程中,你将学习如何:

安装和配置完成后:

  • .NET Core 和 Kestrel:

    • 运行动态应用代码
    • 监听本地 IP 地址并响应 HTTP 请求
  • NGINX 或 NGINX Plus,充当反向代理:

    • 接受通过 IPv6 和 IPv4 进行的 HTTP/2 流量
    • 为 .NET应用提供 SSL 卸载
    • 提供静态文件服务
    • 提供访问日志
    • 添加缓存
  • NGINX 优点:

    • 提供实时活动监控和指标
    • 通过主动健康检查确保应用程序正常运行

.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 服务器
  4. 配置 NGINX 或 NGINX Plus 以反向代理 .NETapplication
  5. 配置 NGINX Plus 实时活动监控和主动健康检查

安装 .NET Core、NGINX 和 NGINX Plus

  1. 使用 Microsoft 网站上的说明安装 .NET Core。

    在我们的示例中,我们使用 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
    
  2. 安装NGINX:

    $ sudo apt-get install nginx
    
  3. 如果您想要实时活动监控、主动健康检查或两者兼而有之,请安装 NGINX Plus。 请参阅NGINX Plus 管理指南中的说明。

    1. 编辑./project.json文件以将 Kestrel 作为依赖项添加到项目中。

      {  "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"
          }
        }
      }
      
    2. 将此简单应用程序的代码复制到名为Program.cs的新文件中。 它返回当前日期和时间,在本地主机的端口 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();
              }
          }
      }
      
    3. 运行dotnet run命令启动 .NET Core 服务器:

      $ 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.
      
    4. 运行curl命令测试连通性和 HTTP:

      $ 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 证书。 有多种方法可以获得:

      • 从知名证书颁发机构 (CA) 购买
      • 让您的公司 IT 团队或 CA 生成它
      • 从现有 IIS 服务器导出
      • 使用免费的 CA,例如Let's Encrypt
      • 直接生成自签名证书

      为了快速启动带有 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'
      -----
      
    2. 在默认 NGINX 和 NGINX Plus 配置文件中为 HTTP 虚拟服务器配置反向代理。

      NGINX 和 NGINX Plus 的主要配置文件是/etc/nginx/nginx.conf 。 但是,多个 NGINX 发行版(以及 NGINX Plus)遵循这样的约定:您不在主文件中放置太多实际配置,而是在/etc/nginx的子目录中创建较小的、特定于功能的文件:

      • 对于nginx.org提供的 NGINX 开源版本和 NGINX Plus,该目录为/etc/nginx/conf.d ,HTTP 虚拟服务器的默认文件为default.conf
      • 对于随 Ubuntu 分发的 NGINX 开源版本,该目录为/etc/nginx/sites-enabled ,HTTP 虚拟服务器的默认文件为default

      然后使用include指令将这些目录中特定于功能的文件的内容读入主文件( nginx.conf )中,例如:

      include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;
      

      如果您不确定系统上 HTTP 虚拟服务器的默认配置文件是什么,请在/etc/nginx/nginx.conf中找到相关的包含指令。

      要将 NGINX 或 NGINX Plus 配置为反向代理,请将以下三个配置块添加到 HTTP 虚拟服务器的默认配置文件中:

      • 第一个服务器块在端口 80 上接受 HTTP 请求并将其重定向到虚拟服务器以进行 HTTPS 请求。

      • 第二个服务器块在端口 443 上接受 HTTPS 请求,并将它们代理到一组或多组上游(后端)服务器,这里称为dotnet 。 (如果在步骤 1 中,您将自签名 SSL 证书安装在/etc/nginx以外的目录中,请在ssl_certificatessl_certificate_key指令中替换正确的路径。)

      • 上游块定义后端服务器的dotnet组。

        运行 Kestrel HTTP 服务器中,我们在localhost:5000上配置了 Kestrel,这意味着它在该端口上监听 IPv4 和 IPv6 流量。 (仅为一种协议配置 Kestrel 可能会导致不稳定,并且可能502錯誤。 类似地,NGINX 和 NGINX Plus 将localhost解析为其 IPv4 和 IPv6 地址(127.0.0.1 和 ::1)。 为了简单起见,这里我们将上游服务器标识为127.0.0.1而不是localhost ,因此它只监听 IPv4 流量。 如果您对包含 IPv6 的更高级配置感到满意,则可以使用localhost

      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;
      }
      
    3. 运行此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
      

      笔记: 如果你看到502糟糕的网关错误,这意味着 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好的
    • 应用服务器是 Kestrel,而不是其他软件
    • 回复正文包含“当前日期”字样
    • 应用程序在 1 秒的超时期限内做出响应
  4. 运行“Hello World”应用程序

    在您选择的父目录中安装并初始化“Hello World”应用程序:

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

    要检查应用程序是否正常运行,请运行dotnet run命令。

    运行 Kestrel HTTP 服务器

    此时,.NET Core 正在 Linux 上运行并使用 Kestrel 作为 HTTP 服务器提供动态数据。

    配置 NGINX 或 NGINX Plus 以反向代理 .NETapplication

    使用 NGINX 或 NGINX Plus 作为 .NET应用的反向代理,您可以轻松配置 SSL/TLS 安全性、HTTP/2 支持和许多其他功能,以便在运行 .NET Core应用的同一台机器上快速交付应用。 以下说明假设您的系统上已经安装了 NGINX 和 NGINX Plus;如果没有,请参阅安装 .NET Core、NGINX 和 NGINX Plus

    配置 NGINX Plus 实时活动监控和主动健康检查

    至此我们已经完成了 NGINX 或 NGINX Plus 与 .NET Core 的基本配置。 NGINX 或 NGINX Plus 为我们的 .NET Core 应用提供 HTTP 处理、被动健康检查、SSL/TLS 安全性以及 HTTP/2 连接。

    如果您已经安装了 NGINX Plus,则可以配置两个附加功能:实时活动监控和主动健康检查。

    配置实时活动监控

    [编辑器 – 本节已更新,参考NGINX Plus API ,该 API 取代并弃用了最初在此处讨论的单独扩展 Status 模块。]

    将以下服务器块添加到 HTTP 虚拟服务器的默认 NGINX 配置文件中。 我们强烈建议您限制对统计数据和指标的访问。 这里我们只允许本地主机和本地网络上的用户访问。

    有关实时活动监控的更多信息,请参阅我们博客上的《通过 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 虚拟服务器的默认配置文件中,将以下位置块添加到主服务器块(在配置 NGINX 或 NGINX Plus 以反向代理 .NETapplication的第 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 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 为 .NET Core应用的 HTTP 请求提供安全性、可扩展性、身份验证、流量限制和智能路由。

    要亲自尝试 NGINX Plus,请立即开始30 天免费试用,或联系我们讨论您的用例


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”