Service Discovery and DNS

Back

Loading concept...

Kubernetes Service Discovery and DNS: The Phone Book of Your Cluster 📞

Imagine you just moved to a giant apartment building with thousands of people. How do you find your friend’s apartment? You don’t memorize every room number—you just look them up in the building directory!

In Kubernetes, Service Discovery and DNS is exactly that directory. Your apps (Pods) don’t need to remember where other apps live. They just ask the directory, and it tells them!


The Big Picture: Why Do We Need This?

Think about it:

  • Pods come and go like people moving in and out of apartments
  • Each Pod gets a new address (IP) when it starts
  • How can apps find each other if addresses keep changing?

Answer: We give apps a permanent name instead of a changing address. DNS translates that name into the current address. Simple!

graph TD A["Your App"] -->|"Hey, where is database?"| B["DNS / CoreDNS"] B -->|"It's at 10.96.45.12!"| A A -->|Connects| C["Database Pod"]

1. Service Discovery and DNS: The Basics

What is Service Discovery?

Service Discovery = Finding other apps automatically without hardcoding addresses.

Real-life example:

  • You want pizza 🍕
  • You don’t memorize the pizza shop’s phone number
  • You search “pizza near me” and get the number
  • That’s service discovery!

In Kubernetes:

# Your app just uses the name
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: myapp
    env:
    - name: DB_HOST
      value: "my-database"  # Name, not IP!

When your app connects to my-database, Kubernetes DNS automatically finds the right Pod!

How DNS Works in Kubernetes

Every Service gets a DNS name automatically:

<service-name>.<namespace>.svc.cluster.local

Example:

  • Service name: my-database
  • Namespace: production
  • Full DNS name: my-database.production.svc.cluster.local

Shortcut: If you’re in the same namespace, just use my-database!


2. CoreDNS Configuration: The Brain Behind DNS

What is CoreDNS?

CoreDNS is the phone operator of your cluster. It answers all DNS questions.

graph TD A["Pod asks: Where is my-service?"] --> B["CoreDNS"] B --> C["Looks up Service IP"] C --> D["Returns: 10.96.45.12"] D --> A

The Corefile: CoreDNS Settings

CoreDNS uses a config file called Corefile. Think of it as the operator’s instruction manual.

