Service Discovery with DNS
Introduction: Beyond Basic Service Discovery
In Unit 2, you learned that Services automatically get DNS names, allowing applications to connect using names like backend-svc instead of IP addresses. You saw how CoreDNS resolves these names to ClusterIP addresses, enabling loose coupling between your application components. But that was just the foundation.
In this lesson, you'll tackle the advanced service discovery scenarios that arise in real production environments: connecting to Services in different namespaces, integrating with external systems outside your cluster, and understanding why some IPs remain stable while others constantly change. These patterns are essential when you're building distributed systems that span multiple namespaces, hybrid cloud architectures, or migrating legacy applications into Kubernetes.
Cross-Namespace Service Access
So far, you've probably worked within a single namespace — typically default. But production Kubernetes environments use multiple namespaces to isolate different teams, applications, or environments. When your frontend Pod in the web namespace needs to connect to a backend Service in the api namespace, the simple service name won't work. Kubernetes DNS uses namespace-scoped resolution by default, so backend-svc only resolves within your current namespace. For cross-namespace access, you need to use the Fully Qualified Domain Name (FQDN).
The FQDN pattern is <service-name>.<namespace>.svc.cluster.local. If you have a Service called database-svc in the data namespace, you can access it from any namespace using database-svc.data.svc.cluster.local, or the shorter form database-svc.data. Let's see this in action with a concrete example.
First, create two namespaces to simulate a multi-tier application:
Now create a backend service in the backend namespace. Save this as deployment-backend.yaml:
Apply this configuration:
Verify the Service exists in the backend namespace:
Now let's create a Pod in the frontend namespace and try to access the backend Service. First, try using just the service name:
As expected, DNS resolution fails because api-svc doesn't exist in the frontend namespace. Now try using the FQDN:
Perfect! The FQDN api-svc.backend successfully resolves to the Service's ClusterIP. Let's verify we can actually connect:
Excellent! Your frontend Pod successfully connected to the backend Service across namespaces. This pattern is crucial for microservices architectures where you want to isolate services by namespace but still enable controlled communication between them. You can use NetworkPolicies (covered in later units) to restrict which namespaces can access which Services, implementing a zero-trust security model.
One important consideration: using FQDNs makes your configuration less portable. If you hardcode api-svc.backend in your application and later need to move the backend to a different namespace, you'll need to update your code. A better approach is to use environment variables or ConfigMaps that specify the full service address, making it easy to reconfigure without code changes.
