Skip to main content
This page documents all Service manifests used in the exchange platform. Services provide stable network endpoints for accessing Pods, enabling service discovery and load balancing.

Backend Router Service

Exposes the backend router deployment for internal cluster access. Location: backend/deployment.yml
apiVersion: v1
kind: Service
metadata:
  name: exchange-router-service
spec:
  selector:
    app: exchange-router
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP
Configuration:
  • Type: ClusterIP - Internal cluster access only
  • Selector: Routes to pods with label app: exchange-router
  • Port Mapping: Service port 80 → Container port 8080
  • Protocol: TCP
  • Access: Available at exchange-router-service.default.svc.cluster.local:80

WebSocket Stream Service

Provides internal access to the WebSocket streaming service. Location: websocket/deployment.yml
apiVersion: v1
kind: Service
metadata:
  name: exchange-ws-stream-service
spec:
  selector:
    app: exchange-ws-stream
  ports:
    - protocol: TCP
      port: 80
      targetPort: 4000
  type: ClusterIP
Configuration:
  • Type: ClusterIP - Internal cluster access only
  • Selector: Routes to pods with label app: exchange-ws-stream
  • Port Mapping: Service port 80 → Container port 4000
  • Protocol: TCP (WebSocket over HTTP)
  • Access: Available at exchange-ws-stream-service.default.svc.cluster.local:80

PostgreSQL Database Service

Provides internal database connectivity for all services. Location: postgres-db/deployment.yml
apiVersion: v1
kind: Service
metadata:
  name: exchange-postgres-service
spec:
  selector:
    app: exchange-postgres
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5432
  type: ClusterIP
Configuration:
  • Type: ClusterIP - Internal cluster access only
  • Selector: Routes to pods with label app: exchange-postgres
  • Port Mapping: Service port 80 → Container port 5432 (PostgreSQL)
  • Protocol: TCP
  • Access: Available at exchange-postgres-service.default.svc.cluster.local:80
  • Note: Port 80 is mapped to PostgreSQL’s standard 5432 port

Redis Service

Provides internal access to Redis for caching and pub/sub. Location: redis/deployment.yml
apiVersion: v1
kind: Service
metadata:
  name: exchange-redis-service
spec:
  selector:
    app: exchange-redis
  ports:
    - protocol: TCP
      port: 80
      targetPort: 6379
  type: ClusterIP
Configuration:
  • Type: ClusterIP - Internal cluster access only
  • Selector: Routes to pods with label app: exchange-redis
  • Port Mapping: Service port 80 → Container port 6379 (Redis)
  • Protocol: TCP
  • Access: Available at exchange-redis-service.default.svc.cluster.local:80
  • Note: Port 80 is mapped to Redis’s standard 6379 port

Service Types

The exchange platform uses two Kubernetes service types:

ClusterIP (Current Architecture)

All services currently use ClusterIP:
type: ClusterIP
Characteristics:
  • Internal cluster access only
  • Default service type
  • Not accessible from outside the cluster
  • Assigned a cluster-internal IP address
  • Most secure option for internal services
When to Use:
  • Backend services that don’t need external access
  • Database and cache services
  • Internal APIs and microservices
  • Services accessed only through Ingress

LoadBalancer (Alternative)

For external access without Ingress:
type: LoadBalancer
Characteristics:
  • Creates a cloud provider load balancer
  • Assigns external IP address
  • Routes external traffic to service
  • Higher cost (per service)
When to Use:
  • Services needing direct external access
  • Non-HTTP protocols
  • When Ingress is not suitable
  • Development/testing environments
Example LoadBalancer Service:
apiVersion: v1
kind: Service
metadata:
  name: exchange-router-external
spec:
  selector:
    app: exchange-router
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

Service Discovery

DNS-Based Discovery

Kubernetes automatically creates DNS records for all services: Service DNS Format:
<service-name>.<namespace>.svc.cluster.local
Examples:
# Full DNS name
exchange-router-service.default.svc.cluster.local

# Short name (within same namespace)
exchange-router-service

# With port
exchange-router-service.default.svc.cluster.local:80

Connection Strings

Services use DNS names in connection strings: Database Connection:
postgresql://user:password@exchange-postgres-service:80/exchange
Redis Connection:
redis://exchange-redis-service:80
HTTP Service:
http://exchange-router-service:80/api/v1/orders

