# Kubernetes verbinden

# Kubernetes verbinden

Costfluent verteilt die Kosten der Nodes eines Kubernetes-Clusters auf Namespaces und weist den
verbleibenden Leerlauf getrennt aus. Eine verifizierte Kostenansicht pro Pod, Workload oder Container
gibt es nicht. Ein kleiner Agent, mit Helm installiert, liest die
Ressourcennutzung im Cluster und meldet sie stündlich an Costfluent. Eine Verbindung müssen Sie
vorher nicht anlegen: Der Cluster registriert sich mit seinem ersten Bericht selbst und erscheint
unter **Einstellungen**, dann **Integrationen**, dann **Kubernetes**.

## Voraussetzungen

- Ein Kubernetes-Cluster, in dem Sie ein Helm-Chart installieren können, mit clusterweitem
  Lesezugriff für das Dienstkonto des Agenten.
- Ausgehendes HTTPS vom Cluster zu `https://api.costfluent.com`, direkt oder über einen Proxy.
- Ein Organisations-API-Token mit der Berechtigung **Report Kubernetes usage**. Workspace-Tokens
  werden abgelehnt.

## Den Agenten installieren

Öffnen Sie **Einstellungen**, dann **API-Token**, und erstellen Sie ein Organisations-Token nur mit
der Berechtigung **Report Kubernetes usage**. Sie erlaubt genau den einen Upload, den der Agent
macht, und sonst nichts. Kopieren Sie das Token; sein vollständiger Wert wird nur einmal angezeigt.

Wählen Sie eine Cluster-ID. Sie benennt den Cluster in Costfluent und muss innerhalb Ihrer
Organisation eindeutig sein: 1 bis 63 Buchstaben, Ziffern, Punkte, Unterstriche oder Bindestriche,
beginnend mit einem Buchstaben oder einer Ziffer. Installieren Sie dann das Chart:

```bash
helm repo add costfluent https://costfluent.github.io/helm-charts
helm upgrade -n costfluent cfa costfluent/costfluent-k8s-agent --install --create-namespace \
  --set agent.token=$COSTFLUENT_API_TOKEN,agent.clusterID=$CLUSTER_ID
```

Installieren Sie einen Agenten pro Cluster. Nach wenigen Minuten erscheint der Cluster auf der
Seite **Kubernetes** als **Importing**. Aktivieren Sie ihn in den Workspaces, die seine Kosten sehen
sollen, wie jede andere Datenquelle.

## Wichtige Werte

| Wert | Standard | Zweck |
|---|---|---|
| `agent.token` | keiner | Das Organisations-API-Token. Setzen Sie es oder `agent.secret`. |
| `agent.secret.name`, `agent.secret.key` | keiner | Ein vorhandenes Secret mit dem Token, statt `agent.token`. |
| `agent.clusterID` | keiner, erforderlich | Die ID des Clusters in Costfluent. |
| `agent.apiEndpoint` | `https://api.costfluent.com` | Wohin die Berichte gehen. |
| `agent.pollingInterval` | | Sekunden zwischen zwei Nutzungsmessungen: 5, 10, 15, 30 oder 60. |
| `agent.nodeAddressTypes` | | Welche Node-Adresse der Agent nutzt, um jedes Kubelet zu erreichen. |
| `agent.disableKubeTLSverify` | `false` | Kubelet-Zertifikate nicht prüfen. |
| `agent.allowedLabels` | alle | Zu sendende Pod-Labels. Leer sendet alle Pod-Labels. |
| `agent.allowedAnnotations` | keine | Zu sendende Pod-Annotationen. Leer sendet keine. |
| `agent.collectNamespaceLabels` | `false` | Namespace-Labels senden. |
| `agent.reportHTTPProxy` | keiner | Ein HTTP-Proxy für den Upload. |
| `persist.size`, `persist.storageClassName` | `1Gi` | Das Volume, das Berichte puffert, solange Costfluent nicht erreichbar ist. |
| `resources` | Anforderung `50m` CPU und `64Mi`, Limit `256Mi` | CPU- und Speicheranforderungen und -limits des Agenten. |

Halten Sie das Token aus Values-Dateien in der Versionskontrolle heraus: Legen Sie es in einem
Secret ab und verweisen Sie mit `agent.secret` darauf.

## Dimensionierung

Der Agent ist ein einzelner Pod, unabhängig von der Größe des Clusters. Sein Speicherbedarf wächst
mit der Zahl der Container, die er verfolgt. Gemessen mit 61 Pods bei einem Abfrageintervall von
5 Sekunden lag sein Working Set im Mittel bei 11,4 MiB, in der Spitze bei 12,8 MiB, bei unter
0,001 CPU-Kernen. Die Standardwerte (`64Mi` angefordert, `256Mi` Limit) lassen Raum für ein
Vielfaches dieser Clustergröße; erhöhen Sie das Speicherlimit, wenn der Pod wegen Überschreitung
neu gestartet wird.

## Was gelesen und gesendet wird

