Test Umgebung mit K3s aufsetzten

Hallo Philipp,

ich habe das mit unserem openDesk-Deployment verglichen.

Bei uns ist OX/AppSuite nicht über nginx, sondern explizit über HAProxy Ingress angebunden. Unsere relevanten Werte sind sinngemäß:

ingress:
ingressClassName: „haproxy“
controller: „haproxy“

und für OX setzen wir zusätzlich den internen Objectstore-Endpunkt:

objectstores:
openxchange:
endpoint: „http://minio:9000

Das steht bei uns nicht als Kubernetes-Manifest, sondern als Helmfile-Werte/Release-Customization. Daher: bitte nicht mit kubectl apply -f helmfile/environments/default/objectstores.yaml.gotmpl anwenden. *.gotmpl sind Helmfile-Templates. Nach einer Änderung muss openDesk wieder über Helmfile angewendet werden, also sinngemäß:

helmfile apply

bzw. mit deinem üblichen Environment-/Namespace-Parameter.

Wichtig: Dass minio auf der SLES-/Proxmox-VM selbst nicht auflösbar ist, ist normal. Der Name minio ist Kubernetes-DNS und gilt innerhalb der Pods im Namespace. Bitte keine 10.42.x.x-Pod-IP in die Werte schreiben, die ist nicht stabil.

Test aus dem Cluster heraus:

NS=opendesk3

kubectl -n „$NS“ run minio-test
–rm -i --restart=Never
–image=curlimages/curl
– curl -i http://minio:9000/

Ein 403 Forbidden von MinIO ist dabei nicht automatisch ein Fehler. Ohne Credentials darf MinIO so antworten.

Der aktuelle Fehler sieht für mich aber zuerst nach Ingress/API-Route aus, nicht nach MinIO:

/appsuite/ → HTTP 200
/appsuite/api… → HTTP 404 / NOSERVER

Das heißt: Das statische AppSuite-UI wird ausgeliefert, aber die API-Route landet nicht korrekt bei der OX-Middleware.

Ich würde daher zuerst prüfen, ob die OX-AppSuite-API-Ingressroute existiert und zur tatsächlich installierten Ingress-Klasse passt:

NS=opendesk3
HOST=webmail.my-domain.cloud

kubectl get ingressclass

kubectl -n „$NS“ get ingress | grep -Ei ‚open-xchange|appsuite‘
kubectl -n „$NS“ get svc,endpoints | grep -Ei ‚open-xchange|core-mw|core-ui‘

kubectl -n „$NS“ describe ingress open-xchange-appsuite-http-api-routes-appsuite-api
kubectl -n „$NS“ get ingress open-xchange-appsuite-http-api-routes-appsuite-api -o yaml

curl -k -i „https://${HOST}/appsuite/api?action=config&version=8.46.4“ | sed -n ‚1,80p‘
curl -k -i „https://${HOST}/appsuite/api/login?action=autologin“ | sed -n ‚1,80p‘

Wenn die Ingressroute fehlt, auf die falsche ingressClassName zeigt oder der Cluster z.B. nginx verwendet, die openDesk-Werte aber auf HAProxy stehen, passt das Fehlerbild sehr gut.

Also: Den internen OX-Objectstore-Endpunkt setzen wir auch so. Der 404 auf /appsuite/api ist aber wahrscheinlich zuerst ein Ingress-/Controller-Mismatch. Besonders prüfen würde ich nginx vs. HAProxy und die Route open-xchange-appsuite-http-api-routes-appsuite-api.

Hallo,

also eingerichtet habe ich gemäß Blog-Eintrag nur den Nginx Ingress.