.:53 {
    errors
    health
    kubernetes cluster.local {
        pods insecure
        fallthrough in-addr.arpa
    }
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

What each part does:

Setting What it Does
errors Log errors
health Health check endpoint
kubernetes Handle cluster DNS
forward Send unknown queries outside
cache 30 Remember answers for 30 seconds
loadbalance Spread requests evenly

Customizing CoreDNS

Want to add a custom DNS entry? Edit the ConfigMap:

kubectl edit configmap coredns -n kube-system

Example: Add custom host

hosts {
    192.168.1.100 mycompany.internal
    fallthrough
}

3. DNS Policies: Who Can Ask What?

What are DNS Policies?

DNS Policy controls how a Pod finds DNS servers. It’s like choosing which phone book to use.

The Four DNS Policies

graph TD A["DNS Policies"] --> B["Default"] A --> C["ClusterFirst"] A --> D["ClusterFirstWithHostNet"] A --> E["None"]

1. ClusterFirst (Most Common)

  • First ask CoreDNS
  • If not found, ask outside DNS
  • Best for most apps
apiVersion: v1
kind: Pod
spec:
  dnsPolicy: ClusterFirst  # Default!

2. Default

  • Use the node’s DNS settings
  • Skips cluster DNS entirely

3. ClusterFirstWithHostNet

  • For Pods using host network
  • Still uses cluster DNS first

4. None

  • You provide ALL DNS settings
  • Maximum control
apiVersion: v1
kind: Pod
spec:
  dnsPolicy: None
  dnsConfig:
    nameservers:
      - 8.8.8.8
    searches:
      - my.dns.search

4. DNS Record Generation: Automatic Name Tags

How Kubernetes Creates DNS Records

Every time you create a Service, Kubernetes automatically creates DNS records. Magic! ✨

Types of DNS Records

A Records (Address Records)

  • Maps name → IP address
  • my-service.default.svc.cluster.local → 10.96.45.12

SRV Records (Service Records)

  • Maps name → port + protocol
  • _http._tcp.my-service.default.svc.cluster.local
# Service with named port
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - name: http    # This name matters!
    port: 80

SRV record created:

_http._tcp.my-service.default.svc.cluster.local
→ 0 0 80 my-service.default.svc.cluster.local

Headless Services: Direct Pod Names

Normal Service → One IP for all Pods Headless Service → Each Pod gets its own DNS name!

apiVersion: v1
kind: Service
metadata:
  name: my-headless
spec:
  clusterIP: None  # Makes it headless!
  selector:
    app: myapp

DNS records for headless:

pod-name.my-headless.namespace.svc.cluster.local

Perfect for databases where you need specific Pods!


5. Endpoints and EndpointSlices: The Address Book

What are Endpoints?

Endpoints are the actual addresses behind a Service. When you create a Service, Kubernetes creates Endpoints automatically.

graph TD A["Service: my-app"] --> B["Endpoints"] B --> C["Pod 1: 10.1.1.5"] B --> D["Pod 2: 10.1.1.6"] B --> E["Pod 3: 10.1.1.7"]

View Endpoints:

kubectl get endpoints my-service

Output:

NAME         ENDPOINTS
my-service   10.1.1.5:80,10.1.1.6:80,10.1.1.7:80

EndpointSlices: The Better Address Book

Problem: With thousands of Pods, one Endpoints object gets HUGE!

Solution: EndpointSlices break it into smaller chunks (max 100 addresses each).

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: my-service-abc12
  labels:
    kubernetes.io/service-name: my-service
endpoints:
- addresses:
  - "10.1.1.5"
  conditions:
    ready: true

Benefits of EndpointSlices:

  • Smaller updates (only changed slice)
  • Faster propagation
  • Less memory usage
  • Scales to thousands of Pods

6. Service Topology and Routing: Smart Traffic Direction

What is Service Topology?

Instead of sending traffic anywhere, topology-aware routing sends it to the closest Pod. Like choosing the pizza shop nearest to you!

Topology Keys (Deprecated but Good to Know)

apiVersion: v1
kind: Service
spec:
  topologyKeys:
  - "kubernetes.io/hostname"    # Same node first
  - "topology.kubernetes.io/zone"  # Same zone next
  - "*"                         # Anywhere as fallback

Topology Aware Hints (The New Way!)

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.kubernetes.io/topology-mode: Auto
spec:
  selector:
    app: myapp

How it works:

graph TD A["Request from Zone-A"] --> B{Topology Check} B -->|Has Pod in Zone-A?| C["Route to Zone-A Pod"] B -->|No Pod in Zone-A| D["Route to any Zone"]

Benefits:

  • Lower latency (closer = faster)
  • Reduced network costs
  • Better performance

Internal vs External Traffic Policy

Internal Traffic Policy:

spec:
  internalTrafficPolicy: Local  # Only same-node Pods

External Traffic Policy:

spec:
  externalTrafficPolicy: Local  # Preserve client IP

7. Load Balancer Configuration: Sharing the Work

What is a LoadBalancer Service?

It’s a Service that gets a real, external IP from your cloud provider. Anyone on the internet can reach it!

apiVersion: v1
kind: Service
metadata:
  name: my-public-app
spec:
  type: LoadBalancer
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 8080

Load Balancer Annotations

Each cloud provider has special settings:

AWS:

metadata:
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-internal: "true"

GCP:

metadata:
  annotations:
    cloud.google.com/load-balancer-type: Internal

Azure:

metadata:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"

Health Checks

Load balancers need to know if Pods are healthy:

spec:
  ports:
  - port: 80
    targetPort: 8080
  healthCheckNodePort: 30000  # For externalTrafficPolicy: Local

Load Balancer IP

Want a specific IP? Request it!

spec:
  type: LoadBalancer
  loadBalancerIP: 203.0.113.10  # Your static IP

Putting It All Together: A Complete Example

Let’s create a web app with database, using everything we learned:

# Database Service (Headless for StatefulSet)
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  clusterIP: None
  selector:
    app: postgres
  ports:
  - port: 5432
---
# Web App Service (Internal)
apiVersion: v1
kind: Service
metadata:
  name: webapp
  annotations:
    service.kubernetes.io/topology-mode: Auto
spec:
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 8080
---
# Public LoadBalancer
apiVersion: v1
kind: Service
metadata:
  name: webapp-public
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: webapp
  ports:
  - port: 443
    targetPort: 8080

What happens:

  1. Web app connects to postgres (DNS resolves it)
  2. Internal traffic uses topology hints (fast!)
  3. External users hit the LoadBalancer
  4. Client IPs are preserved

Quick Reference: DNS Name Formats

What DNS Name
Service <svc>.<ns>.svc.cluster.local
Pod (headless) <pod>.<svc>.<ns>.svc.cluster.local
SRV record _<port>._<proto>.<svc>.<ns>.svc.cluster.local

You Did It! 🎉

You now understand:

  • âś… How Pods find each other (Service Discovery)
  • âś… CoreDNS as the cluster’s phone operator
  • âś… DNS Policies for different needs
  • âś… Automatic DNS record creation
  • âś… Endpoints and EndpointSlices
  • âś… Smart routing with topology
  • âś… LoadBalancer configuration

Remember: In Kubernetes, use names, not IPs. Let DNS do the hard work!


Next: Practice what you learned in the Interactive Lab!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.