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

NGINX | 2017年2月14日

大约两年前,Microsoft®发布了 .NET Core。该框架支持在Linux和Mac系统上原生开发和运行.NET应用程序。ASP.NET Core包含内部Web服务器库Kestrel。

正如Microsoft网站和GitHub存储库中的Kestrel文档所述,通常需要将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 服务器
  4. 配置NGINX或NGINX Plus以反向代理.NET应用程序
  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
  1. 安装NGINX:
$ sudo apt-get install nginx
  1. 如果需要实时活动监控、主动健康检查或同时使用这两项功能,请安装NGINX Plus。有关说明,请参阅《NGINX Plus Admin Guide》。
    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"
    }
  }
}
  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. 运行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.
  1. 运行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证书。获取证书有多种方式:为了快速启动一个启用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. 在默认的NGINX和NGINX Plus配置文件中为HTTP虚拟服务器配置反向代理。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配置为反向代理,请将以下3个配置块添加到HTTP虚拟服务器的默认配置文件中:
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;
}
  • 对于由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请求的虚拟服务器。
  • 第二个server块在端口443上接受HTTPS请求,并将其代理到由一个或多个上游(后端)服务器组成的服务器组,此处称为dotnet。(如果在步骤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来标识上游服务器,使其仅侦听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 服务器

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

配置NGINX或NGINX Plus以反向代理.NET应用程序

在运行.NET Core应用的同一台计算机上,使用NGINX或NGINX Plus作为.NET应用的反向代理,可以轻松配置SSL/TLS安全功能、HTTP/2支持及其他多项功能,从而快速交付应用。以下说明假定系统中已安装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模块,后者现已弃用。]

将以下server块添加到HTTP虚拟服务器的默认NGINX配置文件中。强烈建议限制对统计信息和指标的访问。此处仅允许localhost和本地网络中的用户访问。

有关实时活动监控的更多信息,请参阅我们博客中的《只需 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块中(即配置NGINX或NGINX Plus以反向代理.NET应用程序第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";
}

可以在内置实时活动监控仪表板的“上游”选项卡中验证后端应用是否正常运行(在浏览器中访问//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天免费试用,或联系我们,讨论您的用例。


分享

相关博客文章

NGINX Plus R26 正式发布
NGINX | 2022/02/15

NGINX Plus R26 正式发布

NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
NGINX | 2022/02/10

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击

gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
NGINX | 2021/09/13

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划

了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。

NGINX Plus R19 正式发布
NGINX | 2019/09/03

NGINX Plus R19 正式发布

NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。

NGINX现已正式加入F5
NGINX | 2019/05/09

NGINX现已正式加入F5

NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

使用NGINX和NGINX Plus实现高性能缓存
NGINX | 2016/08/24

使用NGINX和NGINX Plus实现高性能缓存

我将介绍NGINX在内容缓存和性能方面的工作原理,并分享一些控制NGINX内容缓存方式的技巧。