Kahibaro
Discord Login Register

8.1 Services and service discovery

Understanding Services in OpenShift

In OpenShift, Services provide stable, virtual endpoints for accessing groups of pods. Pods are ephemeral and their IPs change; Services give you a consistent name and IP to reach them, and form the basis of in-cluster service discovery.

At a high level, a Service:

OpenShift builds on standard Kubernetes Services; everything here applies to Kubernetes, with a few OpenShift-specific details and defaults.

Core Service Types

ClusterIP (default)

Example:

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  selector:
    app: myapp
    tier: frontend
  ports:
    - port: 80          # Service port
      targetPort: 8080  # Pod containerPort
      protocol: TCP
  type: ClusterIP

Key points:

NodePort

Basic example:

spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080

LoadBalancer

spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080

The Service gets an external IP or hostname from the infrastructure, and traffic is distributed to the backing pods.

ExternalName

apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.example.com

Inside the namespace, accessing external-db is equivalent to using db.example.com.

Service Selectors and Endpoints

Services select pods using spec.selector. This label-based selection is how OpenShift decouples application identity from specific pod instances.

Example:

spec:
  selector:
    app: payments
    role: api

Any pod with labels app=payments and role=api becomes a backend for this Service.

When a Service has a selector:

You can inspect endpoints:

oc get endpoints frontend

If you omit selector, you can manually define endpoints. This is less common but useful for services that point to:

Example Service without selector:


apiVersion: v1
kind: Service
metadata:
  name: legacy-backend
spec:
  ports:
    - port: 5432
      protocol: TCP
apiVersion: v1
kind: Endpoints
metadata:
  name: legacy-backend
subsets:
  - addresses:
      - ip: 10.0.0.10
      - ip: 10.0.0.11
    ports:
      - port: 5432

Service Ports and Target Ports

The port mapping in a Service is important for clean separation between client-facing and container-facing ports.

Fields:

Named targetPort:

You can use container port names instead of numbers, which is useful when containers expose multiple ports:


containers:
  - name: web
    image: myimage
    ports:
      - name: http
        containerPort: 8080
      - name: metrics
        containerPort: 9090
kind: Service
spec:
  selector:
    app: myapp
  ports:
    - name: web
      port: 80
      targetPort: http
    - name: metrics
      port: 9100
      targetPort: metrics

Using names makes your Service configuration independent of exact port numbers inside the containers.

Service Discovery in OpenShift

Service discovery is how applications locate and communicate with other services inside the cluster. In OpenShift, this is primarily handled via cluster DNS.

DNS Names for Services

OpenShift deploys a DNS server that automatically creates DNS entries for Services and pods.

A typical Service DNS name within a namespace looks like:

Examples:

Applications usually only need the short name if they communicate within the same namespace.

Service Discovery via Environment Variables

When a pod starts, Kubernetes injects environment variables for existing Services in its namespace. For a Service frontend on port 80, you might see:

This mechanism:

DNS-based discovery is preferred because it is dynamic and does not require pod restarts when Services change.

Discovering Services from an Application

Common patterns from inside a pod:

Languages and frameworks often have built-in DNS resolution, so using Service names directly is typically straightforward.

Headless Services and Stateful Service Discovery

Headless Services are a special type of Service that do not get a cluster IP. Instead, DNS returns the IPs of individual pods directly.

Configuration:

apiVersion: v1
kind: Service
metadata:
  name: db-headless
spec:
  clusterIP: None
  selector:
    app: db
  ports:
    - port: 5432

Behavior:

This is crucial for applications that require:

You will encounter headless Services mainly when working with stateful or clustered applications.

Service Traffic Routing and Load Balancing (Conceptual Level)

Without going into the networking implementation details:

Key behaviors to understand:

For HTTP-based apps, you often combine:

Services and Namespaces

Services are namespaced resources:

Cross-namespace access uses fully qualified names:

Best practices:

Practical Workflow with Services in OpenShift

Typical steps to expose an internal application:

  1. Deploy an application (e.g., Deployment, DeploymentConfig).
  2. Ensure pods are labeled appropriately (e.g., app=myapp).
  3. Create a Service:
   oc expose deployment myapp --port=80 --target-port=8080

This automatically creates a Service with a selector matching the deployment’s pods.

  1. Verify:
   oc get svc
   oc describe svc myapp
  1. Connect from another pod:
    • Use http://myapp:80 (same namespace).
    • Optionally, fully qualify if needed.

OpenShift adds convenience commands:

Common Pitfalls and Considerations

Understanding these aspects of Services and service discovery will make it easier to design, deploy, and debug microservices-based applications on OpenShift, and to integrate them cleanly with the rest of the cluster networking stack.

Views: 47

Comments

Please login to add a comment.

Don't have an account? Register now!