Here’s a clean, readable blog-style write-up based on your idea, structured exactly as **Problem → Solution → Conclusion**. --- # Dynamic DNS Resolution in NGINX on Kubernetes ## Problem Kubernetes relies heavily on DNS. Services are exposed through stable DNS names, but the IP addresses behind them can and do change as pods are rescheduled, scaled, or restarted. This is normal and expected behavior in a dynamic cluster. NGINX, however, does not naturally behave in a dynamic way when it comes to DNS. When a backend hostname is configured directly in `proxy_pass` or in an `upstream` block, NGINX resolves that hostname **once at startup** and then caches the result indefinitely. If the underlying service IP changes, NGINX keeps sending traffic to the old address, leading to failed requests and hard-to-debug outages. This mismatch between Kubernetes’ dynamic nature and NGINX’s static DNS resolution becomes especially painful for long-running NGINX pods, where configuration reloads are infrequent or undesirable. --- ## Solution To force NGINX to re-resolve DNS dynamically, the backend address must be defined using **variables**. When `proxy_pass` contains a variable, NGINX performs DNS resolution at request time instead of startup time. A typical pattern looks like this: ```nginx resolver kube-dns.kube-system.svc.cluster.local valid=10s; set $backend "my-service.default.svc.cluster.local:8080"; proxy_pass http://$backend$request_uri; ``` Using a variable ensures that NGINX consults Kubernetes DNS regularly and picks up changes to service IPs without requiring a reload. The tradeoff is that once variables are introduced, NGINX no longer allows the use of traditional `upstream` blocks. This means you must manually construct the full backend URL, including scheme, host, port, and request URI. Path rewrites, header forwarding, and protocol handling all become explicit responsibilities of the configuration author. In short: **dynamic DNS comes at the cost of more manual configuration**. --- ## Conclusion Running NGINX in Kubernetes exposes a subtle but critical DNS resolution issue. Kubernetes expects clients to adapt to changing IPs, while NGINX assumes backends are static unless told otherwise. By using variables in `proxy_pass`, NGINX can align with Kubernetes’ dynamic service model and avoid stale DNS entries. However, this approach shifts complexity into the configuration, requiring manual URL construction and careful request handling. Understanding this tradeoff is essential when running NGINX directly in Kubernetes. It explains why some setups fail unpredictably over time—and why ingress controllers and service meshes invest significant effort in abstracting this problem away. Done right, variable-based DNS resolution makes NGINX a reliable citizen in a dynamic cluster.