Veröffentlicht am

OpenCost einrichten: Kubernetes-Kosten tracken und senken

Teilen:
Authors

Kubernetes Cost Monitoring: Kosten-Tracking und Optimierung mit OpenCost

TL;DR

  • OpenCost ist das CNCF-Projekt fuer Kubernetes Cost Monitoring -- Open Source, herstellerunabhaengig und in 15 Minuten installiert
  • Cost Allocation nach Namespace, Label und Team macht sichtbar, welcher Service wie viel kostet -- die Grundlage fuer Showback und Chargeback
  • Budget-Alerts ueber Prometheus und Alertmanager warnen fruehzeitig, bevor Kosten aus dem Ruder laufen
  • Idle-Resource-Erkennung deckt ungenutzte Ressourcen auf -- typisch sind 30-40% verschwendete Kapazitaet
  • Right-Sizing, Spot Instances und Scale-to-Zero sind die drei wirksamsten Hebel fuer sofortige Kostensenkung

Warum Kubernetes Cost Monitoring entscheidend ist

Kubernetes abstrahiert Infrastruktur. Das ist sein groesster Vorteil -- und gleichzeitig die Ursache fuer unkontrollierte Kosten. Entwickler deployen Services ohne zu wissen, was sie kosten. Ops-Teams sehen die Cloud-Rechnung, koennen aber nicht zuordnen, welcher Service welchen Anteil verursacht.

Das Ergebnis: Die durchschnittliche Kubernetes-Umgebung verschwendet 30-40% ihres Budgets durch ueberprovisionierte Ressourcen, vergessene Workloads und fehlende Skalierung.

Kubernetes cost monitoring schliesst diese Luecke. Es verbindet Cloud-Kosten mit Kubernetes-Objekten und macht sichtbar, wer was verbraucht.

FinOps-Grundlagen fuer Kubernetes

FinOps ist die Disziplin, die Cloud-Kosten in die Verantwortung der Engineering-Teams bringt. Fuer Kubernetes bedeutet das drei Phasen:

Inform -- Kosten sichtbar machen. Dashboards, Reports und Allokation nach Teams.

Optimize -- Verschwendung eliminieren. Right-Sizing, Spot-Nutzung, Scale-to-Zero.

Operate -- Kontinuierlich steuern. Budget-Alerts, Governance-Policies, regelmaessige Reviews.

OpenCost deckt die erste Phase komplett ab und liefert die Daten fuer Phase zwei und drei.

OpenCost installieren

OpenCost ist ein CNCF-Sandbox-Projekt und laeuft als einzelner Pod im Cluster. Die Installation per Helm dauert wenige Minuten.

Voraussetzungen

  • Kubernetes 1.25 oder hoeher
  • Prometheus im Cluster (fuer Metriken-Speicherung)
  • Helm 3.x

Installation via Helm

# Helm-Repository hinzufuegen
helm repo add opencost https://opencost.github.io/opencost-helm-chart
helm repo update

# OpenCost installieren
helm install opencost opencost/opencost \
  --namespace opencost \
  --create-namespace \
  --set opencost.prometheus.internal.serviceName=prometheus-server \
  --set opencost.prometheus.internal.namespaceName=monitoring \
  --set opencost.ui.enabled=true

Custom Pricing konfigurieren

Fuer On-Premise oder spezifische Vertragspreise koennt ihr Custom Pricing hinterlegen:

# values-custom.yaml
opencost:
  customPricing:
    enabled: true
    configmapName: opencost-custom-pricing
    provider: custom
  prometheus:
    internal:
      serviceName: prometheus-server
      namespaceName: monitoring
  ui:
    enabled: true
    ingress:
      enabled: true
      hosts:
        - host: costs.internal.example.com
          paths:
            - /
# custom-pricing-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: opencost-custom-pricing
  namespace: opencost
data:
  default.json: |
    {
      "provider": "custom",
      "description": "On-Premise Kubernetes Cluster",
      "CPU": "0.031611",
      "RAM": "0.004237",
      "GPU": "0.95",
      "storage": "0.00005479"
    }
kubectl apply -f custom-pricing-configmap.yaml
helm upgrade opencost opencost/opencost \
  --namespace opencost \
  -f values-custom.yaml

Installation verifizieren

# Pod-Status pruefen
kubectl get pods -n opencost

# API testen -- Kosten der letzten 24h pro Namespace
kubectl port-forward -n opencost svc/opencost 9090:9090
curl http://localhost:9090/allocation/compute?window=24h&aggregate=namespace

Cost Allocation: Kosten nach Team und Service aufschluesseln

