Proxmox mit Ceph und ceph-csi sinnevoll?

fwinkler

Member
Dec 12, 2021
57
3
13
51
Hi,

wir haben eine Proxmox Cluster mit 5 Nodes mit Ceph. Jetzt wollen wir darauf Kubernetes betreiben.
Aktuell Testen ich gerade CSI Treiber und die Frage bei der ich gerade stehe ist wie sinnvoll es ist auf einen ceph einen ceph-csi oder rook mit External Storage zu verwenden?

Das Kubernetes läuft mit Talos als Betriebssystem auf dem Ceph und greift mit dem ceph-csi Treiber wieder auf das Ceph zu.

Gibt es da nicht eine besser Lösung?
 
Hi,

Das Kubernetes läuft mit Talos als Betriebssystem auf dem Ceph und greift mit dem ceph-csi Treiber wieder auf das Ceph zu.
Nur um es richtig zu verstehen: Ihr habt VMs auf deren Talos/Kubernetes läuft, deren Storage von Ceph gebacked wird. Innerhalb der VMs habt ihr dann wieder einen eigenen Ceph-Cluster erstellt, auf welchen dann ceph-csi zugreift?

Die einfachste Lösung wäre hier ein eigenes CephFS (oder mehrere, je nach Architektur natürlich) für Kubernetes im Proxmox VE Ceph Cluster zu erstellen und ceph-csi direkt auf diese Pools zugreifen zu lassen. Über einen eigenen Ceph User (siehe User Management in der Ceph Dokumentation und Capabilities in der ceph-csi Dokumentation) lassen sich dann auch die Rechte etc. entsprechend verteilen.
So betreibe ich persönlich auch einen Cluster für einen Verein, funktioniert bisher eigentlich problemlos.
 
Nein, Kubernetes VM laufen auf dem Ceph vom Proxmox und der ceph-csi Treiber greift auch auf dem Ceph Cluster vom Proxmox zum.

Die Überlegung war nur: der csi Treiber speichert doch die Daten(mountet ein Verzeichnis) auf dem Host vom Kubernetes zwischen, welches auch Ceph ist. Ist das nicht unperformant?

Bei meinen Tests mit kubestr fio habe ich mit ceph-csi 1600 iops im Schreiben und mit dem Localpath Provider( wäre dann ja auch Ceph) komme ich auf 40000 iops Schreibend
 
You run with us.

You need the ClusterId of the Ceph on proxmox and the Ip addresses of the monitors of your Ceph cluster.
Your Kubernetes host must be able to access the monitors.

I can't say anything about performance. I don't know if the values are ok or not.
 
Hi!
Wir betreiben seit gut 1.5 Jahren einen 4 Node Cluster mit PVE-Ceph + RGW (S3), haben dort VMs mit Kuberenetes und ceph-csi am laufen und hatten noch keine nennenswerten probleme (solange keine applikation amok läuft und massiv IO erzeugt *hust*).

Wir haben damals auch RGW am proxmox dazu installiert um S3 Object storage möglich zu machen (Gitlab).

Heute würde Ich wohl einen anderen weg gehen.
Denn man kann mit Rook ja auch auf externe Cluster zugreifen. https://rook.io/docs/rook/latest-release/CRDs/Cluster/external-cluster/external-cluster/?h=exter

Das gute daran wäre das der Rook Operator sich um alles auf Kubernetes seite kümmert während man auf der Proxmox Seite nur die schon existierenden Tools zu nutzen um einen extra User anzulegen. (Keine zusätzlichen mgr plugins mehr)

