为什么我尝试访问 ELB DNS 时得到 502

Why do I get a 502 when I attempt to access ELB DNS

我正在尝试使用以下设置(从上到下)在 EC2 实例上托管 ASP.NET 核心应用程序。鉴于以下设置,我获得了 EC2 实例和目标组的健康状况。此外,如果我检查服务器上 Kestrel 服务的状态,我可以看到来自目标组健康检查的传入请求有 200 个响应。

我遇到的问题是,如果我访问 ELB 的 DNS 端点,我会收到 502(错误网关)响应。为什么是这样?特别是因为我在 Web 服务器上看到健康检查请求进入并收到 200 个响应。 但是我没有看到我明确针对 ELB 的 DNS 端点发出的请求。这就像对 ELB 的 DNS 端点的请求实际上从未到达 Web 服务器。

另一件需要注意的事情是,我在与容纳 EC2 实例的私有子网相同的 VPC 内的 public 子网中有一个跳转服务器。我能够从跳转服务器向私有 IP 发出请求,并通过我的登录 html 返回 200 响应。网络服务器上的一切似乎都是正确的;那之外的东西出了问题。

53 号公路

我正在为我的域使用 Route 53 托管区域。 HZ 有一条指向 Elastic Load Balancer.

的 A 记录

弹性负载均衡器

来自域(在端口 HTTP 和 HTTPS 上)的流量被路由到侦听 HTTP (80) 和 HTTPS (443) 的 Application Load Balancer。 HTTPS 流量具有 证书管理器 分配的 public SSL 证书。 HTTPS 流量在此处终止并作为 HTTP 传递到基础实例。

ELB 目标群体

我有一个目标组指向一个指定的实例。对于目标组,我的目标是 运行 应用程序的登录页面并期待 200 响应。

Auto-Scaling组

我有一个指向 ELB 目标组的 ASG。

网络服务器

对于 Web 服务器,我是 运行 Amazon Linux 2 AMI 实例,带有 Kestrel 运行,位于 Nginx 反向代理后面。 Kestrel 服务在端口 5000 (HTTP) 上托管一个 ASP.NET MVC 应用程序 运行。

EC2 实例位于私有子网中。在同一 VPC 和 AZ 中有一个 public 子网,并附加了 Internet 网关

对于 .NET Core 应用程序的启动配置,我使用标准转发headers。

有一个安全组附加到 EC2 实例,允许来自 ELB 安全组的 HTTP 和 HTTPS 流量以及来自位于同一 VPC 中 public 子网中的跳转箱的 SSH 流量。

我想知道是不是因为发送给 NGINX 的 header 太大了?您可以通过更改以下配置来增加 NGINX 中允许的大小。

nginx.conf

http{
...
proxy_buffer_size   128k;
proxy_buffers   4 256k;
proxy_busy_buffers_size   256k;
large_client_header_buffers 4 16k;
...
}

default.conf

location /{
    ...
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
    ...
}

我最终发现我的 Nginx 配置与 ELB 配置冲突。我最终将 nginx.conf 恢复到其初始状态,并在 conf.d 文件夹下提供了更明确定义的自定义配置(我在这里专门为我的应用程序创建了一个 .conf 文件,该文件以我想要的方式路由流量).

我还做了以下工作来简化我对每件角色的意图:

  1. 由于 SSL 在 ALB 终止,我修改了 Kestrel 以不再侦听 443 (HTTPS) 流量;它只监听 80 (HTTP) 流量。目前,这很好,因为没有任何其他 VPC 成员会由于 HTTP 流量通过 ELB 而构成安全威胁。在ELB之上,一切还是加密的。

  2. 我添加了一个 ELB 侦听器,用于侦听 443 和 80 流量,并将其转发到仅针对 80 流量的目标组(请记住,Kestrel 现在只寻找 80 流量)。

  3. 我还需要将startup.cs改为而不是UseHttpRedirection;同样,SSL 在 ELB 处终止。

所有这些结合起来解决了我的问题。