Beim Ausfall einer Kubernetes Node bleiben Pods im Terminating Status hängen

Kubernetes ist eigentlich dazu da, eine Infrastruktur in Code zu gießen, sie einfach skalieren zu können und dass sich das System im Problemfall “selbst heilt”. Das funtkioniert in der Regel auch ganz gut, aber besonders die “Selbstheilung” hat so ihre Grenzen. In meinem Fall handelt es sich um gemountete Volumes / PCVs, die nur einmal verwendet werden dürfen. Sprich, immer nur genau ein Pod darf dieses Volume mounten.

Das ist z.b. bei Ceph oder NFS mounts der Fall.

In meinem lokalen Cluster aus mehreren Intel NUCs habe ich nun das Problem, dass wenn eine Node ausfällt/vom Strom getrennt wird, dass die Node zwar sehr schnell als fehlend markiert wird und nach 5 Minuten dann auch die Pods das gleiche Schicksal ereilt. Wenn Kubernetes aber nun versucht, die Pods auf einer anderen Node neu zu starten, dann scheitert es daran, dass Kubernetes an dieser Stelle nicht genau weiß, ob die Pods wirklich weg sind oder nur die Infrastruktur selbst nicht richtig kommuniziert. Daher geht es davon aus, dass die Mounts noch beim alten Pod aktiv sind, bis es die endgültige Meldung bekommt, dass der alte Pod wirklich weg ist. Da die Node aber zu diesemn Zeitpunkt keinen Strom mehr hat, kann sie auch nie melden, dass der Pod nicht mehr läuft. Und so wartet Kubernetes einfach bzw. verharrt in diesem unklaren Zustand.

Man kann nun anfangen, die Pods manuell mit einem Force zu löschen, dann werden sie nach einiger Zeit ihre Resourcen wieder frei geben und der neue Pod kann starten. Um dies auch zu automatisieren, kann man sich aber auch mit einem Cron Job innerhalb des Clusters behelfen. Und das sieht dann so aus:

Service Account und RBAC Rolle anlegen:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: cleanup-bot
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cleanup-bot-role
rules:
- apiGroups: [""]
  resources: ["pods", "nodes"]
  verbs: ["get", "list", "delete"]
