31 Service-Definitionen und Cluster-IP

Service-Definitionen implementieren Abstraktionsebenen für Netzwerkkommunikation in OpenShift-Clustern durch virtuelle Endpunkte, die dynamische Pod-Kollektionen über stabile IP-Adressen und DNS-Namen zugänglich machen. ClusterIP-Services bilden die fundamentale Service-Kategorie für cluster-interne Kommunikation und ermöglichen Mikroservice-Architekturen mit entkoppelter Service-Discovery und Load-Balancing.

31.1 Das Problem: Dynamische Pod-IPs

In OpenShift haben Pods dynamische IP-Adressen, die sich bei jedem Neustart ändern. Direkte Pod-zu-Pod-Kommunikation über IP-Adressen ist daher unpraktikabel und fehleranfällig. Services lösen dieses fundamentale Problem durch stabile Abstraktionsschichten.

[Diagramm: Service-ClusterIP-Architektur mit DNS-Resolution und Load Balancing]

Services implementieren Indirection-Layer zwischen Service-Konsumenten und Service-Providern durch Label-Selektor-basierte Pod-Discovery und virtuelle IP-Allokation. Diese Abstraktion ermöglicht dynamische Backend-Änderungen ohne Consumer-Rekonfiguration und unterstützt Rolling-Deployment-Szenarien mit nahtloser Service-Kontinuität.

31.1.1 Warum Services essentiell sind

Ohne Services (problematisch):

# Pod-IP-Adressen ändern sich konstant
oc get pods -o wide
# NAME           READY   IP           NODE
# webapp-abc123  1/1     10.128.2.15  worker-1
# webapp-def456  1/1     10.128.3.22  worker-2

# Nach Neustart: Komplett andere IPs!
oc delete pod webapp-abc123
oc get pods -o wide
# webapp-ghi789  1/1     10.128.1.31  worker-1  <- Neue IP!

Mit Services (stabil):

# Service behält stabile IP und DNS-Namen
oc get service webapp-service
# NAME            TYPE        CLUSTER-IP     PORT(S)
# webapp-service  ClusterIP   172.30.1.100   80/TCP

# Anwendungen können über DNS-Namen kommunizieren
curl http://webapp-service/api/health

31.2 ClusterIP-Services: Die Grundlage

ClusterIP-Services sind der Standard-Service-Typ für interne Cluster-Kommunikation. Sie erhalten virtuelle IP-Adressen aus dem Service-Subnet und sind nur innerhalb des Clusters erreichbar.

31.2.1 Basis-Service-Definition

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
  labels:
    app: webapp
    tier: frontend
spec:
  type: ClusterIP  # Standard-Typ (kann weggelassen werden)
  selector:
    app: webapp    # Pods mit diesem Label werden erfasst
  ports:
  - name: http
    port: 80       # Service-Port (extern sichtbar)
    targetPort: 8080  # Container-Port (intern)
    protocol: TCP
  # ClusterIP wird automatisch zugewiesen

31.2.2 Service-Erstellung und -Verifikation

# Service erstellen
oc apply -f webapp-service.yaml

# Service-Status prüfen
oc get service webapp-service
oc describe service webapp-service

# Ausgabe-Beispiel:
# Name:              webapp-service
# Namespace:         default
# Labels:            app=webapp
# Selector:          app=webapp
# Type:              ClusterIP
# IP:                172.30.1.100
# Port:              http  80/TCP
# TargetPort:        8080/TCP
# Endpoints:         10.128.2.15:8080,10.128.3.22:8080

# Service-Konnektivität testen
oc run test-pod --image=curlimages/curl:latest --rm -it --restart=Never -- \
  curl http://webapp-service/health

31.3 Endpoint-Management und Pod-Discovery

Endpoint-Controller überwachen kontinuierlich Pod-Status und aktualisieren Service-Endpoints basierend auf Readiness-Probe-Ergebnissen und Pod-Lifecycle-Events. Diese dynamische Endpoint-Verwaltung gewährleistet Traffic-Routing ausschließlich zu gesunden Pod-Instanzen.

31.3.1 Automatische Endpoint-Verwaltung

# Aktuelle Endpoints anzeigen
oc get endpoints webapp-service

# Beispiel-Output:
# NAME            ENDPOINTS                                      AGE
# webapp-service  10.128.2.15:8080,10.128.3.22:8080,10.128.4.31:8080  5m

# Endpoint-Details inspizieren
oc describe endpoints webapp-service