Environment Variables

Kubernetes also injects service information as environment variables:
EXCHANGE_ROUTER_SERVICE_HOST=10.96.1.5
EXCHANGE_ROUTER_SERVICE_PORT=80

Service Networking

Port Mapping Strategy

All services use a consistent port mapping:
ports:
  - protocol: TCP
    port: 80          # Service port (external to service)
    targetPort: XXXX  # Container port (internal to pod)
Service Ports (all services): 80 Target Ports (by service):
  • Backend Router: 8080
  • WebSocket Stream: 4000
  • PostgreSQL: 5432
  • Redis: 6379
Benefits:
  • Standardized service port (80) for all services
  • Ingress can route to all services on port 80
  • Target ports match application defaults
  • Clear separation between service and pod networking

Load Balancing

Services provide automatic load balancing:
selector:
  app: exchange-router
How It Works:
  1. Service selects all pods matching the label
  2. Traffic is distributed across healthy pods
  3. Round-robin load balancing by default
  4. Unhealthy pods are automatically removed
Example with Multiple Replicas:
Pod 1 (10.244.1.5:8080) ←
Pod 2 (10.244.2.3:8080) ← Service (10.96.1.5:80)
Pod 3 (10.244.3.7:8080) ←

Service Access Patterns

Internal Service Communication

Services communicate using DNS names: Backend → Database:
const client = new Pool({
  host: 'exchange-postgres-service',
  port: 80,
  database: 'exchange'
});
Engine → Redis:
const redis = new Redis({
  host: 'exchange-redis-service',
  port: 80
});

External Access via Ingress

External traffic flows through Ingress:
Internet → Ingress (exchange.jogeshwar.xyz)

  ├─ /backend/* → exchange-router-service:80
  └─ /ws        → exchange-ws-stream-service:80

Service Operations

View Services

# List all services
kubectl get services

# Detailed service info
kubectl describe service exchange-router-service

# Get service endpoints (pod IPs)
kubectl get endpoints exchange-router-service

Test Service Connectivity

# From within cluster (debug pod)
kubectl run -it --rm debug --image=busybox --restart=Never -- sh
wget -O- http://exchange-router-service:80/health

# Port forward to local machine
kubectl port-forward service/exchange-router-service 8080:80
curl http://localhost:8080/health

Monitor Service Traffic

# Watch endpoints update
kubectl get endpoints -w

# Check service events
kubectl get events --field-selector involvedObject.name=exchange-router-service

Service Configuration Examples

Multi-Port Service

Expose multiple ports from the same service:
apiVersion: v1
kind: Service
metadata:
  name: exchange-router-service
spec:
  selector:
    app: exchange-router
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
    - name: metrics
      protocol: TCP
      port: 9090
      targetPort: 9090
  type: ClusterIP

Headless Service

Direct pod access without load balancing:
apiVersion: v1
kind: Service
metadata:
  name: exchange-postgres-headless
spec:
  clusterIP: None
  selector:
    app: exchange-postgres
  ports:
    - port: 5432
      targetPort: 5432

Session Affinity

Sticky sessions for stateful applications:
apiVersion: v1
kind: Service
metadata:
  name: exchange-router-service
spec:
  selector:
    app: exchange-router
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  ports:
    - port: 80
      targetPort: 8080

Best Practices

  1. Use ClusterIP by Default: Only expose services externally when necessary
  2. Consistent Port Mapping: Standardize service ports across your platform
  3. Named Ports: Use port names for multi-port services
  4. DNS Names: Use service DNS names instead of IP addresses
  5. Health Checks: Configure readinessProbes on pods for automatic health-based routing
  6. Labels: Use consistent label selectors matching your deployments
  7. Namespaces: Use service DNS with namespace for cross-namespace communication

Troubleshooting

Service Not Routing Traffic

# Check if service has endpoints
kubectl get endpoints exchange-router-service

# Verify pod labels match service selector
kubectl get pods -l app=exchange-router

# Check pod readiness
kubectl get pods -l app=exchange-router -o wide

DNS Resolution Issues

# Test DNS from pod
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup exchange-router-service

# Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns

Connection Timeouts

# Verify target port matches container port
kubectl get service exchange-router-service -o yaml
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].ports}'

# Test connectivity to pod directly
kubectl port-forward pod/<pod-name> 8080:8080

Build docs developers (and LLMs) love