當 AWS 的 ELB/ALB 被 Nginx 代理後的動態 IP 問題

2017-06-13 AWS, Nginx

這幾天把一個在 On-Premises 的專案移上 AWS,遇到了一個 Nginx 去 proxy_pass ELB/ALB 的問題,由於一些狀況導致必須從 On-Premises 的環境當入口,再做 Load balancer 的 CBR context path 導上 AWS 的 ELB

 

OK,一開始整個很順利的就導上去,用 Nginx 去 proxy_pass ELB,但是必須重申一點,AWS 所有的 IP 都是動態的,AWS 並不保證 IP 不會變動!

 

這下好了,當 ELB 增加的時候還沒問題,當他 Autoscaling 開始砍 eni 的時候 Nginx 的 proxy_pass 就掛了,這時會發現 Nginx 還在 access 舊的 ELB IP,並沒有隨著 ELB 的 domain name 的 A record 改變而動態更動。

 

先說 AWS ELB/ALB、Nginx 各自的狀況

  • AWS ELB/ALB
    • 實際上 ELB 是跑在 EC2 上的,會在你選擇的 subnet 都起一台 EC2,然後跑 Autoscaling 來支撐流量,而在 ELB 上你會拿到一個 A record,IP 就是 ELB 起在 subnet 的 EC2,而這個 domain 的 TTL 是 60 秒,也就是如果 ELB Autoscaling 增減 eni 的話 60 秒就會更新一次 A record。
  • Nginx
    • Nginx 在 config 內如果有設定 domain 的話在 start 讀取設定檔後就會去 Query IP 後 cache 起來,直到下次 config reload 後才會再次查詢 domain

 

從上面兩者的狀況來看,可以發現 ELB 是動態 DNS,但 Nginx 是靜態 DNS (cache),這樣搭配的組合就是 .. 死。

 

先講優雅(有錢人)的解法,就是買 Nginx Plus,你必須要付  $1.500,1 台/年 instance,你就可以很優雅的在 server {} 裡面加入 resolve 來指定 dns,resolver 會按照 dns server 的 TTL 來做更新。

 

然後也有土砲(免費)的解法,

server {
...
  resolver 172.16.0.23;
  set $upstream_endpoint http://service-1234567890.us-east-1.elb.amazonaws.com;
  location / {
    proxy_pass $upstream_endpoint;
  }
...
}

 

利用 Nginx 在 proxy_pass 裡面提到的一段:

Parameter value can contain variables. In this case, if an address is specified as a domain name, the name is searched among the described server groups, and, if not found, is determined using a resolver.

所以用 set 寫成變數後,他就會使用 resolver,所以也必須指定 resolver 的 dns server

 

 

 

Ref:

Nginx with dynamic upstreams

AWS 的 ELB 與 Nginx 的愛恨糾葛

給 Mr. 沙先生一點建議

彙整

分類

展開全部 | 收合全部

License

訂閱 Mr. 沙先生 的文章

輸入你的 email 用於訂閱