# Pod mit failing Readiness Probe wird automatisch entfernt
oc get pods -l app=webapp
# NAME           READY   STATUS    RESTARTS   AGE
# webapp-abc123  1/1     Running   0          10m
# webapp-def456  0/1     Running   0          10m  <- Not ready!

# Endpoints werden automatisch aktualisiert
oc get endpoints webapp-service
# webapp-abc123 bleibt, webapp-def456 wird entfernt

31.3.2 Label-Selektor-Mechanismen

Label-Selektor-Mechanismen definieren Pod-zu-Service-Zuordnungen über Key-Value-Metadaten-Matching:

# Service mit spezifischen Selektoren
apiVersion: v1
kind: Service
metadata:
  name: backend-api-service
spec:
  selector:
    app: backend
    component: api
    version: stable  # Nur stabile Version
  ports:
  - port: 80
    targetPort: 8080

---
# Pods mit passenden Labels
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-api
spec:
  selector:
    matchLabels:
      app: backend
      component: api
      version: stable
  template:
    metadata:
      labels:
        app: backend      # Matches Service selector
        component: api    # Matches Service selector
        version: stable   # Matches Service selector
    spec:
      containers:
      - name: api
        image: backend-api:stable

31.3.3 Headless Services

Headless Services eliminieren ClusterIP-Allokation und exposieren individuelle Pod-IPs über DNS A-Records für Direct-Pod-Access-Szenarien:

# Headless Service (kein ClusterIP)
apiVersion: v1
kind: Service
metadata:
  name: database-headless
spec:
  clusterIP: None  # Macht Service "headless"
  selector:
    app: database
  ports:
  - port: 5432
    targetPort: 5432

DNS-Resolution bei Headless Services:

# Normale Services: Eine IP
nslookup webapp-service.default.svc.cluster.local
# webapp-service.default.svc.cluster.local has address 172.30.1.100

# Headless Services: Alle Pod-IPs
nslookup database-headless.default.svc.cluster.local
# database-headless.default.svc.cluster.local has address 10.128.2.15
# database-headless.default.svc.cluster.local has address 10.128.3.22
# database-headless.default.svc.cluster.local has address 10.128.4.31

31.4 DNS-basierte Service Discovery

Cluster-DNS implementiert automatische Service-Name-Resolution über fully qualified domain names (FQDN) innerhalb Cluster-Namespace-Grenzen. Diese DNS-Integration abstrahiert IP-Address-Management vollständig.

31.4.1 DNS-Naming-Konventionen

Service-DNS-Records folgen strukturierten Naming-Conventions:

# DNS-Format: <service-name>.<namespace>.svc.cluster.local

# Beispiele:
webapp-service.default.svc.cluster.local          # Full FQDN
webapp-service.default                             # Namespace-qualified
webapp-service                                     # Kurz (nur innerhalb namespace)

# Test DNS-Resolution
oc run dns-test --image=busybox --rm -it --restart=Never -- \
  nslookup webapp-service.default.svc.cluster.local

# Cross-Namespace-Zugriff
# Service in 'backend' Namespace von 'frontend' Namespace aus
curl http://api-service.backend.svc.cluster.local/data

31.4.2 DNS-Konfiguration und -Optimierung

DNS-Caching auf Node-Ebene optimiert Service-Discovery-Performance:

# DNS-Konfiguration des Clusters prüfen
oc get configmap/coredns -n openshift-dns -o yaml

# Pod-DNS-Konfiguration anzeigen
oc exec webapp-pod -- cat /etc/resolv.conf
# nameserver 172.30.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5

# DNS-Performance testen
oc exec webapp-pod -- time nslookup database-service

31.4.3 Custom DNS-Policies

Custom DNS-Policies ermöglichen angepasste DNS-Resolution-Behavior:

apiVersion: v1
kind: Pod
spec:
  dnsPolicy: ClusterFirst  # Standard: Cluster-DNS zuerst
  # Alternativen:
  # dnsPolicy: None         # Custom DNS-Config
  # dnsPolicy: Default      # Node-DNS verwenden
  # dnsPolicy: ClusterFirstWithHostNet  # Für hostNetwork-Pods
  
  # Custom DNS-Konfiguration
  dnsConfig:
    nameservers:
    - 8.8.8.8
    searches:
    - company.com
    options:
    - name: ndots
      value: "2"
    - name: edns0

31.5 Load Balancing und Traffic-Distribution

OpenShift Services implementieren automatisches Load Balancing für Traffic-Verteilung über verfügbare Endpoints.

31.5.1 Standard Load-Balancing-Verhalten

Round-Robin Load-Balancing implementiert gleichmäßige Traffic-Verteilung über verfügbare Service-Endpoints:

# Load Balancing testen
for i in {1..10}; do
  oc exec test-pod -- curl -s http://webapp-service/api/hostname
done

# Ausgabe zeigt verschiedene Pod-Namen (Round-Robin):
# webapp-abc123
# webapp-def456  
# webapp-ghi789
# webapp-abc123  <- Zurück zum ersten
# webapp-def456

31.5.2 Session Affinity

Session-Affinity-Konfigurationen ermöglichen Client-zu-Pod-Binding für Anwendungen mit lokalen Session-State-Requirements:

apiVersion: v1
kind: Service
metadata:
  name: stateful-webapp
spec:
  selector:
    app: webapp
  sessionAffinity: ClientIP  # Sticky Sessions basierend auf Client-IP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800  # 3 Stunden Session-Persistenz
  ports:
  - port: 80
    targetPort: 8080

Session Affinity testen:

# Wiederholte Requests vom gleichen Pod sollten zum gleichen Backend gehen
oc exec test-pod -- curl -s http://stateful-webapp/api/hostname
oc exec test-pod -- curl -s http://stateful-webapp/api/hostname
oc exec test-pod -- curl -s http://stateful-webapp/api/hostname
# Alle Requests gehen zum gleichen Backend-Pod

31.5.3 External Traffic Policy

External Traffic Policy-Konfigurationen steuern Source-IP-Preservation für externe Traffic-Quellen:

apiVersion: v1
kind: Service
metadata:
  name: webapp-nodeport
spec:
  type: NodePort
  externalTrafficPolicy: Local  # Bewahrt Source-IP, aber ungleiche Load-Balance
  # externalTrafficPolicy: Cluster  # Standard: gleichmäßige Balance
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080

31.6 Multi-Port Services und Port-Management

Multi-Port Services ermöglichen Exposition mehrerer Application-Ports über einzelne Service-Definitionen mit Named-Port-References.

31.6.1 Multi-Port Service-Definition

apiVersion: v1
kind: Service
metadata:
  name: multi-protocol-service
spec:
  selector:
    app: webapp
  ports:
  # HTTP-Traffic
  - name: http
    port: 80
    targetPort: 8080
    protocol: TCP
  # HTTPS-Traffic
  - name: https
    port: 443
    targetPort: 8443
    protocol: TCP
  # Metrics-Endpoint
  - name: metrics
    port: 9090
    targetPort: 9090
    protocol: TCP
  # UDP-basierter Service (z.B. DNS)
  - name: dns-udp
    port: 53
    targetPort: 5353
    protocol: UDP

31.6.2 Target-Port-Mapping

Target-Port-Mapping entkoppelt Service-Port-Definitionen von Container-Port-Implementierungen:

apiVersion: v1
kind: Service
spec:
  ports:
  # Service-Port kann von Container-Port abweichen
  - name: web
    port: 80          # Externer Service-Port
    targetPort: 8080  # Interner Container-Port
  
  # Named-Port-Referenz (flexibler)
  - name: api
    port: 443
    targetPort: https-port  # Referenz auf benannten Container-Port

---
# Container mit benannten Ports
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: webapp
        ports:
        - name: https-port  # Benannter Port
          containerPort: 8443
        - containerPort: 8080  # Unbenannt

31.7 Service-Monitoring und Observability

Service-Level Metrics aggregieren Traffic-Statistics, Response-Times und Error-Rates auf Service-Abstraction-Level für Application-Performance-Management.

31.7.1 Service-Metriken sammeln

# Service-Endpoints und -Status überwachen
oc get service --show-labels
oc get endpoints -l app=webapp

# Service-Traffic über Prometheus Metriken
# (wenn Service Monitor konfiguriert)
curl http://prometheus:9090/api/v1/query?query='rate(http_requests_total{service="webapp-service"}[5m])'

# Service-Discovery-Status prüfen
oc describe service webapp-service | grep -A 10 Endpoints

# DNS-Resolution-Tests
oc run dns-debug --image=busybox --rm -it --restart=Never -- \
  nslookup webapp-service.default.svc.cluster.local

31.7.2 Distributed Tracing Integration

Distributed-Tracing Integration auf Service-Level ermöglicht Request-Flow-Tracking über Service-Boundaries:

# Service mit Tracing-Annotations
apiVersion: v1
kind: Service
metadata:
  name: traced-service
  annotations:
    # Jaeger-Tracing aktivieren
    sidecar.jaegertracing.io/inject: "true"
  labels:
    app: webapp
    tracing: enabled
spec:
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 8080

31.7.3 Service-Dependency Mapping

Service-Dependency Mapping visualisiert Service-Communication-P