Nginx内部DNS解决问题 [英] Nginx internal dns resolve issue
问题描述
我在AWS中有nginx容器,该容器确实为我的网站提供反向代理,例如 https://example.com .我拥有自动在本地DNS中注册的后端服务-aws.local(由AWS ECS自动发现完成). 我的问题是nginx仅在启动期间将名称解析为IP,因此当服务容器重新启动并获取新IP时,nginx仍尝试使用旧IP,并且出现"502 Bad Gateway"错误.
I have nginx container in AWS that does reverse proxy for my website e.g. https://example.com. I have backend services that automatically register in local DNS - aws.local (this is done by AWS ECS Auto-Discovery). The problem I have is that nginx is only resolving name to IP during start, so when service container is rebooted and gets new IP, nginx still tries old IP and I have "502 Bad Gateway" error.
这是我正在运行的代码:
Here is a code that I am running:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
include /etc/nginx/mime.types;
log_format graylog2_json '{ "timestamp": "$time_iso8601", '
'"remote_addr": "$remote_addr", '
'"body_bytes_sent": $body_bytes_sent, '
'"request_time": $request_time, '
'"response_status": $status, '
'"request": "$request", '
'"request_method": "$request_method", '
'"host": "$host",'
'"upstream_cache_status": "$upstream_cache_status",'
'"upstream_addr": "$upstream_addr",'
'"http_x_forwarded_for": "$http_x_forwarded_for",'
'"http_referrer": "$http_referer", '
'"http_user_agent": "$http_user_agent" }';
upstream service1 {
server service1.aws.local:8070;
}
upstream service2 {
server service2.aws.local:8080;
}
resolver 10.0.0.2 valid=10s;
server {
listen 443 http2 ssl;
server_name example.com;
location /main {
proxy_pass http://service1;
}
location /auth {
proxy_pass http://service2;
}
我找到一些建议来更改nginx配置以解析每个请求的名称,但是随后我发现我的浏览器尝试打开"service2.aws.local:8070",但由于其AWS本地DNS名称而失败.我应该在浏览器上看到 https://example.com/auth .
I find advices to change nginx config to resolve names per request, but then I see my browser tries to open "service2.aws.local:8070" and fails since its AWS local DNS name. I should see https://example.com/auth" on my browser.
server {
set $main service1.aws.local:2000;
set $auth service2.aws.local:8070;
location /main {
proxy_http_version 1.1;
proxy_pass http://$main;
}
location /auth {
proxy_http_version 1.1;
proxy_pass http://$auth;
}
您能帮我修复它吗? 谢谢!!!
Can you help me fixing it? Thanks !!!
推荐答案
我找到了解决此问题的完美方法. Nginx的"proxy_pass"不能使用"etc/hosts"信息.
I found perfectly solution of this issue. Nginx "proxy_pass" can't use "etc/hosts" information.
我建议您在ECS中使用HA-Proxy反向代理. 我尝试了nginx反向代理,但失败了. HA-Proxy并获得成功. 它比nginx配置更简单.
I wanna sugguest you use HA-Proxy reverse proxy in ECS. I tried nginx reverse proxy, but failed. And success with HA-Proxy. It is more simple than nginx configuration.
首先,使用Docker的链接"选项并设置环境变量"(例如LINK_APP,LINK_PORT).
First, use "links" option of Docker and setting "environment variables" (eg. LINK_APP, LINK_PORT).
第二,将此环境变量"填充到haproxy.cfg中.
Second, fill this "environment variables" into haproxy.cfg.
此外,我建议您使用动态端口映射"到ALB.它使作品更加灵活.
Also, I recommend you use "dynamic port mapping" to ALB. it makes more flexible works.
taskdef.json:
taskdef.json :
# taskdef.json
{
"executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<APP_NAME>_ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "<APP_NAME>-rp",
"image": "gnokoheat/ecs-reverse-proxy:latest",
"essential": true,
"memoryReservation": <MEMORY_RESV>,
"portMappings": [
{
"hostPort": 0,
"containerPort": 80,
"protocol": "tcp"
}
],
"links": [
"<APP_NAME>"
],
"environment": [
{
"name": "LINK_PORT",
"value": "<SERVICE_PORT>"
},
{
"name": "LINK_APP",
"value": "<APP_NAME>"
}
]
},
{
"name": "<APP_NAME>",
"image": "<IMAGE_NAME>",
"essential": true,
"memoryReservation": <MEMORY_RESV>,
"portMappings": [
{
"protocol": "tcp",
"containerPort": <SERVICE_PORT>
}
],
"environment": [
{
"name": "PORT",
"value": "<SERVICE_PORT>"
},
{
"name": "APP_NAME",
"value": "<APP_NAME>"
}
]
}
],
"requiresCompatibilities": [
"EC2"
],
"networkMode": "bridge",
"family": "<APP_NAME>"
}
haproxy.cfg:
haproxy.cfg :
# haproxy.cfg
global
daemon
pidfile /var/run/haproxy.pid
defaults
log global
mode http
retries 3
timeout connect 5000
timeout client 50000
timeout server 50000
frontend http
bind *:80
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
compression algo gzip
compression type text/css text/javascript text/plain application/json application/xml
default_backend app
backend app
server static "${LINK_APP}":"${LINK_PORT}"
Dockerfile(haproxy):
Dockerfile(haproxy) :
FROM haproxy:1.7
USER root
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
请参阅:
Github: https://github.com/gnokoheat/ecs-reverse-proxy
Docker镜像:gnokoheat/ecs-reverse-proxy:latest
Docker image : gnokoheat/ecs-reverse-proxy:latest
这篇关于Nginx内部DNS解决问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!