Die Staerke von Kubernetes cost monitoring liegt in der Allokation. OpenCost ordnet Kosten automatisch zu -- nach Namespace, Label, Annotation oder Controller.

Namespace-basierte Allokation

Die einfachste Variante: Jedes Team bekommt einen Namespace, OpenCost aggregiert automatisch.

# Namespace mit Team-Labels fuer Kostenallokation
apiVersion: v1
kind: Namespace
metadata:
  name: team-payments
  labels:
    team: payments
    cost-center: "4711"
    environment: production

Label-basierte Allokation

Fuer feinere Granularitaet nutzt ihr Labels direkt auf Deployments:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-api
  namespace: team-payments
  labels:
    app: payment-api
    team: payments
    cost-center: "4711"
    component: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: payment-api
  template:
    metadata:
      labels:
        app: payment-api
        team: payments
        cost-center: "4711"
        component: backend
    spec:
      containers:
        - name: api
          image: payment-api:v2.1.0
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              cpu: 500m
              memory: 1Gi

Shared-Cost-Verteilung

Cluster-weite Kosten wie Ingress-Controller, Monitoring und Service Mesh muessen fair verteilt werden. OpenCost unterstuetzt proportionale Verteilung:

# Shared Costs per API abfragen
curl "http://localhost:9090/allocation/compute?window=7d&aggregate=label:team&shareNamespaces=kube-system,monitoring,ingress-nginx&shareSplit=weighted"

Grafana-Dashboards fuer Kostenvisualisierung

OpenCost exportiert Prometheus-Metriken, die sich direkt in Grafana visualisieren lassen.

Prometheus-Metriken von OpenCost

Die wichtigsten Metriken:

# CPU-Kosten pro Container
opencost_container_cpu_cost_total

# Memory-Kosten pro Container
opencost_container_memory_cost_total

# Storage-Kosten pro PV
opencost_container_storage_cost_total

# Gesamtkosten pro Namespace
sum(opencost_container_cpu_cost_total + opencost_container_memory_cost_total) by (namespace)

Grafana-Dashboard konfigurieren

# grafana-dashboard-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: opencost-grafana-dashboard
  namespace: monitoring
  labels:
    grafana_dashboard: "true"
data:
  opencost-overview.json: |
    {
      "dashboard": {
        "title": "Kubernetes Cost Overview",
        "panels": [
          {
            "title": "Monatliche Kosten pro Namespace",
            "type": "barchart",
            "targets": [
              {
                "expr": "sum(opencost_container_cpu_cost_total + opencost_container_memory_cost_total) by (namespace) * 730",
                "legendFormat": "{{ namespace }}"
              }
            ]
          },
          {
            "title": "CPU vs Memory Kosten-Verteilung",
            "type": "piechart",
            "targets": [
              {
                "expr": "sum(opencost_container_cpu_cost_total) * 730",
                "legendFormat": "CPU"
              },
              {
                "expr": "sum(opencost_container_memory_cost_total) * 730",
                "legendFormat": "Memory"
              }
            ]
          },
          {
            "title": "Idle Resources (verschwendete Kosten)",
            "type": "gauge",
            "targets": [
              {
                "expr": "1 - (sum(rate(container_cpu_usage_seconds_total[1h])) / sum(kube_pod_container_resource_requests{resource='cpu'}))",
                "legendFormat": "CPU Idle Rate"
              }
            ]
          }
        ]
      }
    }

Budget-Alerts mit Prometheus

Sichtbarkeit allein reicht nicht. Budget-Alerts warnen, bevor die monatliche Rechnung explodiert.

Alerting Rules definieren

# prometheus-cost-alerts.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: cost-alerts
  namespace: monitoring
spec:
  groups:
    - name: kubernetes-cost-alerts
      rules:
        - alert: NamespaceCostExceedsBudget
          expr: |
            sum(opencost_container_cpu_cost_total + opencost_container_memory_cost_total) by (namespace) * 730 > 500
          for: 1h
          labels:
            severity: warning
            category: cost
          annotations:
            summary: "Namespace {{ $labels.namespace }} ueberschreitet 500 EUR/Monat"
            description: "Aktuelle hochgerechnete Monatskosten: {{ $value | humanize }} EUR"

        - alert: ClusterCostSpike
          expr: |
            sum(opencost_container_cpu_cost_total + opencost_container_memory_cost_total) * 730
            > 1.3 * avg_over_time(
              (sum(opencost_container_cpu_cost_total + opencost_container_memory_cost_total) * 730)[7d:1h]
            )
          for: 2h
          labels:
            severity: warning
            category: cost
          annotations:
            summary: "Cluster-Kosten 30% ueber dem 7-Tage-Durchschnitt"

        - alert: HighIdleResources
          expr: |
            1 - (
              sum(rate(container_cpu_usage_seconds_total{namespace!="kube-system"}[1h]))
              / sum(kube_pod_container_resource_requests{resource="cpu", namespace!="kube-system"})
            ) > 0.5
          for: 24h
          labels:
            severity: info
            category: cost
          annotations:
            summary: "Ueber 50% der angeforderten CPU wird nicht genutzt"

