How Service Discovery works in Kubernetes?
Service discovery in Kubernetes enables microservices to locate and communicate with each other efficiently. Kubernetes automatically manages service discovery using DNS, making it a foundational aspect of microservices communication within a Kubernetes cluster. This tutorial will explore the concepts, configurations, and examples of service discovery using Kubernetes DNS.
How Service Discovery Works in Kubernetes
Kubernetes provides built-in DNS-based service discovery that ensures each service within the cluster can communicate with others using DNS names. The DNS server runs inside the cluster and maintains records for all services.
DNS-Based Service Discovery
- Automatic DNS Naming: Each service is assigned a DNS name of the format:
service-name.namespace.svc.cluster.local
.service-name
: The name of the service.namespace
: The namespace where the service resides (e.g.,default
).svc.cluster.local
: The default DNS suffix for Kubernetes services.
- Internal Communication: Services within the cluster communicate using this DNS name, allowing seamless inter-service communication.
Example Scenario: Order-Service Communicating with User-Service and Payment-Service
Imagine you have three microservices:
- Order-Service: Manages orders.
- User-Service: Manages user data.
- Payment-Service: Handles payment transactions.
Architecture Overview
Implementing Service Discovery
1. Defining User-Service
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 2
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service-image
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 80
targetPort: 8080
2. Defining Payment-Service
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-service
spec:
replicas: 2
selector:
matchLabels:
app: payment-service
template:
metadata:
labels:
app: payment-service
spec:
containers:
- name: payment-service
image: payment-service-image
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: payment-service
spec:
selector:
app: payment-service
ports:
- port: 80
targetPort: 8080
3. Defining Order-Service
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 2
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: order-service-image
ports:
- containerPort: 8080
env:
- name: USER_SERVICE_HOST
value: "user-service.default.svc.cluster.local"
- name: USER_SERVICE_PORT
value: "80"
- name: PAYMENT_SERVICE_HOST
value: "payment-service.default.svc.cluster.local"
- name: PAYMENT_SERVICE_PORT
value: "80"
---
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service
ports:
- port: 80
targetPort: 8080
How Communication is Configured
- Environment Variables: In the Order-Service deployment, environment variables specify the DNS names of the User-Service and Payment-Service.
USER_SERVICE_HOST
andPAYMENT_SERVICE_HOST
are set to the DNS names of the corresponding services.
- DNS Resolution: Kubernetes automatically resolves these DNS names to the respective service endpoints.
Workflow
- Client Places an Order:
- The client sends a request to the Order-Service.
- Order-Service Calls User-Service:
- The Order-Service uses the DNS name
user-service.default.svc.cluster.local
to access the User-Service and retrieve user details.
- The Order-Service uses the DNS name
- Order-Service Calls Payment-Service:
- After retrieving user information, Order-Service calls Payment-Service using the DNS name
payment-service.default.svc.cluster.local
to process the payment.
- After retrieving user information, Order-Service calls Payment-Service using the DNS name
- DNS Resolution:
- Kubernetes DNS resolves the service names to the corresponding service IPs, enabling communication.
DNS Configuration in Kubernetes
Automatic DNS Setup
- Kubernetes automatically configures DNS for all services created within the cluster.
- The Kube-DNS add-on or CoreDNS (the default DNS server in Kubernetes) manages DNS records, ensuring that all services can be accessed using their DNS names.
- You don’t need to manually configure DNS records for internal services.
Internal Communication Example
- In the Order-Service code, you can use the
USER_SERVICE_HOST
environment variable to make a request to the User-Service.const http = require('http'); const userServiceHost = process.env.USER_SERVICE_HOST; const userServicePort = process.env.USER_SERVICE_PORT; const options = { hostname: userServiceHost, port: userServicePort, path: '/users', method: 'GET' }; const req = http.request(options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { console.log(`User Details: ${data}`); }); }); req.on('error', (error) => { console.error(`Error connecting to User-Service: ${error.message}`); }); req.end();
Key Takeaways
- DNS-Based Service Discovery: Kubernetes uses DNS to manage service discovery, making communication between microservices seamless.
- Automatic DNS Configuration: Kubernetes automatically assigns DNS names to services, removing the need for manual configuration.
- Environment Variables: You can use environment variables to set the DNS names of services in the deployment configurations, making the communication dynamic and reliable.
- Internal Communication: Services can communicate within the cluster using these DNS names, ensuring connectivity.
FAQs
Q1: How does Kubernetes manage DNS for service discovery?
- Kubernetes runs a DNS server (e.g., CoreDNS) within the cluster that automatically assigns DNS names to services. This allows microservices to communicate using service names, which are resolved to the service IP addresses.
Q2: Do I need to configure DNS manually for service discovery?
- No, Kubernetes automatically handles DNS configuration for internal services. You only need to use the service name, namespace, and DNS suffix for communication.
Q3: What happens if a service’s IP changes?
- Kubernetes DNS dynamically updates DNS records if a service’s IP changes, ensuring consistent connectivity across the cluster.
Q4: Can services in different namespaces communicate using DNS?
- Yes, services in different namespaces can communicate using fully qualified domain names (e.g.,
user-service.other-namespace.svc.cluster.local
).
Q5: How is service discovery secured in Kubernetes?
- Kubernetes supports TLS encryption, RBAC (Role-Based Access Control), and Network Policies to secure communication between services.
Clap here if you liked the blog