- apiGroups: ["storage.k8s.io"]
  resources: ["volumeattachments"]
  verbs: ["list", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cleanup-bot-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cleanup-bot-role
subjects:
- kind: ServiceAccount
  name: cleanup-bot
  namespace: default

Wenn das eingerichtet ist, kann man den Cronjob so anlegen:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: pod-cleanup-dead-nodes
  namespace: default
spec:
  schedule: "*/10 * * * *" # alle 10 Minuten
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: cleanup-bot
          containers:
          - name: cleanup
            image: bitnami/kubectl:latest
            command:
            - /bin/sh
            - -c
            - |
              for node in $(kubectl get nodes --no-headers | awk '$2 == "NotReady" {print $1}'); do
                echo "Cleaning up pods on $node"
                kubectl get pods --all-namespaces --field-selector spec.nodeName=$node -o json \
                  | jq -r '.items[] | select(.metadata.deletionTimestamp != null) | "kubectl delete pod -n \(.metadata.namespace) \(.metadata.name) --grace-period=0 --force"' \
                  | sh
              done
          restartPolicy: OnFailure

Dieser Cronjob schaut alle 10 Minuten nach, ob es Nodes gibt, die im Status “NotReady” sind. Für alle Nodes in diesem Status werden die Pods auf dieser Node ausgelesen und einzeln per kubectl und keiner Grace-Period gelöscht.

In meinem Fall hat dies genau die Lösung gebracht, die ich gesucht habe. Erst ist die Node nicht mehr erreichbar, dann failen die Pods und Kubernetes versucht sie neu auf anderen Nodes zu starten, scheitert aber daran wegen der noch offenen Volume Mounts. Nach max. 10 Minuten kommt der Cronjob und beendet alle Pods hart und löst damit den Volume mount auf, worauf sich nach kurzer Zeit die “neuen” Pods aus ihrem Pending Status befreien und korrekt hochfahren.

Wie kann man minikube mit lokalen Dockerfiles verwenden?

Minikube ist der perfekte Partner, wenn es darum geht, auf dem eigenen Rechner mal schnell ein Kubernetes Setup zu testen bzw. für die Entwickung.

Aber wie bekommt man ein lokales Image bzw. ein Dockerfile in Minikube, sodass man es z.B. für Deployments verwenden kann?

Mane ersetzt einfach docker mit minikube:

minikube build -t mein-image-name:latest .

Innerhalb eines Deployments kann man nun so auf das Image zugreifen:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mein-app-name
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mein-app-name
  template:
    metadata:
      labels:
        app: mein-app-name
    spec:
      containers:
        - name: mein-app-name
          image: mein-image-name:latest
          imagePullPolicy: Never #oder 'IfNotPresent'

Das entscheidende ist tatsächlich die imagePullPolicy – wenn diese nicht auf Never oder IfNotPresent gesetzt wird, dann versucht minikube bzw. kubernetes das image von Docker Hub zu laden.

Alternativ zu “build” kann man mittels “load” auch ein Image, welches man mittels “docker build” gebaut hat, in die minikube registry kopieren.

Call of Duty Black Ops 6 mit schlechtem Sound bei Bluetooth Headsets

Extrem nervig, im neuen black ops hatte ich einen extrem schlechten Sound mit meinen Sony wh1000xm3, bis ich auf diese Lösung gefunden habe:

Windows Suchleiste öffnen und dort nach “Dienste” suchen. Alternativ kann man auch nach “services.msc” suchen. Dann die gefundene App starten und in der Liste nach “Bluetooth Audio Gateway Service” suchen. Diesen Dienst beenden bzw. komplett deaktivieren.

Anschließend black ops starten und den nun viel besseren Sound genießen.

Hintergrund: Bluetooth Audio hat mehrere Profile. Eines davon ist der headset Modus inkl. Mikrofon, der jedoch die Audio Qualität massiv runterschraubt. Indem man den Dienst beendet zwingt man black ops dieses headset Profil nicht zu verwenden und damit wird der Sound wieder korrekt abgespielt.

Wichtig: natürlich geht nun das Mikro deines Bluetooth Headsets nicht mehr, du musst also wenn dann ein kabelgebundenes Mikro verwenden, falls du eines benutzen möchtest.

Neuer k3s Server kann einem bestehenden Cluster nicht joinen weil die SSL certs nicht verifiziert werden können

Wenn du zu einem bestehenden k3s Cluster eine neue Node hinzufügen möchtest und beim Start dieser Node diese Fehlermeldung

“/var/lib/rancher/k3s/server/… newer than datastore and could cause a cluster outage. Remove the file(s) from disk and restart to be recreated from datastore.”

erscheint, dann ist die empfohlene Lösung nicht ganz ausreichend. Du musst die entsprechenden Dateien nicht löschen, sondern mit von einer bereits aktiven Node des Clusters kopieren und quasi damit auf der neuen Node erstetzen. Achtung: Es werden nicht sofort alle problematischen Dateien aufgelistet, beim nächsten Versuch kommen evtl weitere derartige Meldungen.

Wenn man dann alle diese Dateien ersetzt hat, sollte Join zum Cluster funktionieren.

Wie man SSL für local self hosted Services mit Kubernetes für Mac und IOS einrichtet

Wenn man lokal ein paar Services hosted, dann möchte man natürlich trotzdem SSL Verschlüsselung nutzen – zum einen um einfach die ständigen Sicherheitswarnungen vom Browser zu unterbinden, aber auch da man einfach keinem Netzwerk blind vertrauen sollte – selbst dem eigenen. In meinem Fall kam dann noch hinzu, dass manche iOS Apps zwingend nach gültigen SSL Zertifikaten verlangen.

Lokale SSL Zertifikate sind self-signed bzw. Selbst-Signiert. Normalerweise werden Zertifikate von diveresen Anbietern im Netz gegen Geld angeboten, damit diese sicherstellen, dass man auch die Person/Firma ist, die man vorgibt zu sein. In den letzten Jahren hat Let’s encrypt diese Abzocke endlich beendet und das ganze kostenlos gemacht, indem die Verifizierung automatisiert per DNS+HTTP Abfragen automatisiert werden konnte.

Alle diese Anbieter funktionieren nur, weil Betriebssysteme und Browser diesen Stellen vertrauen und damit Zertifikaten, die von diesen sogn. root certificates beglaubigt wurden, auch vertrauen . Dabei ist das root Zertifikat in der Regel unendlich lange gültig, alle Sub-Zertifikate die von dieser Stelle ausgegeben wurden sind jedoch in der Regel zeitlich begrenzt.

Dieser ganze Hokuspokus wird erstmal nur gemacht, um Vertrauen herzustellen und sicherzustellen, dass wenn ich google.com aufrufe und dort steht, dass die Verbindung gesichert ist und der Gegenstelle vertraut wird, dass dem auch so ist. Damit wird z.b. verhindert, dass ich zwar mit einer Website spreche, die behauptet google.com zu sein, aber eigentlich ein Man-in-the-middle Angreifer ist, der mich verdeckt auf einen anderen Server geleitet hat.

Denn unabhängig vom Vertrauen kann man natürlich die Verbindung mit den Zertifikaten verschlüsseln, nur bringt das eben nicht viel wenn ich nicht weiß, ob mein Gegenüber das richtige Gegenüber ist.

Das erstmal zu den Grundlagen.

Das Vorgehen für lokale Self-Signed Zertifikate ist etwas anders: Zunächst erstellen wir uns eine CA, also eine eigene Ausgabestelle für Zertifikate. Anschließend müssen wir diese CA auf allen unseren Geräten hinterlegen und ihr das Vertrauen aussprechen. Ab diesem Moment können wir damit neue Unterzertifikate erstellen, denen dann auf allen diesen Geräten automatisch auch vertraut wird und eine SSL Verbindung zustande kommt.

In meinem Fall wollte ich das ganze so einfach wie möglich halten und habe mich daher für ein Lokales Wildcard Zertifikat (*.bytelude.intern) entschieden.

Die Schritte dafür sind folgende:

Zertifikate erstellen

1. CA Key und Cert anlegen (bitte ein sicheres Passwort verwenden, wenn danach gefragt wird und dieses sicher hinterlegen!):

openssl genpkey -algorithm RSA -aes128 -out private-ca.key -outform PEM -pkeyopt rsa_keygen_bits:2048
openssl req -x509 -new -nodes -sha256 -days 3650 -key private-ca.key -out self-signed-ca-cert.crt

2. Key und Certificate Request für das Bytelude Unterzertifikat anlegen

openssl genpkey -algorithm RSA -out bytelude.key -outform PEM -pkeyopt rsa_keygen_bits:2048
openssl req -new -key bytelude.key -out bytelude.csr

3. Config für das Bytelude Unterzertifikat anlegen. Inhalt der Datei bytelude.ext:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.bytelude.intern
# Optionally add IP if you're not using DNS names:
IP.1 = 192.168.1.3

Sowohl für den DNS als auch den IP Eintrag könnt ihr mehrere Einträge mit fortlaufender Nummer machen.

4. Bytelude Unterzertifikat erzeugen

openssl x509 -req -in bytelude.csr -CA self-signed-ca-cert.crt -CAkey private-ca.key -CAcreateserial -out bytelude.crt -days 365 -sha256 -extfile bytelude.ext

Dieses letzte Zertifikat ist nun das konkrete Zertifikat, welches ihr z.B. im Webserver hinterlegt. Dieses ist in diesem Beispiel ein Jahr lang gültig und muss dann erneuert werden – dafür reicht dieser letzte Befehl aus, sofern die restlichen Dateien noch da sind.

Die Datei “self-signed-ca-cert.crt” ist das Zertifikat, welches ihr auf euren Geräten hinterlegen müsst.

Mac

Auf dem Mac zieht man es einfach in die Schlüsselbundverwaltung. Anschließend öffnet ihr die Informationen zu diesem Zertifikat und stellt dort das Vertrauen auf “Immer vertrauen”.

iPhone/iPad

Schickt euch das Root CA Cert (“self-signed-ca-cert.crt”) per Airdrop oder anderweitig an das entsprechende Gerät. Anschließend öffnet/installiert ihr es auf dem Gerät und geht dann in: Einstellungen, Allgemein und dann “VPN und Geräteverwaltung” und installiert dort das neue Zertifikat final.

Anschließend muss dem neu installierten Zertifikat noch das Vertrauen ausgesprochen werden, was über Einstellungen, Allgemein, Info und dann “Zertifikatsvertrauenseinstellungen” erledigt wird:

Wenn dieser Schalter aktiviert ist, dann werden ab sofort alle Zertifikate von dieser CA als vertrauenswürdig eingestuft, also auch eure Unterzertifikate.

 

Kubernetes

Als letzten Schritt muss nun noch das Unterzertifikat in eure Kubernetes Instanz eingespielt werden. Das geht über folgenden Befehl:

kubectl -n kube-system create secret tls default-ingress-cert --key=bytelude.key --cert=bytelude.crt --dry-run=client --save-config -o yaml  | kubectl apply -f -

Zusätzlich müsst ihr noch folgende Ressource in eurem Kubernetes System entweder anlegen oder editieren:

apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
  name: default
  namespace: kube-system
spec:
  defaultCertificate:
    secretName: default-ingress-cert

In meinem Fall ist Traefik der Default Ingress, bei Nginx könnte das Vorgehen evtl abweichen.

Nachdem all das erledigt ist, muss beim jeweiligen Service nur noch der Ingress so konfiguriert werden, dass er auch TLS/SSL spricht:

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: freshrss
  namespace: freshrss
  annotations:
    kubernetes.io/ingress.global-static-ip-name: freshrss-ip
spec:
  tls:
  - hosts:
      - freshrss.bytelude.intern
  rules:
  - host: freshrss.bytelude.intern
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: freshrss
            port:
              number: 80

Damit das funktioniert müsst ihr natürlich die entsprechende URL in eurem DNS (z.B. freshrss.bytelude.intern) hinterlegt haben. In meinem Fall habe ich in meinem Ubiquity Router einfach eine Wildcard DNS hinterlegen können, sodass alles was *.bytelude.intern ist auf die gleiche IP zeigt.

Wenn ihr nun alles richtig gemacht habt, dann sollte beim Aufruf von https://freshrss.bytelude.intern keine Sicherheits-Warnung kommen und das Schlosssymbol eures Browsers sollte auch geschlossen sein und somit eine sichere Verbindung vorhanden sein.

Wenn das eine Jahr herum ist und ihr ein neues Unterzertifikat erstellt habt, sollte ein erneutes Ausführen des Befehls

kubectl -n kube-system create secret tls default-ingress-cert --key=bytelude.key --cert=bytelude.crt --dry-run=client --save-config -o yaml | kubectl apply -f -

ausreichen, sodass ab sofort das neue Zertifikat verwendet wird. Damit sollte sich das ganze auch relativ einfach automatisieren lassen.

k3s graceful shutdown im Cluster Betrieb – oder wie keine Pods mehr in der Schwebe hängen bleiben

Um einen eigenen Playground zu haben, steht bei mir nun schon seit einer Weile ein Proxmox Cluster, bestehend aus mehreren Intel NUCs der meine lokalen Services hosted. Unter anderem läuft darauf auch ein k3s cluster mit mehreren Nodes.

Da Kubernetes / k8s eigentlich ein “selbstheilendes” System ist, bin ich bisher davon ausgegangen, dass man ohne Probleme einzelne Nodes aus dem Cluster nehmen kann, ohne dass man sonderlich lange Downtimes hat. Das ist auch korrekt, wenn man Services mit mehreren Instanzen hat, wird jedoch schwer, wenn Services nur aus einzelnen Instanzen bestehen. Mir ist bewusst, dass es dann natürlich kein HA (High Availability) Betrieb ist, aber das ist bei mir lokal auch nicht notwendig. Für mich ist nur wichtig, dass wenn einer der NUCs mal aussteigen sollte, dass meine Services sich selbst heilen und dann auf einer anderen Node weiter laufen.

Beim experimentieren mit diesen Anforderungen habe ich dann schnell gelernt, dass k8s bzw. k3s sich nicht so verhält wie von mir erwartet. Das gewollte Verhalten ist nämlich, dass wenn eine Node für den Cluster nicht erreichbar ist, erstmal für 5 Minuten nichts passiert. Die Hoffnung des Systems ist, dass es sich nur um einen kurzen Restart handelt oder aber z.b. Upgrades gemacht werden. Da k8s ja eine Orchestrierung ist, ist es möglich, dass nur der k8s Service selbst heruntergefahren / neu gestartet wird, die Container/Pods aber einfach weiter laufen.

Bis hierhin macht das für mich auch Sinn, aber das Verhalten wird komisch, wenn man die Node mittels “reboot” neu startet oder per “shutdown” herunterfährt. K8s/k3s verhält sich an dieser Stelle nämlich genauso. Obwohl es wissen sollte, dass ein Shutdown ansteht und somit die Pods auch gestoppt werden, teilt es dies dem restlichen Cluster nicht mit. Und somit wartet der restliche Cluster 5 Minuten, ehe er irgendwas macht.

Wenn die Node als nach 5 Minuten nicht wieder da ist, dann fangen die anderen Nodes an, die Pods zu verschieben bzw. neue Instanzen hochzufahren. Das ist erstmal eine gute Idee, aber im k8s Kontext sind die “alten” Instanzen noch da. Und hier wird es tricky, sobald man Container hat, die z.B. Volumes verwenden. In meinem Fall sind es Volumes innerhalb eines Ceph Clusters, aber das gleiche wird auch bei anderen Formen von Volumes passieren: der Claim auf diese Volumes erlaubt nur einen einzelnen Zugriff, und keinen Zugriff von mehreren Pods gleichzeitig. In meinem speziellen Fall blockiert also der Controller, der die Ceph Volumes bereit stellt, dass der neue Pod hochfahren kann, da er nicht weiß, was mit dem “alten” Pod ist. So lange also die eben heruntergefahrene k3s Node nicht wieder für den Cluster erreichbar ist, verharrt der Pod in diesem Zustand. Das zum Thema selbstheilend.

Ich habe das Problem für mich nun so gelöst, dass ich auf jeder k3s Node einen Cleanup Service neben dem eigentlichen k3s Service laufen lasse. Dieser Service startet NACH dem k3s Service, wird aber VOR der Beendigung des k3s Services auch ordentlich beendet.

Der Service sieht so aus (%H ist der Hostname, meine Nodes heißen jeweils wie ihr Hostname):

[Unit]
Description=k3s node drain on shutdown
After=k3s.service
Before=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/k3s-enable-node.sh %H
RemainAfterExit=true
ExecStop=/usr/local/bin/k3s-drain-node.sh %H
[Install]
WantedBy=multi-user.target

Die beiden Scripte haben diesen Inhalt:

k3s-enable-node.sh

#!/bin/bash
kubectl uncordon $1

k3s-drain-node.sh

#!/bin/bash
node_name=$1
kubectl drain $node_name
sleep 5
set +e
kubectl get pods --all-namespaces --field-selector spec.nodeName=$node_name | tail +2 | grep -v "csi-rbdplugin" | grep -v "svclb-traefik" | awk '{print $2 " --namespace=" $1}' | xargs -n 2 kubectl delete pod -o name
sleep 20

Die sleep Befehle habe ich zur Sicherheit drin, weil kubectl Commands ja nicht immer zu 100% synchron ablaufen. Kann sein, dass das übertrieben ist. Das “set +e” ist drin, weil das Stoppen einzelner Pods evtl Fehler wirft und in diesem Fall das ganze Script failen würde. Da ich hier aber nur versuche noch zu retten was zu retten ist, ignoriere ich die Fehler und versuche so viele Pods wie möglich zu verschieben.

Wenn ich nun einen shutdown oder reboot command auf einer meiner k3s Nodes ausführe, dann wird zuerst das k3s-drain-node.sh Script ausgeführt. Es markiert die k3s Node, dass auf dieser keine neuen Pods mehr gestartet werden dürfen und auch kein Processing mehr passiert. Anschließend lasse ich mir eine Liste mit allen Pods, die auf dieser Node laufen ausgeben, formatierte die etwas um, ignoriere einzelne Pods die ohnehin fest an diese Node gepinnt sind und nirgendwo anders laufen und lösche dann alle Pods, die übrig bleiben. Da die aktuelle Node keine neuen Pods mehr starten darf, werden diese ordnungsgemäß beendet und auf den anderen Nodes im Cluster neu gestartet. Erst wenn das erledigt ist fährt sich die eigentliche Node herunter. Somit habe ich natürlich eine kleine Downtime, aber innerhalb kürzester Zeit ist der jeweilige Pod ja dann wieder erreichbar und ich habe keine permanenten Ausfälle mehr. Ohne diese Scripts würde es also mindestens 5 Minuten dauern, ehe der Pod woanders hin verschoben werden würde, und selbst dann ist aufgrund der Volume Problematik nicht sicher, ob er überhaupt neu gestartet werden kann.

nip.io – deine dynamische Domain für beliebige IP Adressen

Ein Kollege hat mir den Dienst nip.io gezeigt, der extrem praktisch ist, wenn man schnell und unkompliziert eine Domain benötigt, die auf eine spezielle IP zeigt.

Das Prinzip ist relativ einfach, denn bei nip.io ist die Ziel IP direkt ein Teil der Domain:

optionale-subdomain.192.168.1.10.nip.io

Den Teil optionale-subdomain kann man beliebig nutzen/ändern oder auch einfach weg lassen, der Rest erklärt sich glaube ich relativ leicht selbst 🙂

Eine bestehende Flux Installation upgraden

Wenn man z.B. beim bootstrap von Flux die Services für image-reflector-controller und image-automation-controller vergessen hat und diese nachinstallieren möchte, dann wird man zumindest in der offiziellen Doku nicht so recht darauf hingewiesen.

Die Lösung ist dann doch relativ einfach: in eurem Flux Ordner folgendes (natürlich für euer System angepasst) ausführen und anschließend per git commiten/pushen:

flux install \
--components-extra image-reflector-controller,image-automation-controller \
--export > ./clusters/my-cluster/flux-system/gotk-components.yaml

[Quicktip] Auf dem Ubiquity Edge Router X einen Wildcard DNS Eintrag anlegen

Auf dem Ubiquity Edge Router X kann man ja wunderbar unter Wizards –> DNS Host Names statische DNS Einträge mit “Hostname –> IP” setzen. Allerdings eben nur einzeln. Wenn man einen Wildcard DNS Eintrag anlegen will, der “*.bytelude.intern” auf die IP “192.168.1.10” weiterleitet, dann geht das so:

  1. Edge Router X UI aufrufen
  2. Menüpunkt “Config Tree” öffnen
  3. service –> dns –> forwarding auswählen
  4. auf der rechten seite bei “options” auf “+Add” klicken und dann in das Textfeld folgendes schreiben:
    address=/.bytelude.intern/192.168.1.10
  5. Auf Preview/Speichern drücken und der Eintrag ist sofort aktiv. Nun könnt ihr auf eurem Rechner test.bytelude.intern anpingen und das DNS Ergebnis sollte die IP 192.168.1.10 sein.

Wichtig ist der Punkt vor der Domain, damit es als Wildcard funktioniert!

Defektes Teasi One 3 extend wiederherstellen

Mein Schwiegervater hat ein Fischer E-Bike und zumindest eine Zeit lang hatten die als Fahrradcomputer ein Tahuna Teasi One 3 extend mit dabei. Das Teil ist ein Windows CE PocketPC mit Touch Screen und da drauf läuft Tahuna, was quasi ein Open Streetmap Client mit Spezialisierung auf Fahrrad fahren ist. Der Hersteller dieses Gerätes ist vor einer Zeit insolvent gegangen und es gab noch ein letztes Update für das System, wo dann wohl auch alle Länderkarten freigeschaltet wurden (die vorher Geld gekostet haben). Und dieses Update funktionierte wohl noch bis Ende 2023 und damit zu spät für mich. Da noch ein zweites Teasi mit einer neueren Software vorhanden war, dachte ich, dass ich das System einfach rüber kopieren kann (das Gerät verhält sich wie ein USB Stick am Rechner). Dummerweise ging das zwar, allerdings wollte das Tahuna dann einen Lizenzschlüssel, der natürlich nicht vorhanden war. Und ganz blöderweise ging in diesem Moment der USB Stick Modus nicht mehr, sodass das Gerät quasi festgefahren war.

Weder möglicher Support Dienstleister noch das was von der Firma übrig war konnten mir weiterhelfen bzw. waren überhaupt erreichbar. Auf den noch online verfügbaren Seiten des Herstellers war die Rede von einem Wiederherstellungsimage, welches man auf eine Micro SD Karte kopieren konnte und damit das Gerät auf Werkseinstellungen bekommen konnte. Ja, aber leider waren die Links bereits tot. Also klapperte ich diverse Blogs und Foren ab, um dann irgendwann beim Forum von mtb-news.de zu landen. Dort fand ich einen Thread und ein User namens Holger hatte genau das gleiche Teasi wie ich und sprach auch von dem Wiederherstellungs-Image. Also kontaktierte ich ihn, er meldete sich, fand noch die alte Micro-SD Karte von seiner Wiederherstellung und konnte dank einer Anleitung von mir eine Kopie der Karte als Image anfertigen. Nachdem er mir die Datei dann zugeschickt hatte, spielte ich sie auf die Karte und es funktionierte direkt auf Anhieb – sie formatierte das Teasi komplett und nach einem Neustart ging es direkt in den USB Stick Modus.

Und GLÜCKLICHERWEISE hatte ich vor meiner Herumkopiererrei eine komplette Sicherheitskopie des Systems gezogen, welche ich anschließend wieder auf das Gerät kopieren konnte – und es funktionierte.

Da ich vielleicht nicht der letzte mit diesem Problem bin, möchte ich die Datei zur Verfügung stellen und hoffe jemandem damit genauso zu helfen wie Holger es mit mir getan hat.

WICHTIG: dieses Image formatiert mehr oder weniger einfach nur den internen Speicher des Teasi One 3 Extend (ich vermute es geht auch mit den anderen Versionen, kann das aber nicht verifizieren!). Das bedeutet, nachdem diese SD Karte in das Gerät eingelegt wird beginnt SOFORT die Formatierung, alle Daten auf dem Teasi sind direkt gelöscht! Wenn das Gerät nicht eingeschaltet ist dann passiert die Formatierung erst nach dem Einschalten mit der eingelegten Karte.

ACHTUNG!!!! ACHTUNG!!!! ACHTUNG!!!!

Die Teasi Update Server sind offline, ihr könnt das original System NICHT wiederherstellen!!!!

HABT IHR ALSO KEINE KOMPLETTE SICHERHEITSKOPIE EURES “BikeNav” ORDNERS VOM TEASI, DANN LEGT KEINESFALLS!!!!! EINE MICRO-SD MIT DIESEM IMAGE IN DAS GERÄT EIN!!!!!!

Dieses Image bringt euch nur etwas, wenn ihr eine original Kopie des BikeNav Ordners habt!

Nach dieser Warnung, hier nun das Image: Teasi One 3 Extend Recovery Image