Alertmanager-Route fuer Kosten-Alerts

# alertmanager-config.yaml
route:
  receiver: default
  routes:
    - match:
        category: cost
      receiver: cost-team
      group_wait: 30m
      group_interval: 4h
      repeat_interval: 24h

receivers:
  - name: cost-team
    slack_configs:
      - channel: '#finops-alerts'
        title: 'Kubernetes Cost Alert'
        text: '{{ .CommonAnnotations.summary }}'
    email_configs:
      - to: 'finops-team@example.com'
        send_resolved: true

OpenCost vs. Kubecost: Vergleich

Kubecost baut auf OpenCost auf, bietet aber zusaetzliche Enterprise-Features.

FeatureOpenCostKubecost FreeKubecost Enterprise
Cost AllocationJaJaJa
Prometheus-MetrikenJaJaJa
Web-UIEinfachUmfangreichUmfangreich
Multi-ClusterNeinNeinJa
Savings RecommendationsNeinBegrenztJa
SSO / RBACNeinNeinJa
Historische Daten15 Tage15 TageUnbegrenzt
KostenKostenlosKostenlosLizenzgebuehr

Empfehlung: Startet mit OpenCost. Wenn ihr Multi-Cluster-Support oder automatisierte Savings-Empfehlungen braucht, evaluiert Kubecost Enterprise.

Idle-Resource-Erkennung

Idle Resources sind der groesste Kostentreiber. OpenCost hilft, sie systematisch zu identifizieren.

Ungenutzte Deployments finden

# Deployments mit 0 CPU-Verbrauch in den letzten 7 Tagen
kubectl get deployments --all-namespaces -o json | \
  jq -r '.items[] | select(.status.readyReplicas > 0) | "\(.metadata.namespace)/\(.metadata.name)"' | \
  while read deployment; do
    ns=$(echo $deployment | cut -d'/' -f1)
    name=$(echo $deployment | cut -d'/' -f2)
    cpu=$(kubectl top pods -n $ns -l app=$name --no-headers 2>/dev/null | awk '{sum+=$2} END {print sum+0}')
    if [ "$cpu" -lt 5 ]; then
      echo "LOW USAGE: $deployment (${cpu}m CPU)"
    fi
  done

Ueberprovisionierte Pods identifizieren

# PrometheusRule fuer Overprovisioning-Erkennung
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: overprovisioning-detection
  namespace: monitoring
spec:
  groups:
    - name: overprovisioning
      rules:
        - alert: CPURequestsTooHigh
          expr: |
            (
              sum(kube_pod_container_resource_requests{resource="cpu"}) by (namespace, pod)
              - sum(rate(container_cpu_usage_seconds_total[7d])) by (namespace, pod)
            ) / sum(kube_pod_container_resource_requests{resource="cpu"}) by (namespace, pod) > 0.8
          for: 7d
          labels:
            severity: info
          annotations:
            summary: "Pod {{ $labels.namespace }}/{{ $labels.pod }} nutzt weniger als 20% der angeforderten CPU seit 7 Tagen"

        - alert: MemoryRequestsTooHigh
          expr: |
            (
              sum(kube_pod_container_resource_requests{resource="memory"}) by (namespace, pod)
              - sum(container_memory_working_set_bytes) by (namespace, pod)
            ) / sum(kube_pod_container_resource_requests{resource="memory"}) by (namespace, pod) > 0.7
          for: 7d
          labels:
            severity: info
          annotations:
            summary: "Pod {{ $labels.namespace }}/{{ $labels.pod }} nutzt weniger als 30% des angeforderten Memory seit 7 Tagen"

Kosten-Optimierung: Die drei wirksamsten Hebel

1. Right-Sizing mit VPA-Recommendations

Der Vertical Pod Autoscaler im Recommender-Modus analysiert echten Verbrauch und schlaegt passende Requests vor:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: payment-api-vpa
  namespace: team-payments
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: payment-api
  updatePolicy:
    updateMode: "Off"
  resourcePolicy:
    containerPolicies:
      - containerName: api
        minAllowed:
          cpu: 50m
          memory: 128Mi
        maxAllowed:
          cpu: 2
          memory: 4Gi
