我的集群上有两个服务:myapp-service 和 nginx-service。我正在使用服务发现来连接两者,一切正常。
问题发生在我部署新版本的 myapp-service 时,它带有一个新的私有(和公共)IP 地址。部署后,我看到 ip 在 Route 53 上正确更新,但是当我尝试通过 nginx 访问我的应用程序时,它返回一个错误的网关。当我查看 Cloudwatch 上的 nginx 日志时,我可以看到 nginx 正在尝试连接到 myapp-service 的旧私有 IP 地址。
这是我的 nginx 配置(default.conf),marketplace-service.local 是我在 Route 53 上的注册表。
upstream channels-backend {
server marketplace-service.local:8000;
}
server {
listen 80;
location / {
proxy_pass http://channels-backend;
}
}
任何人都可以帮我发现我在这里错过了什么吗??
谢谢
我不知道
upstream
部分。
upstream channels-backend {
server marketplace-service.local:8000;
}
但我确定
server
部分。对于Fargate
,使用localhost
所以添加server_name localhost;
。然后将下面显示的 4 行代码添加到 location
块。
server {
listen 80;
server_name localhost;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://channels-backend;
}
}
问题与DNS缓存有关。与许多服务器一样,Nginx 缓存 DNS 查找,这意味着 Nginx 不会为它代理的每个请求执行 DNS 查找。相反,它解析 DNS 名称一次并在一段时间内重复使用该 IP 地址(由 DNS 条目的生存时间 (TTL) 定义)。
你的案例中棘手的部分来自 proxy_pass 指令,它使 Nginx 仅在启动时解析 proxy_pass 中定义的地址一次 - 在启动时不遵守 route53 记录 TTL!
当您更新通道后端服务时,它会获得一个新的 IP 地址,Nginx 服务将继续使用旧 IP 地址,直到您重新启动 Nginx。这就是为什么您看到 Nginx 尝试连接到旧 IP 地址并返回错误网关错误的原因。
为了能够永久解决这个问题,您必须明确告诉 Nginx 使用解析器和有效指令遵守 TTL,并结合使用 proxy_pass 指令中的变量。
resolver <DNS_IP_ADDRESS> valid=10s;
upstream channels-backend {
server marketplace-service.local:8000;
}
server {
listen 80;
location / {
set $backend "http://channels-backend";
proxy_pass $backend;
}
}
根据你的DNS服务器IP替换
我不确定第三个选项,但我认为它应该可行。
如果您的位置块操纵 URI(例如重写),请考虑使用 map 而不是 set。我遇到了类似的问题,地图是唯一对我有用的解决方案。
# When specifying multiple servers, they are queried in the order
# they appear in the directive
resolver 10.0.0.2 169.254.169.253 127.0.0.11 valid=10s;
upstream channels-backend {
server marketplace-service.local:8000;
}
map $request_uri $backend {
hostnames;
default http://channels-backend;
}
server {
listen 80;
location ~ ^/api/ {
rewrite ^/api/(.*) /$1 break;
proxy_pass $backend;
}
}