Kubernetes & Cilium Cheat Sheet

Der ultimative Guide für Debugging, Scaling, Networking und Node-Management.

Inhaltsverzeichnis

Node Management & Uncordon

Wenn ein Node den Status SchedulingDisabled hat, ist er abgesperrt. So bekommst du ihn wieder fit:

Node wieder aktivieren (Uncordon)

kubectl uncordon 

Dies entfernt den Taint node.kubernetes.io/unschedulable und erlaubt dem Scheduler wieder, Pods darauf zu platzieren.

Wartungsmodus (Drain & Cordon)

# Cordon (Absperren): Keine neuen Pods
kubectl cordon 

# Drain (Entleeren): Verschiebt alle Pods sicher
kubectl drain  --ignore-daemonsets --delete-emptydir-data

Pod Verteilung (Affinity & Anti-Affinity)

Steuere genau, wo deine Pods landen sollen.

1. Anti-Affinity (Verteilen)

Sorgt dafür, dass Pods NICHT auf demselben Node landen (Ausfallsicherheit).

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - gtg-eventsystem
        topologyKey: "kubernetes.io/hostname"

2. Pod Affinity (Zusammenhalten)

Zieht Pods auf denselben Node (z.B. App + Cache für Performance).
Tipp: Dies ermöglicht es mehreren Pods, dasselbe RWO-Volume (ReadWriteOnce) zu mounten, da sie sich auf demselben Node befinden.

affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values:
          - redis-cache
      topologyKey: "kubernetes.io/hostname"

Debugging & Inspecting

Status & Logs

# Pod Details & Events (Wichtig!)
kubectl describe pod  -n 

# Logs (letzte 100 Zeilen)
kubectl logs  -n  --tail=100

# Live Logs
kubectl logs -f  -n 

# Wo läuft der Pod? (IP & Node)
kubectl get pods -o wide

Interaktiver Zugriff (Exec & Port-Forward)

# Shell im Container öffnen
kubectl exec -it  -n  -- /bin/sh

# Port Forwarding (Lokal testen)
kubectl port-forward pod/ 8080:8080

Rollouts & Deployments

# Status prüfen
kubectl rollout status deployment/

# Historie
kubectl rollout history deployment/

# Undo (Rollback)
kubectl rollout undo deployment/

# Restart (ohne Code-Änderung)
kubectl rollout restart deployment/

Ressourcen & Scaling (HPA/VPA)

Requests vs. Limits

HPA (Horizontal Pod Autoscaler)

Skaliert die Anzahl der Pods basierend auf CPU/RAM. Ideal für stateless Web-Apps.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

VPA (Vertical Pod Autoscaler)

Passt die Größe (CPU/RAM Requests) der Pods an. Ideal für Java-Apps oder DBs, die schwer horizontal skalieren.

Achtung: VPA startet Pods oft neu, um Ressourcen zu ändern! Nicht zusammen mit HPA auf CPU/RAM nutzen!

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Auto"

Security & Namespace Limits

ResourceQuota (Namespace Limits)

Verhindert, dass ein einzelner Namespace den gesamten Cluster lahmlegt. Setzt harte Obergrenzen für CPU, RAM und Pod-Anzahl.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: limit-quota
  namespace: my-namespace
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "20"

RBAC (Role-Based Access Control)

Das Rechte-System von Kubernetes basiert auf drei Säulen:

Wichtige Begriffe:

# 1. ServiceAccount (Die Identität für Apps/Bots)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-bot
  namespace: default

---
# 2. Role (Was darf gemacht werden?)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-manager
  namespace: default
rules:
- apiGroups: [""] # Core API (Pods, Services, etc.)
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch", "create", "delete"]

---
# 3. RoleBinding (Verbindet Account mit Rolle)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: bind-bot-to-manager
  namespace: default
subjects:
- kind: ServiceAccount
  name: my-bot
  namespace: default
roleRef:
  kind: Role
  name: pod-manager
  apiGroup: rbac.authorization.k8s.io

Cilium & Networking

Hubble (Netzwerk-Röntgenblick)

# Live Traffic beobachten
hubble observe --pod  --follow

# Nur Dropped Packets
hubble observe --verdict DROPPED

DNS-Based Firewall Policies

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
spec:
  egress:
    # 1. DNS erlauben (Wichtig!)
    - toEndpoints:
        - matchLabels:
            "k8s:io.kubernetes.pod.namespace": kube-system
            k8s-app: kube-dns
      toPorts:
        - ports: [{ port: "53", protocol: UDP }]
          rules:
            dns: [{ matchPattern: "*" }]
    # 2. Zugriff auf Domain erlauben
    - toFQDNs:
        - matchName: "gitea.example.com"
      toPorts:
        - ports: [{ port: "443", protocol: TCP }]

YAML Beispiele (Templates)

Kopierfertige Vorlagen für die wichtigsten Kubernetes-Ressourcen.

Deployment

Der Standard für stateless Apps. Sorgt dafür, dass immer X Pods laufen.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

StatefulSet

Für zustandsbehaftete Apps (Datenbanken). Stabile Netzwerknamen (pod-0, pod-1) und persistenter Speicher pro Pod.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql"
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "secret"
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "longhorn"
      resources:
        requests:
          storage: 10Gi

ConfigMap & Secret

Trenne Konfiguration vom Code. Secrets sind base64-kodiert (aber nicht verschlüsselt!).

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_COLOR: "blue"
  LOG_LEVEL: "debug"
---
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
stringData:
  DB_PASSWORD: "supersecret123"

Service (ClusterIP, NodePort, LoadBalancer)

Ein Service macht deine Pods im Cluster erreichbar. Es gibt verschiedene Typen:

  • ClusterIP (Standard): Nur innerhalb des Clusters erreichbar.
  • NodePort: Öffnet einen Port (30000-32767) auf jedem Node. Gut für Tests.
  • LoadBalancer: Fordert eine externe IP vom Cloud-Provider an (teuer, aber einfach).
  • ExternalName: Leitet auf einen externen DNS-Namen weiter (z.B. db.google.com).
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80        # Port des Service
      targetPort: 80  # Port im Container
  type: ClusterIP     # Ändere zu NodePort oder LoadBalancer bei Bedarf

Ingress (HTTP/HTTPS)

Der "Türsteher" für externen Traffic (z.B. via Nginx Ingress Controller).

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - my-app.example.com
    secretName: my-app-tls
  rules:
  - host: my-app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

DaemonSet

Läuft auf jedem Node genau einmal (z.B. für Logs, Monitoring, Networking).

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluent/fluentd:v1.14
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

PVC & Storage (Longhorn)

RWO (ReadWriteOnce): Kann nur von einem Node gleichzeitig gemountet werden (Standard Block Storage).
RWX (ReadWriteMany): Kann von vielen Nodes gleichzeitig genutzt werden (wie NFS/Share).

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce # oder ReadWriteMany (RWX)
  storageClassName: longhorn
  resources:
    requests:
      storage: 10Gi