【问题标题】:How to configure nginx as basic load balancer如何将 nginx 配置为基本负载均衡器
【发布时间】:2020-09-07 14:56:18
【问题描述】:

我有一台服务器,我想将其设置为负载平衡器/反向代理。
在 debian 10 上运行的 nginx/1.14.2

我根本不想要缓存,我只是希望当人们访问负载平衡 nginx 服务器时,它将 TCP 直接发送到后端服务器(基于 nginx 的 ip 哈希算法),就好像他们最初连接到它一样。

我还想在这个负载均衡器之上使用 cloudflare 来实现它的 CDN 和缓存。

这是我目前的设置:

upstream backend {
    ip_hash;
    server node1.example.com;
    server node2.example.com;
    keepalive 100;
}

server {
    listen 80;
    listen [::]:80;
    access_log off;

    location / {
        proxy_http_version 1.1;

        proxy_set_header Host $http_host;
        real_ip_header X-Forwarded-For;

        proxy_pass http://backend;
        proxy_redirect off;
        proxy_request_buffering off;
        proxy_buffering off;
    }
}

所有节点和负载均衡器在他们的 conf.d/ 中都有这个(来自 cloudflare 对 nginx 的推荐)

set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;
real_ip_header CF-Connecting-IP;

这似乎工作正常 CF-Connecting-IP 设置为客户端的 Ip。

问题 1

node1.example.comnode2.example.com 上运行的 PHP 服务器当前报告以下内容,其中 (a.b.c.d) 是负载平衡器 IP,(w.x.y.z) 是连接客户端的 IP

  ["REMOTE_ADDR"]=>  "a.b.c.d"
  ["HTTP_X_FORWARDED_FOR"]=>  "w.x.y.z"

我认为real_ip_header X-Forwarded-For; 会使用 HTTP_X_FORWARDED_FOR(来自 cloudflare)并将其存储为真实 IP,这样 php 会说 REMOTE_ADDR 与 HTTP_X_FORWARDED_FOR 相同

这就是我想要的

  ["REMOTE_ADDR"]=> "w.x.y.z"
  ["HTTP_X_FORWARDED_FOR"]=>  "w.x.y.z"

我怎样才能做到这一点?

问题 2

负载均衡器正在添加请求 HTTP 标头 CACHE_CONTROL: max-age=0
它是否正确?如果没有,我怎样才能让负载均衡器使用 CACHE_CONTROL cloudflare 发送的任何内容

问题 3

负载均衡器发出请求 HTTP 标头 CONNECTION: closed 但如果我访问后端,我总是得到 CONNECTION: keep-alive 这是正确的吗?我在负载均衡器上设置了keepalive,但它似乎总是关闭

【问题讨论】:

  • 对于#1,它是正确的。见xpertdeveloper.com/…
  • 我实际上通过在两个节点上使用set_real_ip_from [loadbalancerip] 修复了REMOTE_ADDR 问题。我希望解决方案可以仅在负载均衡器上运行,但情况似乎并非如此
  • 对于#3,根据docs`应该清除“Connection”头字段`在location指令中使用proxy_set_header Connection "";
  • 对于#2,它在哪里添加这个?在对代理的请求中还是在代理的响应中?

标签: php nginx proxy nginx-reverse-proxy


【解决方案1】:

问题 1 已通过在 node1 和 node2 上使用 set_real_ip_from a.b.c.d 解决,其中 a.b.c.d 是负载平衡 IP。

【讨论】:

    【解决方案2】:

    问题 2

    负载均衡器正在添加请求 HTTP 标头 CACHE_CONTROL: max-age=0 这是正确的吗?如果没有,我怎么能有 负载均衡器使用任何 CACHE_CONTROL cloudflare 发送的内容

    默认情况下,Nginx 的缓存不支持 Cache-Control:no-cache 请求头, 也不是 Pragma:no-cache 请求标头。您必须显式配置 Nginx 以绕过 当用户代理发送这些请求标头时,缓存并将请求传递到源服务器。

    可能会对你有所帮助:

    proxy_cache_bypass $http_pragma;
    proxy_cache_bypass $http_cache_control; 
    

    在这种情况下,代理将遵守 Cloudflare 服务发送的缓存标头。

    问题 3

    负载均衡器正在发出请求 HTTP 标头 CONNECTION: closed 但如果 我访问后端我总是得到 CONNECTION: keep-alive is this 正确的?我在负载均衡器上设置了keepalive,但似乎总是 关闭

    根据that docs for http keepalive,您还应该设置:

    proxy_http_version 1.1;
    proxy_set_header Connection "";
    

    请注意,proxy_http_version 的 default 行为是 1.0

    并确保您设置的 100 个连接就足够了keepalive 100; 因为设置太低的值也可能导致CONNECTION: closed 行为。

    【讨论】:

      【解决方案3】:

      问题 1

      ...剪辑...

      我认为real_ip_header X-Forwarded-For; 会使用 X-Forwarded-For(来自 CloudFlare)并将其存储为真实 IP,这样 PHP 会说 $_SERVER["REMOTE_ADDR"]X-Forwarded-For 相同

      你可以,但是please don't do that。这是语义,真的。我的意思是,您可以将汽车的左前轮用作方向盘,这是有原因的,而且两者都是轮子,但我敢肯定,如果您这样做,人们会觉得您很有趣。

      您的 PHP 脚本中的$_SERVER["REMOTE_ADDR"] 或 nginx 中的 $remote_addr 指的是它接受来自的请求的直接客户端;您的客户端(如果他们直接连接到您的后端),或者您的负载均衡器/代理(如果您的客户端从那里连接)。

      X-Forwarded-For 来自负载平衡器(或代理)服务器的请求标头指的是您的真实客户端 IP 地址。因为它是一个普通的请求标头,所以任何客户端都可以欺骗它们,无论是意外(比如说客户端配置错误)还是故意的。

      这样做是出于安全原因,因此如果您的请求是代理/负载平衡请求(具有X-Forwarded-For 请求标头);如果他们的远程地址(nginx 中的$remote_addr 或 PHP 中的 $_SERVER["REMOTE_ADDR"])在您的受信任负载平衡器/代理列表中,您可以接受连接,或者 拒绝如果他们的远程地址不在列表中,则作为伪造请求。

      问题 2

      负载均衡器正在添加请求 HTTP 标头 CACHE_CONTROL: max-age=0 这是正确的吗?

      Cache-Control可以是请求或响应头,所以你需要确认谁发送了这个头;您的客户端、CloudFlare、您的 nginx 负载均衡器或您的 PHP 脚本。

      问题 3

      负载均衡器发出请求 HTTP 标头 CONNECTION: 已关闭,但如果我访问后端,我总是得到 CONNECTION: keep-alive 这是正确的吗?

      nginx by defaultHost: $proxy_hostConnection: close 添加到每个proxy_pass 后端请求。使用proxy_set_header 指令来防止这种情况发生。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 2016-12-29
        • 2019-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多