OpenShift Service Discovery for Microservices
Learn how Service Discovery works in OpenShift, understand Kubernetes DNS, internal networking, Spring Boot microservice communication, and enterprise service discovery patterns.
Introduction
Modern enterprise applications rarely consist of a single application. Instead, they are built using dozens or even hundreds of microservices.
For example, an online banking platform may have separate microservices for:
- Authentication
- Customer Management
- Accounts
- Payments
- Transactions
- Notifications
- Fraud Detection
These services constantly communicate with each other.
A common question is:
How does one microservice locate another inside OpenShift without knowing its IP address?
The answer is Service Discovery.
OpenShift automatically provides service discovery through Kubernetes DNS, allowing applications to communicate using stable service names instead of changing Pod IP addresses.
Learning Objectives
By the end of this article, you will understand:
- What is Service Discovery?
- Why Service Discovery is required
- Kubernetes DNS
- Internal DNS resolution
- ClusterIP Services
- Spring Boot communication
- Cross-namespace communication
- Enterprise architecture
- Best practices
Microservices Without Service Discovery
Imagine three microservices communicating directly.
flowchart LR
A[Order Service]
--> B[10.10.2.15]
B --> C[Payment Pod]
Problem:
- Pod IP changes
- Scaling breaks communication
- Failed Pods receive new IPs
Applications become unreliable.
Microservices With Service Discovery
flowchart LR
A[Order Service]
--> B[payment-service]
--> C[Payment Pods]
Applications communicate using Service names, not Pod IPs.
What is Service Discovery?
Service Discovery is the process of automatically locating services running inside a cluster.
Instead of:
http://10.20.15.18
Applications use:
http://payment-service
OpenShift automatically resolves the service name to healthy Pods.
Service Discovery Architecture
flowchart TD
Order[Order Service]
DNS[CoreDNS]
PaymentService[Payment Service]
Pod1[Payment Pod 1]
Pod2[Payment Pod 2]
Order --> DNS
DNS --> PaymentService
PaymentService --> Pod1
PaymentService --> Pod2
CoreDNS is responsible for DNS resolution inside the cluster.
Complete Request Flow
sequenceDiagram
participant Order
participant DNS
participant Service
participant Pod
participant PaymentAPI
Order->>DNS: Resolve payment-service
DNS-->>Order: Cluster IP
Order->>Service: HTTP Request
Service->>Pod: Load Balance
Pod->>PaymentAPI: Execute
PaymentAPI-->>Order: JSON Response
Kubernetes DNS
Every Service automatically receives a DNS name.
Example:
payment-service
Fully Qualified Domain Name (FQDN):
payment-service.default.svc.cluster.local
DNS is automatically maintained by OpenShift.
DNS Hierarchy
flowchart TD
Cluster
--> Namespace
Namespace
--> Service
Service
--> Pods
Internal DNS
Applications communicate internally without exposing APIs externally.
flowchart LR
ORDER["Order Service"]
DNS["payment-service.default.svc.cluster.local"]
SVC["Payment Service"]
PODS["Payment Pods"]
ORDER --> DNS
DNS --> SVC
SVC --> PODS
No Route required.
Why Not Use Pod IP?
Pod IPs are temporary.
flowchart LR
OldPod[Payment Pod]
--> IP1[10.10.5.8]
Crash[Pod Restart]
--> NewPod[Payment Pod]
--> IP2[10.10.8.15]
Service Discovery hides these changes.
ClusterIP Service
Every Service has a stable virtual IP.
flowchart LR
ORDER["Order Service"]
SERVICE["ClusterIP Service"]
subgraph APP["Payment Application"]
POD1["Payment Pod 1"]
POD2["Payment Pod 2"]
POD3["Payment Pod 3"]
end
ORDER --> SERVICE
SERVICE --> POD1
SERVICE --> POD2
SERVICE --> POD3
Applications always connect to the ClusterIP.
Banking Example
flowchart LR
API["API Gateway"]
CUSTOMER["Customer Service"]
PAYMENT["Payment Service"]
LOAN["Loan Service"]
FRAUD["Fraud Service"]
NOTIFY["Notification Service"]
API --> CUSTOMER
API --> PAYMENT
API --> LOAN
PAYMENT --> FRAUD
PAYMENT --> NOTIFY
Each service communicates using DNS names.
Spring Boot Example
Payment Service URL
payment.service.url=http://payment-service
Order Service
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/orders")
public String placeOrder() {
return restTemplate.getForObject(
"http://payment-service/api/pay",
String.class);
}
}
No IP addresses are required.
Using Spring WebClient
WebClient.builder()
.baseUrl("http://payment-service")
.build();
WebClient works seamlessly with OpenShift DNS.
Multi-Service Architecture
flowchart LR
BROWSER["Browser"]
ROUTE["OpenShift Route"]
GATEWAY["API Gateway"]
CUSTOMER["Customer Service"]
ORDER["Order Service"]
PAYMENT["Payment Service"]
INVENTORY["Inventory Service"]
FRAUD["Fraud Service"]
BROWSER --> ROUTE
ROUTE --> GATEWAY
GATEWAY --> CUSTOMER
GATEWAY --> ORDER
GATEWAY --> PAYMENT
ORDER --> INVENTORY
PAYMENT --> FRAUD
Only the API Gateway is exposed externally.
Cross-Namespace Communication
Suppose:
Payment Service
Namespace:
payments
Order Service
Namespace:
orders
Use:
payment-service.payments.svc.cluster.local
instead of:
payment-service
Cross-Namespace Architecture
flowchart LR
ORDERS["Orders Namespace"]
DNS["payment-service.payments.svc.cluster.local"]
PAYMENTS["Payments Namespace"]
PODS["Payment Pods"]
ORDERS --> DNS
DNS --> PAYMENTS
PAYMENTS --> PODS
Verify DNS
Open terminal:
oc rsh payment-pod
Test DNS:
nslookup payment-service
or
curl http://payment-service
List Services
oc get svc
Example:
payment-service
customer-service
loan-service
Service Endpoints
oc get endpoints
Output:
payment-service
10.10.1.4
10.10.1.5
10.10.1.8
Scaling Example
Before Scaling
flowchart LR
Service
--> Pod1
Service
--> Pod2
After Scaling
flowchart LR
Service
--> Pod1
Service
--> Pod2
Service
--> Pod3
Service
--> Pod4
Service
--> Pod5
Applications continue using the same DNS name.
Service Discovery During Deployment
flowchart LR
ORDER["Order Service"]
DNS["payment-service"]
OLD["Old Pods"]
NEW["New Pods"]
ORDER --> DNS
DNS --> OLD
DNS --> NEW
Rolling deployments happen transparently.
Enterprise Banking Architecture
flowchart TD
CUSTOMER["Customer"]
ROUTE["OpenShift Route"]
API["API Gateway"]
AUTH["Authentication Service"]
ACCOUNT["Account Service"]
PAYMENT["Payment Service"]
FRAUD["Fraud Detection"]
ORACLE[("Oracle Database")]
KAFKA[("Kafka")]
NOTIFY["Notification Service"]
CUSTOMER --> ROUTE
ROUTE --> API
API --> AUTH
API --> ACCOUNT
API --> PAYMENT
PAYMENT --> FRAUD
FRAUD --> ORACLE
PAYMENT --> KAFKA
KAFKA --> NOTIFY
Every service communicates using internal DNS.
Common Problems
Service Not Found
Verify:
oc get svc
DNS Resolution Failed
Verify:
nslookup payment-service
No Endpoints
oc get endpoints
If empty:
- Labels mismatch
- Pods not running
Connection Refused
Check:
- Service Port
- Target Port
- Spring Boot server.port
Best Practices
- Never use Pod IPs.
- Always communicate using Service names.
- Expose only API Gateway externally.
- Keep backend services internal.
- Use ClusterIP for microservices.
- Use FQDN for cross-namespace communication.
- Monitor DNS resolution.
- Configure health probes.
Common Mistakes
❌ Hardcoding Pod IPs.
❌ Exposing every microservice.
❌ Using NodePort internally.
❌ Forgetting namespace names.
❌ Calling Pods directly.
Advantages
- Automatic discovery
- Stable networking
- Dynamic scaling
- Built-in DNS
- High availability
- Zero configuration
- Better resilience
- Enterprise ready
Summary
Service Discovery is one of the core capabilities that enables microservices to communicate reliably inside OpenShift.
Key takeaways:
- OpenShift automatically provides DNS-based Service Discovery.
- Applications communicate using Service names instead of Pod IP addresses.
- ClusterIP Services provide stable endpoints while Pods can scale or restart transparently.
- CoreDNS resolves service names within the cluster.
- Cross-namespace communication uses fully qualified domain names (FQDNs).
- Service Discovery enables scalable, resilient, and loosely coupled Spring Boot microservices.
Interview Questions
- What is Service Discovery?
- Why shouldn't applications use Pod IP addresses?
- What is CoreDNS?
- What is the default Service type used for Service Discovery?
- How does OpenShift resolve service names?
- What is the FQDN format of a Service?
- How do microservices communicate across namespaces?
- What happens to Service Discovery when Pods are scaled?
- How do you verify Service endpoints?
- Why is Service Discovery essential in microservice architectures?