博客 | NGINX

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

NGINX-F5-horiz-black-type-RGB 的一部分
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 安装 nginx
  3. 如果您想要实时活动监控、主动健康检查或两者兼而有之,请安装 NGINX Plus。 请参阅NGINX Plus 管理指南中的说明。

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

      { “版本”: “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” },“导入”:“dnxcore50”} } }
      
    2. 将此简单应用程序的代码复制到名为Program.cs的新文件中。 它返回当前日期和时间,在本地主机的端口 5000 上运行 Kestrel。

      使用系统;使用 Microsoft.AspNetCore.Builder;
      使用 Microsoft.AspNetCore.Hosting;
      使用 Microsoft.AspNetCore.Http;
      
      命名空间 ConsoleApplication
      {
      公共类 Program
      {
      公共静态 void Main(string[] args)
      {
      var host = new WebHostBuilder()
      .UseKestrel()
      .Configure(app =>
      {
      app.Run(async (context) => await context.Response.WriteAsync("当前日期:" + DateTime.Now + "n"));
      })
      .Build();
      
      host.Run();
      }
      }
      }
      
    3. 运行dotnet run命令启动 .NET Core 服务器:

      $ dotnet run项目应用程序(.NETCoreApp,Version=v1.0)将被编译,因为输入已被修改 为 .NETCoreApp,Version=v1.0 编译应用程序 编译成功。
          0 警告 0 错误 已用时间 00:00:01.9047678 你好,世界!
      托管环境: 生产内容根路径:/app/bin/Debug/netcoreapp1.0 现在监听:http://localhost:5000application已启动。 按Ctrl+C关机。
      
    4. 运行curl命令测试连通性和 HTTP:

      $ curl -v localhost:5000 * 将 URL 重建为:localhost:5000/ * 尝试 ::1... * 已连接到 localhost (::1) 端口 5000 (#0) > GET / HTTP/1.1 > 主机:localhost:5000 > 用户代理:curl/7.47.0 > 接受:*/* > < HTTP/1.1 200 OK < 日期: 2017 年 2 月 14 日星期二 19:50:59 GMT < 传输编码:分块 < 服务器: Kestrel < 当前日期: 02/14/17 12:50:59 PM * 与主机 localhost 的连接 #0 保持完好
      
    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.pem生成一个 4096 位 RSA 私钥 .........++ ................................++ 将新私钥写入“/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 )中,例如:

      包括 /etc/nginx/conf.d/*.conf;包括 /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

      服务器 { listen 80 default_server;
      listen [::]:80 default_server;
      return 301 https://$host$request_uri;
      }
      
      服务器 {
      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 * 重建 URL 至:https://localhost/ * 尝试 ::1... * 已连接到 localhost (::1) 端口 443 (#0) ...[跳过]... < HTTP/1.1 200 OK < 服务器:nginx/1.10.0 (Ubuntu) < 日期: 2017 年 2 月 14 日星期二 20:22:07 GMT < 传输编码:分块 < 连接:保持活动 < 当前日期: 2017 年 2 月 14 日下午 1:22:07
      

      笔记: 如果你看到502糟糕的网关错误,这意味着 NGINX 或 NGINX Plus 无法连接到您的 .NET应用。 确保它在端口 5000 上运行并提供响应。

      如果您已经安装了nghttp2包,您还可以运行以下nghttp命令来测试通过 HTTP/2 的连接。 在以下示例中,查找以橙色突出显示的行,该行位于相当长的输出的开头附近。

      $ nghttp -v https://localhost [ 0.000] 已连接协商的协议:h2 [ 0.009] 发送 SETTINGS 帧 (niv=2) [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] [ 0.009] 发送 PRIORITY 帧 (dep_stream_id=0, weight=201, exclusive=0)
      
    • 响应代码为200好的
    • 应用服务器是 Kestrel,而不是其他软件
    • 回复正文包含“当前日期”字样
    • 应用程序在 1 秒的超时期限内做出响应
  4. 运行“Hello World”应用程序

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

    $ cd父目录用于应用程序$ 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 管理指南》

    服务器 { listen 8080;
    allow 127.0.0.1; # 允许本地主机访问统计信息
    allow 10.3.3.0/24; # 允许本地网络访问统计信息
    denied all; # 阻止从其他地方访问
    
    root /usr/share/nginx/html;
    
    location / {
    return 302 /dashboard.html;
    }
    
    location /api {
    api write=on;
    }
    
    location = /dashboard.html {
    root /usr/share/nginx/html;
    }
    
    # 将请求重定向到旧仪表板
    location = /status.html {
    return 301 /dashboard.html;
    }
    }
    

    配置主动健康检查

    主动健康检查可确保 NGINX Plus 仅向正常运行的应用发送流量。 您定义 NGINX Plus 定期向应用程序发送的 HTTP 请求,以及应用程序必须返回才被视为健康的响应类型。

    这里我们要求应用程序的响应满足以下条件:

    在 HTTP 虚拟服务器的默认配置文件中,将以下位置块添加到主服务器块(在配置 NGINX 或 NGINX Plus 以反向代理 .NETapplication的第 2 步中定义的 HTTPS 流量块):

    位置@healthcheck { proxy_pass http://dotnet;
    proxy_set_header 主机 localhost;
    health_check match=currentdate;
    proxy_connect_timeout 1s;
    proxy_read_timeout 1s;
    }
    

    另外,在层次结构中与服务器上游块处于同一级别添加以下匹配块:

    匹配当前日期 { 状态 200;
    标头服务器 = Kestrel;
    正文 ~ "当前日期";
    }
    

    您可以在内置实时活动监控仪表板的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 内容。”