Laut dem Design dokument zu dem feature (https://github.com/rook/rook/blob/master/design/ceph/ceph-external-cluster.md#object-storage-rgw) sollte es sogar möglich sein die RGW daemons im Kubernetes laufen zu lassen während diese auf die Pools vom PVE-Ceph cluster zugreifen. Hab das jedoch noch nicht getestet.

PS: Bin gerade dabei das oben genannte in meinem HomeLab Cluster abzubilden und kann, wenn gewollt, updates posten.
Edit: Werde mir das mit dem "Verzeichnis" mounten nochmal ansehen, aber eigentlich sollte das kein problem sein da ceph-csi ja das RBD kernel module benutzt um die PVCs zu mounten. (muss ich dennoch checken ob das auch wirklich so ist)
 
Last edited:
  • Like
Reactions: Johannes S
Okay ich bin endlich dazu gekommen mir das ganze ein wenig genauer anzusehen und habe erfolgreich einen Rook Cluster in Kubernetes deployed welcher auf den Hyperconverged Ceph Cluster von Proxmox zugreift.

Bitte beachtet das die Anleitung schnell mitgeschriebene Notizen sind,

Edit: S3 Object Storage muss Ich mir erst noch weiter ansehen.

Markdown (GitHub flavored):
# Rook in Kubernetes with Proxmox as hyperconverged Ceph

### Special Note

- Use only `RFC 1123` compliant characters for the pool name. Took me a long time to debug this one.

### Prerequisite

- Create an RBD + CephFS pool for Kubernetes to use, needs to be RFC 1123 compliant.

### Deploy Ceph Operator + Cluster

- For the operator no special config is necessary
- For the Cluster it must be deployed with the following values.yaml: [URL]https://github.com/rook/rook/blob/release-1.16/deploy/charts/rook-ceph-cluster/values-external.yaml[/URL]
- For Talos Linux run `kubectl label namespace rook-ceph pod-security.kubernetes.io/enforce=privileged` to allow privileged containers needed for the ceph CNI plugins to work.

### Export external Cluster
[URL]https://rook.io/docs/rook/v1.16/CRDs/Cluster/external-cluster/provider-export/[/URL]

1. Download the `create-external-cluster-resources.py` from the rook Github page.
2. Move it to the Server where the existing ceph cluster is.
3. Run the script with the following permissions to create the necessary users etc.

```bash
python3 create-external-cluster-resources.py \
  --rbd-data-pool-name your-rbd-pool-name \
  --cephfs-filesystem-name your-cephfs-pool-name \
  --k8s-cluster-name your-kubernetes-cluster-name \
  --restricted-auth-permission true \
  --skip-monitoring-endpoint \
  --format bash
```

### Import external cluster
[URL]https://rook.io/docs/rook/v1.16/CRDs/Cluster/external-cluster/consumer-import/#import-the-provider-data[/URL]

1. Copy the `export` parts from the script above.
2. Run the `import-script.sh`.
 
Last edited:
Hi,

mit dem rook-ceph External Cluster das Funktioniert bei uns.

Aktuell haben wir das ganze mit ceph-csi laufen.

Aber beides ist zu langsam.
 
Hi,

mit dem rook-ceph External Cluster das Funktioniert bei uns.

Aktuell haben wir das ganze mit ceph-csi laufen.

Aber beides ist zu langsam.

Ich hätte gerne noch ein paar infos:
- Ist die VM Disk von Talos auch in einem Ceph storage oder Proxmox host local?
- Hast du schon ein RBD auf einem Proxmox host gemounted und dort einen IO test gemacht?
- Ist dein Cluster in dem Ceph läuft eh hoffenltich über 10G NICS angebunden
- Kannst du mir deine `kubestr fio` commands geben zwecks size etc, dann probier ich das bei mir mal aus und kann dir vielleicht vergleichswerte geben
 
Hier sind fio von uns: https://github.com/siderolabs/talos/issues/9754

Die Talos VM laufen auf dem Proxmox im Ceph, das ist richtig.
Die VM haben zwei Nic, eine nur Kubernetes und die zweite Nic ist eine 100G vom public Ceph Netzwerk.

Das war ein Windows Server 2022 VM welche auf dem Ceph läuft, ohne spezielle Einstellungen.

Screenshot 2024-11-25 145658.png
 
Cool danke dann werd Ich das heute abend mal ausprobieren. Noch ne anmerkung: Ich hab das ganze in meinem Homelab am laufen mit 1G daher werden die zahlen natürlich nicht zusammenpassen.

Schuss ins blaue:
Wenn du 2 nics hast hast du da schon mal nen traceroute oder ähnliches laufen lassen um zu sehen ob der mount auch über die richtige NIC läuft?
 
CODE]iperf -c 192.168.1.1 C-m -P 1000[/CODE]
von proxmox zu proxmox:
Code:
[SUM] 0.0000-10.0517 sec   116 GBytes  99.2 Gbits/sec