sles-k3s:~ # kubectl get ingressclass
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       20d
sles-k3s:~ # kubectl get ingress | grep -Ei "open-xchange|appsuite"
open-xchange-appsuite-appsuite-base                  nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-caldav-well-known-redirect     nginx   dav.mydomain.cloud                        192.168.0.1   80, 443   14d
open-xchange-appsuite-carddav-well-known-redirect    nginx   dav.mydomain.cloud                        192.168.0.1   80, 443   14d
open-xchange-appsuite-core-help-route                nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-core-ui-api-route              nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-dav-infostore-route            nginx   dav.mydomain.cloud                        192.168.0.1   80, 443   14d
open-xchange-appsuite-dav-root-route                 nginx   dav.mydomain.cloud                        192.168.0.1   80, 443   14d
open-xchange-appsuite-guard-api-route                nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-guard-pgp-route                nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-guard-support-api-route        nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-http-api-routes-ajax           nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-http-api-routes-api            nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-http-api-routes-appsuite-api   nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-office-web-route               nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-rest-routes-admin              nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-rest-routes-advertisement      nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-rest-routes-chronos            nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-rest-routes-preliminary        nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-rest-routes-userfeedback       nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-rootredirect                   nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-rt2-route                      nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-static-routes-infostore        nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-static-routes-realtime         nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-static-routes-servlet          nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
open-xchange-appsuite-static-routes-webservices      nginx   webmail.mydomain.cloud                    192.168.0.1   80, 443   14d
sles-k3s:~ # kubectl get svc,endpoints | grep -Ei "open-xchange|core-mw|core-ui"
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
service/open-xchange-core-documentconverter         ClusterIP   10.43.27.219    <none>        8008/TCP,8011/TCP,8017/TCP                                                                     14d
service/open-xchange-core-guidedtours               ClusterIP   10.43.232.130   <none>        80/TCP                                                                                         14d
service/open-xchange-core-imageconverter            ClusterIP   10.43.32.216    <none>        8005/TCP,8018/TCP                                                                              14d
service/open-xchange-core-mw-admin                  ClusterIP   10.43.147.146   <none>        80/TCP                                                                                         14d
service/open-xchange-core-mw-businessmobility       ClusterIP   10.43.148.4     <none>        80/TCP                                                                                         14d
service/open-xchange-core-mw-http-api               ClusterIP   10.43.56.251    <none>        80/TCP                                                                                         14d
service/open-xchange-core-mw-request-analyzer       ClusterIP   10.43.187.157   <none>        80/TCP                                                                                         14d
service/open-xchange-core-mw-sync                   ClusterIP   10.43.135.200   <none>        80/TCP                                                                                         14d
service/open-xchange-core-ui                        ClusterIP   10.43.225.228   <none>        80/TCP,9090/TCP                                                                                14d
service/open-xchange-core-ui-middleware             ClusterIP   10.43.188.230   <none>        80/TCP,9090/TCP                                                                                14d
service/open-xchange-core-user-guide                ClusterIP   10.43.125.21    <none>        80/TCP                                                                                         14d
service/open-xchange-gotenberg                      ClusterIP   10.43.190.17    <none>        80/TCP                                                                                         14d
service/open-xchange-guard-ui                       ClusterIP   10.43.4.80      <none>        80/TCP                                                                                         14d
service/open-xchange-nextcloud-integration-ui       ClusterIP   10.43.45.189    <none>        80/TCP                                                                                         14d
service/open-xchange-public-sector-ui               ClusterIP   10.43.190.71    <none>        80/TCP                                                                                         14d
endpoints/open-xchange-core-documentconverter         10.42.0.183:8017,10.42.0.183:8008,10.42.0.183:8011               14d
endpoints/open-xchange-core-guidedtours               10.42.0.181:8080                                                 14d
endpoints/open-xchange-core-imageconverter            10.42.0.182:8018,10.42.0.182:8005                                14d
endpoints/open-xchange-core-mw-admin                  10.42.0.119:8009                                                 14d
endpoints/open-xchange-core-mw-businessmobility       10.42.0.119:8009                                                 14d
endpoints/open-xchange-core-mw-http-api               10.42.0.119:8009                                                 14d
endpoints/open-xchange-core-mw-request-analyzer       10.42.0.119:8009                                                 14d
endpoints/open-xchange-core-mw-sync                   10.42.0.119:8009                                                 14d
endpoints/open-xchange-core-ui                        10.42.0.184:8080,10.42.0.184:9090                                14d
endpoints/open-xchange-core-ui-middleware             10.42.0.180:9090,10.42.0.185:9090,10.42.0.180:8080               14d
endpoints/open-xchange-core-user-guide                10.42.0.179:8080                                                 14d
endpoints/open-xchange-gotenberg                      10.42.0.178:3000                                                 14d
endpoints/open-xchange-guard-ui                       10.42.0.186:8080                                                 14d
endpoints/open-xchange-nextcloud-integration-ui       10.42.0.188:8080                                                 14d
endpoints/open-xchange-public-sector-ui               10.42.0.189:8080                                                 14d
sles-k3s:~ # kubectl describe ingress open-xchange-appsuite-http-api-routes-appsuite-api
Name:             open-xchange-appsuite-http-api-routes-appsuite-api
Labels:           app.kubernetes.io/managed-by=Helm
Namespace:        opendesk
Address:          192.168.0.1
Ingress Class:    nginx
Default backend:  <default>
TLS:
  opendesk-certificates-tls terminates webmail.mydomain.cloud