Der Agent liest nur: Nodes, Pods, Namespaces und die Ressourcenmetriken, die jedes Kubelet
bereitstellt. Er sendet Form und Identität der Nodes, Identität von Pods und Containern,
Ressourcenanforderungen und -nutzung sowie die Pod-Labels, die Sie erlauben. Container-Images,
Umgebungsvariablen, Secrets, Config Maps, Logs und Netzwerkverkehr sendet er nie. Die Tabelle
[what the agent reads and sends](https://github.com/costfluent/helm-charts/tree/main/costfluent-k8s-agent#what-the-agent-reads-and-sends)
in der README des Charts ist die vollständige Liste.

Berichte, die nicht zugestellt werden können, bleiben auf dem Volume des Agenten und werden
gesendet, sobald Costfluent wieder erreichbar ist.

## Wie die Kosten berechnet werden

Die Tageskosten jedes Nodes werden in CPU, Speicher und, auf GPU-Nodes, GPU aufgeteilt. Die
Berechnung nutzt die Ressourcenanforderungen und die gemessene Nutzung der Container, um Kosten
auf Namespaces zu verteilen. Der verbleibende Teil der Node-Kosten sind Leerlaufkosten und
erscheint als Namespace `__idle__`.

Der Preis eines Nodes kommt aus der ersten dieser Quellen, die einen hat:

1. Den Abrechnungszeilen einer AWS-, Azure- oder GCP-Verbindung Ihrer Organisation, die diesen
   Node abrechnen.
2. Den Annotationen des Nodes selbst, unten beschrieben.
3. Den Raten, die in Costfluent für den Cluster hinterlegt sind.

Ein Node, den keine davon bepreist, wird ausgelassen und am Cluster als unbepreist gezählt.

Costfluent verarbeitet jeden Cluster einmal pro Nacht, um 02:00 UTC, für den Vortag. Kosten
erscheinen deshalb am Morgen nach der Installation, während die Seite **Kubernetes** den neuesten
Bericht schon nach wenigen Minuten zeigt. Gruppieren oder filtern Sie in Kostenberichten nach
**Cluster** und **Namespace**, und nutzen Sie Pod-Labels als Tags mit dem Namen `k8s:label:<key>`.

## On-Premises und eigene Raten

Für Nodes ohne Cloud-Abrechnung, etwa in On-Premises- oder Bare-Metal-Clustern, öffnen Sie den
Cluster auf der Seite **Kubernetes** und hinterlegen seine Stundenraten pro vCPU, pro GB Speicher
und pro GPU sowie deren Währung. Um einzelne Nodes anders zu bepreisen, annotieren Sie sie:

```bash
kubectl annotate node <node> \
  costfluent.com/vcpu-hourly-rate=0.021 \
  costfluent.com/ram-gb-hourly-rate=0.003 \
  costfluent.com/gpu-hourly-rate=0.90
```

Annotationsraten gelten in der Währung des Clusters und haben Vorrang vor den Raten des Clusters.

## Doppelzählung vermeiden

Die Kosten eines Clusters sind die Kosten seiner Nodes, die bereits die Cloud-Verbindung meldet,
die sie bezahlt. Costfluent rechnet Kubernetes-Kosten nicht zu den erfassten Ausgaben, aber ein
Kostenbericht über einen Workspace mit beiden Quellen zeigt die Nodes doppelt: einmal als Instanzen
der Cloud, einmal auf Namespaces verteilt. Filtern Sie einen Bericht nach Anbieter auf eine Seite,
wenn Sie eine Summe brauchen.

## Cluster-Status

| Status | Bedeutung |
|---|---|
| **Importing** | Der Cluster hat berichtet, sein erster Tag ist noch nicht verarbeitet. |
| **Stable** | Berichte kommen an und jeder Tag wird verarbeitet. |
| **Stale** | Seit zwei Stunden kein Bericht. Prüfen Sie, ob der Agent-Pod läuft und Costfluent erreicht. |
| **Warning** | Einige Nodes haben keinen Preis, oder die Verarbeitung eines Tages ist fehlgeschlagen. Die Cluster-Seite sagt, was davon. |

## Fehlerbehebung

Der Agent protokolliert jeden abgelehnten Upload mit dem Grund. Die häufigsten:

- **401 oder 403.** Das Token ist falsch, widerrufen, ein Workspace-Token oder hat die Berechtigung
  **Report Kubernetes usage** nicht. Die Berichte bleiben gepuffert, ein korrigiertes Token holt
  sie nach.
- **409.** Ein anderer Agent meldet diese Cluster-ID bereits, oder die Organisation hat ihr Limit
  von 100 Clustern erreicht. Geben Sie jedem Cluster eine eigene ID.
- **410.** Der Cluster wurde in Costfluent gelöscht. Deinstallieren Sie den Agenten oder
  installieren Sie ihn unter einer neuen Cluster-ID erneut.
- **413.** Ein Bericht war zu groß. Der Agent wartet und versucht es erneut; schränken Sie
  `agent.allowedLabels` ein, wenn es anhält.
- **Keine Nutzung auf AKS.** Kubelets auf AKS liefern oft Zertifikate, die der Agent nicht prüfen
  kann, oder sind unter ihrer Standardadresse nicht erreichbar. Setzen Sie
  `agent.disableKubeTLSverify=true` und `agent.nodeAddressTypes=InternalIP`.

## Deinstallieren

```bash
helm uninstall -n costfluent cfa
```

Der Cluster wird zwei Stunden später **Stale**, seine bisherigen Kosten bleiben in den
Kostenberichten. Löschen Sie ihn auf der Seite **Kubernetes**, um ihn zu entfernen; ein Agent, der
für einen gelöschten Cluster weiterläuft, wird abgelehnt. Widerrufen Sie danach sein API-Token.