von kubernetes(talos) zu proxmox :
Code:
[SUM] 0.00-11.37 sec  30.5 GBytes  23.1 Gbits/sec
 
CODE]iperf -c 192.168.1.1 C-m -P 1000[/CODE]
von proxmox zu proxmox:
Code:
[SUM] 0.0000-10.0517 sec   116 GBytes  99.2 Gbits/sec

von kubernetes(talos) zu proxmox :
Code:
[SUM] 0.00-11.37 sec  30.5 GBytes  23.1 Gbits/sec

Also wenn das deine werte sind dann isses klar das das ceph-csi plugin langsamer is als die Disk die direkt in der VM hängt.

Kannst du mal die VM config von einer Talos VM posten?
 
hier mal eine Worker Config:

Code:
version: v1alpha1
debug: false
persist: true
machine:
  type: worker
  token: ***************
  ca:
    crt: *****
    key: ""
  certSANs:
    - 10.144.190.30
    - 127.0.0.1
  kubelet:
    image: ghcr.io/siderolabs/kubelet:v1.30.2
    extraArgs:
      rotate-server-certificates: "true"
    extraMounts:
      - destination: /var/openebs/local
        type: bind
        source: /var/openebs/local
        options:
          - bind
          - rshared
          - rw
    defaultRuntimeSeccompProfileEnabled: true
    nodeIP:
      validSubnets:
        - 10.144.190.0/24
        - 192.168.1.0/24
    disableManifestsDirectory: true
  network:
    hostname: k8s-worker1.dev.plano.internal
    interfaces:
      - interface: eth0
        addresses:
          - 10.144.190.34/24
        routes:
          - network: 0.0.0.0/0
            gateway: 10.144.190.1
        mtu: 1500
        dhcp: false
      - interface: eth1
        addresses:
          - 192.168.1.34/24
        mtu: 9000
        dhcp: false
    nameservers:
      - 10.144.189.2
      - 10.144.189.3
      - 8.8.8.8
    disableSearchDomain: true
  install:
    disk: /dev/sda
    image: factory.talos.dev/installer/7c30a8273598fca56152985b99dd0313b17468204b463c1807a7b9911e9de9e5:v1.7.5
    wipe: false
  files:
    - content: |
        -----BEGIN CERTIFICATE-----
        ****
        -----END CERTIFICATE-----
      permissions: 0o644
      path: /etc/ssl/certs/ca-certificates
      op: append
    - content: |-
        [plugins."io.containerd.grpc.v1.cri"]
          enable_unprivileged_ports = true
          enable_unprivileged_icmp = true
        [plugins."io.containerd.grpc.v1.cri".containerd]
          discard_unpacked_layers = false
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          discard_unpacked_layers = false
      permissions: 0o0
      path: /etc/cri/conf.d/20-customization.part
      op: create
  sysctls:
    fs.inotify.max_queued_events: "65536"
    fs.inotify.max_user_instances: "8192"
    fs.inotify.max_user_watches: "524288"
    net.core.rmem_max: "2500000"
    net.core.wmem_max: "2500000"
  features:
    rbac: true
    stableHostname: true
    apidCheckExtKeyUsage: true
    diskQuotaSupport: true
    kubePrism:
      enabled: true
      port: 7445
    hostDNS:
      enabled: true
      forwardKubeDNSToHost: true
      resolveMemberNames: true
  kernel:
    modules:
      - name: nbd
cluster:
  id: Dzux6EvEApyt751Lg1sqQMNJlufwBPMajOPuzN_lsPg=
  secret: *****
  controlPlane:
    endpoint: https://10.144.190.30:6443
  network:
    cni:
      name: none
    dnsDomain: cluster.local
    podSubnets:
      - 10.69.0.0/16
    serviceSubnets:
      - 10.96.0.0/16
  token: ****
  ca:
    crt: *****
    key: ""
  discovery:
    enabled: true
    registries:
      kubernetes:
        disabled: false
      service:
        disabled: false
 
Hmm hab die route mit `0.0.0.0/0` noch nie selbst benutzt aber sollte das ned sagen das alle routes über das gateway gehen sollen?

Was gibt den `talosctl get routes`
 