Rules:
  Host                      Path  Backends
  ----                      ----  --------
  webmail.mydomain.cloud
                            /appsuite/api   open-xchange-core-mw-http-api:80 (10.42.0.119:8009)
Annotations:                haproxy-ingress.github.io/affinity: cookie
                            haproxy-ingress.github.io/path-type: prefix
                            haproxy-ingress.github.io/proxy-body-size: 100M
                            haproxy-ingress.github.io/session-cookie-name: http-api-routes-appsuite-api
                            haproxy-ingress.github.io/timeout-client: 60s
                            haproxy-ingress.github.io/timeout-server: 60s
                            meta.helm.sh/release-name: open-xchange
                            meta.helm.sh/release-namespace: opendesk
                            nginx.ingress.kubernetes.io/affinity: cookie
                            nginx.ingress.kubernetes.io/proxy-body-size: 100M
                            nginx.ingress.kubernetes.io/proxy-read-timeout: 60
                            nginx.ingress.kubernetes.io/proxy-send-timeout: 60
                            nginx.ingress.kubernetes.io/rewrite-target: /appsuite/api$1
                            nginx.ingress.kubernetes.io/session-cookie-change-on-failure: true
                            nginx.ingress.kubernetes.io/session-cookie-name: http-api-routes-appsuite-api
                            nginx.ingress.kubernetes.io/session-cookie-path: /
                            nginx.ingress.kubernetes.io/use-regex: true
Events:                     <none>
sles-k3s:~ # kubectl -n $NS get ingress open-xchange-appsuite-http-api-routes-appsuite-api -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    haproxy-ingress.github.io/affinity: cookie
    haproxy-ingress.github.io/path-type: prefix
    haproxy-ingress.github.io/proxy-body-size: 100M
    haproxy-ingress.github.io/session-cookie-name: http-api-routes-appsuite-api
    haproxy-ingress.github.io/timeout-client: 60s
    haproxy-ingress.github.io/timeout-server: 60s
    meta.helm.sh/release-name: open-xchange
    meta.helm.sh/release-namespace: opendesk
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/proxy-body-size: 100M
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/rewrite-target: /appsuite/api$1
    nginx.ingress.kubernetes.io/session-cookie-change-on-failure: "true"
    nginx.ingress.kubernetes.io/session-cookie-name: http-api-routes-appsuite-api
    nginx.ingress.kubernetes.io/session-cookie-path: /
    nginx.ingress.kubernetes.io/use-regex: "true"
  creationTimestamp: "2026-05-18T10:33:24Z"
  generation: 1
  labels:
    app.kubernetes.io/managed-by: Helm
  name: open-xchange-appsuite-http-api-routes-appsuite-api
  namespace: opendesk
  resourceVersion: "460776"
  uid: 69ebc8b2-c849-4c07-b1c6-ceb8fd42c32a
spec:
  ingressClassName: nginx
  rules:
  - host: webmail.mydomain.cloud
    http:
      paths:
      - backend:
          service:
            name: open-xchange-core-mw-http-api
            port:
              number: 80
        path: /appsuite/api
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - webmail.mydomain.cloud
    secretName: opendesk-certificates-tls
status:
  loadBalancer:
    ingress:
    - ip: 192.168.0.1

Sieht für mich so erstmal korrekt aus.

Sollte ich jetzt den haproxy-ingress installieren und OX zuweisen?