Nginx cache pitfalls

Nginx cache pitfalls

社内LT用に作成した資料です。NginxのDNS cacheにはまった話をしました

164fd510e92a1912155b869b2c333c1e?s=128

Tsuji Daishiro

December 04, 2019
Tweet

Transcript

  1. Nginxのcacheにはまった話 2019/12/4(Wed) mornIngTalk #4 Future Architect Tsuji Daishiro

  2. 構成の概要 ✓ Nginxはリバースプロキシ ✓ クライアントアプリからNginxを経由してバックエンドのHerokuアプリのAPIにアクセス 2

  3. nginx.conf ✓ nginx.confの一部 ✓ よくあるupstreamを使ったconfig 3 http { upstream backend

    { server sample.herokuapp.com:443; } server { location /hoge { proxy_pass https://backend; proxy_set_header Host sample.herokuapp.com; proxy_redirect off; } } } nginx.conf
  4. 事象 4

  5. 問題の事象 ✓ たまに404のNot Foundがレスポンスとして返ってくる ✓ 観測すると10回に1回程度の頻度 ✓ 通常は “OK” などの文字列が返ってくる

    5 404としてレスポンスが返ってきたときのBodyのHTMLの一例
  6. 原因 6

  7. 原因 ✓ NginxのDNSのcacheの仕様によるものだった ✓ https://www.nginx.com/blog/dns-service-discovery-nginx-plus/ 7 As NGINX starts up

    or reloads its configuration, it queries a DNS server to resolve backends.example.com. The DNS server returns the list of three backends discussed above, and NGINX uses the default Round Robin algorithm to load balance requests among them. NGINX chooses the DNS server from the OS configuration file /etc/resolv.conf. This method is the least flexible way to do service discovery and has the following additional drawbacks: • If the domain name can’t be resolved, NGINX fails to start or reload its configuration. • NGINX caches the DNS records until the next restart or configuration reload, ignoring the records’ TTL values. • We can’t specify another load-balancing algorithm, nor can we configure passive health checks or other features defined by parameters to the server directive, which we’ll describe in the next section.
  8. 原因 ✓ NginxのDNSのcacheの仕様によるものだった ✓ https://www.nginx.com/blog/dns-service-discovery-nginx-plus/ 8 As NGINX starts up

    or reloads its configuration, it queries a DNS server to resolve backends.example.com. The DNS server returns the list of three backends discussed above, and NGINX uses the default Round Robin algorithm to load balance requests among them. NGINX chooses the DNS server from the OS configuration file /etc/resolv.conf. This method is the least flexible way to do service discovery and has the following additional drawbacks: • If the domain name can’t be resolved, NGINX fails to start or reload its configuration. • NGINX caches the DNS records until the next restart or configuration reload, ignoring the records’ TTL values. • We can’t specify another load-balancing algorithm, nor can we configure passive health checks or other features defined by parameters to the server directive, which we’ll describe in the next section. 再起動やリロードするまでDNSレコードをキャッシュ。TTLは無視。
  9. 問題にならないケースも ✓ DNSレコードをキャッシュしても問題にならないケースがある ✓ ドメイン名に対して、名前解決先のIPアドレスが一定の場合 9 hoge.com 192.168.1.1 192.168.1.2 固定のIPアドレスに紐づく場合など

  10. 今回のケース ✓ バックエンドのサービスがHeroku ✓ SaaS ✓ デプロイしたサービスに紐づくドメインのグローバルIPが都度変わる $ nslookup sample.herokuapp.com

    ✓ Internalの通信にALBをはさむ場合も同様 10 あるタイミングで名前解決したDNSレコードが有効とは限らない
  11. 何が起こっていたか ✓ デプロイしたサービスとは別のサービスと通信していると判断 ✓ グローバルIPの割り当て方法について、サポートから明確な回答は得られず。 11 sample.heroku.com → x.x.x.x x.x.x.x

    のIPアドレスは自分たちのサービスに割り当てられて おらず、別のサービスに割り当てられている。 別のサービス 自分たちのサービス 別のサービスと通信したときの404 Not Foundのレスポンス
  12. 対応策 12

  13. 対応策 ✓ 都度名前解決させる ✓ set, resolver, proxy_passを用いることで実装可能 ✓ upstreamを諦める(少し頑張ればupstreamでも実装できるよう。未確認) 13

    http { resolver 169.254.169.253 valid=0s; server { listen 80 default_server; server_name _; root /usr/share/nginx/html; location /hoge { set $url "https://sample.herokuapp.com/hoge"; proxy_pass $url; proxy_redirect off; } } } nginx.conf
  14. None