# VPA-Empfehlungen anzeigen
kubectl get vpa payment-api-vpa -n team-payments -o jsonpath='{.status.recommendation}'

Typische Einsparung durch Right-Sizing: 25-40% der Compute-Kosten.

2. Spot Instances fuer fehlertolerante Workloads

# Node-Affinity fuer Spot-faehige Workloads
apiVersion: apps/v1
kind: Deployment
metadata:
  name: batch-processor
spec:
  replicas: 5
  template:
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 90
              preference:
                matchExpressions:
                  - key: kubernetes.io/lifecycle
                    operator: In
                    values:
                      - spot
      tolerations:
        - key: kubernetes.io/lifecycle
          operator: Equal
          value: spot
          effect: NoSchedule
      containers:
        - name: processor
          image: batch-processor:v1.3.0
          resources:
            requests:
              cpu: 500m
              memory: 1Gi

Spot Instances sparen 60-80% gegenueber On-Demand-Preisen. Voraussetzung: Der Workload muss Unterbrechungen tolerieren.

3. Scale-to-Zero fuer Dev/Staging

# KEDA ScaledObject fuer Scale-to-Zero
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: dev-api-scaler
  namespace: development
spec:
  scaleTargetRef:
    name: dev-api
  minReplicaCount: 0
  maxReplicaCount: 3
  cooldownPeriod: 300
  idlePeriod: 600
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus-server.monitoring:9090
        metricName: http_requests_total
        query: sum(rate(http_requests_total{namespace="development",service="dev-api"}[5m]))
        threshold: "1"

Entwicklungs-Environments laufen oft 24/7, werden aber nur 8-10 Stunden am Tag genutzt. Scale-to-Zero spart hier 60-70%.

Showback und Chargeback fuer Teams

Showback-Report automatisieren

# CronJob fuer woechentlichen Kosten-Report
apiVersion: batch/v1
kind: CronJob
metadata:
  name: weekly-cost-report
  namespace: opencost
spec:
  schedule: "0 8 * * 1"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: report
              image: curlimages/curl:latest
              command:
                - /bin/sh
                - -c
                - |
                  REPORT=$(curl -s "http://opencost.opencost:9090/allocation/compute?window=7d&aggregate=label:team")
                  curl -X POST "https://hooks.slack.com/services/YOUR/WEBHOOK/URL" \
                    -H "Content-Type: application/json" \
                    -d "{\"text\": \"Woechentlicher Kubernetes-Kostenbericht:\\n\`\`\`${REPORT}\`\`\`\"}"
          restartPolicy: OnFailure

Praktisches Einspar-Beispiel

Ein typischer Produktions-Cluster mit 20 Nodes und 150 Deployments:

MassnahmeMonatliche EinsparungAufwand
Right-Sizing (VPA Off-Mode)2.500 EUR2 Tage
Spot fuer Batch-Workloads1.800 EUR1 Tag
Scale-to-Zero Dev/Staging3.200 EUR0.5 Tage
Idle Deployments entfernen900 EUR0.5 Tage
Gesamt8.400 EUR/Monat4 Tage

Das entspricht ueber 100.000 EUR Einsparung pro Jahr bei einem einmaligen Aufwand von wenigen Tagen.

Verwandte Artikel

Fazit

Kubernetes cost monitoring ist keine optionale Erweiterung -- es ist eine Grundvoraussetzung fuer den wirtschaftlichen Betrieb von Kubernetes-Clustern. OpenCost liefert die Transparenz, die Teams brauchen, um fundierte Entscheidungen ueber Ressourcen-Allokation zu treffen.

Der Einstieg ist einfach: OpenCost installieren, zwei Wochen Daten sammeln, dann systematisch optimieren. Die typische Einsparung liegt bei 30-50% der bisherigen Kosten.

Wenn Sie Unterstuetzung beim Aufbau Ihres Kubernetes-FinOps-Prozesses brauchen -- von der Tool-Auswahl ueber die Implementierung bis zur Team-Schulung -- stehen wir Ihnen gerne zur Verfuegung. Kontaktieren Sie uns unter /kontakt fuer ein unverbindliches Gespraech.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen

kubernetesopencost+1 weitere

OpenCost FinOps: Kubernetes-Kosten pro Team aufschlüsseln

Meistern Sie mit OpenCost 2026 die präzise Kostenallokation und Showback in Kubernetes für FinOps im Mittelstand. Dieser Guide zeigt DevOps-Teams, wie sie Cloud-Kosten transparent machen, Budgets überwachen und die Kubernetes Kostenoptimierung sowie Effizienz signifikant steigern – ideal als leistungsstarke Kubecost-Alternative.

Weiterlesen →