Fio results:

  • Proxmox: fio --name=read_iops --size=2G --bs=4k --rw=randread --verify=0 --direct=1 --ioengine=libaio --iodepth=64
  • Kubernets: kubestr fio -n fio -s ceph-fs

Proxmox with Ceph installed and mounted:
Code:
JobName: read_iops
  blocksize=4K filesize=2G iodepth=64 rw=randread
read:
  IOPS=14.7k, BW=57.4MiB/s (60.2MB/s)(2048MiB/35668msec)
  iops: min= 6910, max=22418, avg=14732.68
  bw: min=27640, max=89672, avg=58930.70

Proxmox without Ceph installed but mounted:
Code:
JobName: read_iops
  blocksize=4K filesize=2G iodepth=64 rw=randread
read:
  IOPS=12.9k, BW=50.5MiB/s (52.9MB/s)(2048MiB/40557msec)
  iops: min= 5456, max=22208, avg=12933.31
  bw: min=21824, max=88832, avg=51733.23

Kubernetes:
Code:
Running FIO test (default-fio) on StorageClass (ceph-fs) with a PVC of Size (100Gi)
Elapsed time- 1m29.385812934s
FIO test results:

FIO version - fio-3.36
Global options - ioengine=libaio verify=0 direct=1 gtod_reduce=1

JobName: read_iops
  blocksize=4K filesize=2G iodepth=64 rw=randread
read:
  IOPS=443.255371 BW(KiB/s)=1789
  iops: min=54 max=624 avg=446.258057
  bw(KiB/s): min=216 max=2496 avg=1785.032227

JobName: write_iops
  blocksize=4K filesize=2G iodepth=64 rw=randwrite
write:
  IOPS=150.828690 BW(KiB/s)=619
  iops: min=84 max=218 avg=152.064514
  bw(KiB/s): min=336 max=872 avg=608.451599

JobName: read_bw
  blocksize=128K filesize=2G iodepth=64 rw=randread
read:
  IOPS=418.671600 BW(KiB/s)=54105
  iops: min=102 max=574 avg=422.129028
  bw(KiB/s): min=13056 max=73472 avg=54032.515625

JobName: write_bw
  blocksize=128k filesize=2G iodepth=64 rw=randwrite
write:
  IOPS=150.607803 BW(KiB/s)=19793
  iops: min=100 max=212 avg=151.870972
  bw(KiB/s): min=12800 max=27136 avg=19447.515625

Disk stats (read/write):
  -  OK

Also Ja iwo bleiben da ca. 50% IOPS beim lesen auf der Strecke.
Hab den kubernets fio test jetzt ein paar mal gemacht aber is immer so zwischen 400-450 IOPS für den read_iops task


EDIT: Hab gemerkt das ich den kubestr test für block devices statt CephFS gemcaht habe wobei Proxmox ein CephFS mount ist. Hab das mal korrigiert.
Ceph-Block ist aber generell nochmal ~200 IOPS schneller als CephFS, nur damit man das auch noch berücksichtigt.
 
Last edited:
  • Like
Reactions: Johannes S
Schaut okay aus.
Das einzige was mir jetzt noch einfällt is ein TCP-Dump wenn kubestr läuft um zu sehen ob die packages auch wirklich über die richtige NIC gehen.

Da Ich bei mir das Problem nachstellen kann das IOPS in Proxmox und Talos nicht zusammenpassen nehme Ich mal an das es wirklich ein Talos/Cilium/Rook config problem ist und nix mit Proxmox zu tun hat.

Daher würde Ich vorschlagen das wir die diskussion nach: https://github.com/siderolabs/talos/issues/9754 verlegen.
Ich werde die tage mal einen Iperf test auch bei mir machen und die Daten + die benchmarks von oben in dem Github issue posten, da Ich ein homelab hab isses mir auch egal wenn ich detailiertere infos zum cluster bereit stelle.
 
Ich denke inzwischen die gehen über die falsche Nic.
Die zweite Nic ist auf dem Proxmox ein bond aus 3 x 10G .
Die wo ceph drüber gehen sollte ist eine 100G.
 
Ja das dachte Ich auch deswegen der output von `talosctl routes` aber was imho dagegen spricht ist das Ich es verifizieren kann das IOPS in Kubernetes einfach echt grotten schlecht ist.

Und bei mir haben die VMs alle nur 1 NIC