Linux Server zeigt unterschiedliche Werte bei df und du

Wenn das Monitoring meldet, dass die Platte eines Servers voll läuft, ein

du -hs /*

aber deutlich weniger verwendeten Speicher anzeigt als man es per df sieht – dann gibts erstmal Verwunderung.

Eine google Recherche hat mich dann auf den Trichter gebracht, dass dies ein Zeichen von zwar gelöschten Dateien, aber noch offenen Dateihandles auf diesen liegen kann. Sprich, man hat zwar eine Datei gelöscht, aber ein Programm hat die Datei aktuell noch geöffnet. Dann ist zwar der Dateiname nicht mehr sichtbar, aber die Inhalte der Datei liegen noch immer auf der Festplatte und verbrauchen natürlich auch ensprechend Platz. In meinem Fall ist filebeat nicht mit einem Logrotate klar gekommen und hatte somit eine relativ große Log Dateien weiterhin geöffnet. Mit jedem Logrotate kam eine dazu…

Wie kann man das sichtbar machen? So:

lsof | grep "/var" | grep deleted

oder gleich mit

lsof | grep deleted

wobei man bei letzterem vielleicht ein paar Ergebnisse sieht, die berechtigt noch Handles offen halten.

Hier mal eine Beispielhafte Ausgabe:

Ganz links sieht man den Dienst bzw. Command, und in der ganz rechten Spalte die jeweilige Datei.

Normalerweise sollte es reichen, den entsprechenden Dienst einfach neu zu starten und das Problem ist erstmal behoben. Sollte der Fehler wieder auftreten, müsste dann evtl ein Update/Patch oder als letzte Möglichkeit ein kontrollierter regelmäßiger Neustart das Problem beheben.

Ansible startet nicht mehr unter Mac OS Catalina

Beim Ausführen von Ansible Befehlen bekam ich seit kurzem immer wieder die Fehlermeldung

Abort trap: 6

angezeigt. Da ich Ansible direkt über pip installiert hatte, führte ich natürlich erstmal ein Update dort durch – was aber keine Abhilfe brachte. Irgendwie hatte das ganze mit dem Wegfall von python 2.7 mit Mac OS Catalina zu tun.

Die relativ plumpe, aber doch effektive Lösung war:

pip3 uninstall ansible
brew install ansible

🤷‍♂️😂

Nach Mac OS Catalina Update – Mail App Suchfunktion ist kaputt

Das Update auf Mac OS Catalina lief bei mir eigentlich ohne Probleme durch, aber heute fiel mir dann auf, dass die Suchfunktion in der Mail App sich sehr komisch verhielt bzw. einfach kaputt war.

Mir war natürlich gleich klar, dass der Suchindex wahrscheinlich einen Treffer hatte, da ich die App ja trotzdem normal bedienen und Mails senden/empfangen konnte.

Um das Problem zu beheben, musste ich also den Suchindex der Mail App zurücksetzen und neu aufbauen lassen. Dazu sind folgende Schritte nötig:

  1. Mail App beenden
  2. Im Finder den Ordner ~/Library/Mail/V7/MailData öffnen (mit CMD+SHIFT+G)
  3. Alle Dateien, die mit „Envelope Index“ beginnen löschen (oder in einen Backup-Ordner schieben)
  4. Mail App wieder starten. Es empfängt euch ein Screen, der mitteilt, dass Mail sich selbst reparieren muss. Anschließend werden die Mails neu indiziert, in dieser Zeit ist Mail nicht benutzbar.

Nginx Docker Reverse Proxy wirft 404 Fehler ab dem zweiten Request

Als großer Fan von “nackten Servern” auf denen nur Docker Container laufen, nutze ich Nginx als Reverse Proxy – im Speziellen das großartige Setup von jwilder/nginx-proxy in Kombinantion mit dem Let’s Encrypt Addon. Effektiv läuft das Teil passiv mit und schaut nur auf bestimmte Environment-Variablen anderer Docker Container. Sobald es diese sieht, wird automatisch ein Reverse Proxy in Nginx so konfiguriert, dass er diesen Dienst erreichbar macht und gleichzeitig wird noch ein Let’s Encrypt Cert für die entsprechende Domain besorgt und auf dem neuesten Stand gehalten.

Nun hatte ich in einem Setup mit sehr vielen gleichzeitig laufenden Diensten das Problem, dass einer der Dienste immer nur auf den ersten Request erfolgreich geantwortet hat, aber bei jedem weiteren Request nur noch einen 404 geworfen hat. Der Dienst selbst lief, Nginx hat auch keinen Fehler im Log geworfen und ich war etwas ratlos.

Nach ein paar grauen Haaren mehr und dem ein oder anderen versteckten Hinweis auf Google kam ich dann auf des Rätsels Lösung: durch ein fehlerhaftes Deployment lief kurzzeitig ein weiterer Container, der mittels der Environment Variable die gleiche URL für sich beanspruchte. Der Nginx Automatismus machte daraus automatisch einen Load Balancer. Nachdem das fehlerhafte Deployment weg war, wurde der Loadbalancer aber nicht mehr aufgelöst und somit war nur noch einer von beiden Einträgen aktiv. Warum der Nginx dann trotzdem immer wieder auf den nicht vorhandenen Host gehen wollte erschließt sich mir nicht so richtig, aber das war des Problems Lösung.

Also bin ich einfach per docker exec in den Nginx Container und habe die Datei /etc/nginx/conf.d/default editiert:


# server.name.com
upstream server.name.com {
# CONTAINER_NAME_1
server 123.45.0.67:1234;
# CONTAINER_NAME_2
server 123.45.0.78:1234;
}

Nachdem ich den Part von CONTAINER_NAME_2 gelöscht hatte, konnte ich mittels

nginx -s reload

die Config von Nginx on the fly neu laden und ab dem Moment lief der Service wieder wie gewohnt.

Wie man Featurebranches mit Jenkins baut

Meine Güte! Wie viel Zeit habe ich bereits in dieses Thema investiert und am Ende ist die Lösung meines Problems dann doch so simpel…

Aber fangen wir von vorn an. Der moderne Entwickler arbeitet in der Regel mit git und im optimalen Fall nach dem gitflow Konzept bzw. mit Featurebranches. Ist der Code fertig gestellt, wird ein für den Branch ein Review durchgeführt und davor bzw. gleichzeitig wird durch eine CI – in meinem Fall Jenkins – geprüft, ob dieser Branch denn so überhaupt noch lauffähig ist. Im konkreten Beispiel ist Atlassian Bitbucket dabei der Git host, es werden Pull Requests verwendet und um diese mergen zu können, muss Jenkins melden, dass der Code erfolgreich integriert werden konnte.

Jenkins ist dabei so eingestellt, dass es einen Job gibt, der auf sämtliche Branches eines Repositories lauscht. Sobald es einen Push gibt, checkt Jenkins diesen Code-Stand aus und baut ihn. Wenn alles gut ist meldet er das an Bitbucket zurück. Das Problem ist nun: was ist, wenn der Build wegen eines Problems auf der Buildnode, fehlendem Internet oder warum auch immer fehlschlägt? Dann wird man nie den Merge vollziehen können, da die Rückmeldung von Jenkins fehlt. Man kann nun einfach irgendeinen weiteren Commit machen, diesen pushen und es geht von neuem los. Oder aber, man macht es folgendermaßen:

Der ursprüngliche Job (“Job-01”), der auf alle Branches gelauscht hat, wird so umgebaut, dass er parametrisiert ist (Parametername “Branchname” z.B.) und im git Bereich wird angegeben , dass nur der Branch “$Branchname” gebaut werden soll. Anschließen legt man einen weiteren Job an (“Job-02”), der auf das gleiche repo sowie Veränderungen in allen Branches lauscht.

Dieser Job wiederum macht nichts anderes, als bei einer erkannten Änderung den parametrisierten Job  (“Job-01”) auszuführen und den entprechenden Branch als Parameter zu übergeben.

Nun haben wir erstmal den gleichen Zustand wie vorher – aber zusätzlich die Möglichkeit, den parametrisierten Job von Hand und unter Angabe des gewünschten Branches zu bauen. Also eben z.B., wenn der Job vorher fehlgeschlagen ist. Dieser wiederum kann dann seinen Status auch an Bitbucket melden.

AWS Lambda@Edge liefert 503 Error und es gibt keine Logs

Jobbedingt musste ich mich kürzlich mit AWS Lambda@Edge Funktionen herumschlagen. Da die wenigesten wahrscheinlich wissen, was das ist:

Lamdba Funktionen gehören zum Bereich “serverless” – letztendlich bedeutet es nur, dass man nicht eigene Server oder Dienste (z.B. wordpress) hosted, sondern einzelne Funktionen. Beispiel: eine Bildskalierung. Sprich, man gibt dem Service eine URL mit und parameter, wie groß das Zielbild sein soll. Der Service holt sich das Bild von der URL, verkleinert/vergrößert es auf die Maße und gibt es dann zurück.

Lambda@Edge ist dann die Hipster Variante davon, diese Funktionen kann man nämlich vor sein AWS Cloudfront CDN hängen. Sprich, bei jedem Request, der beim CDN ankommt, wird vorher die entsprechende Lambda Methode ausgeführt. Mit dieser kann man den Request verändern, Authentifizierung abhandeln, oder auch z.B. A/B Tests fahren. (weitere Beispiele: docs.aws.amazon.com)

Im Gegensatz zum “normalen” Lambda gibt es jedoch ein paar Einschränkungen, die hier ganz gut erklärt werden: Lambda at the Edge

Zusätzlich zu den unzähligen Unterseiten, hier mal meine aktuellen Erkenntnisse zum Thema Lambda@Edge:

  • AWS Lambda@Edge funkionen MÜSSEN in “North Virginia (us-east-1)” abgelegt werden!
  • Der komplette Code für die Lambda Funktion darf nicht größer als 1MB sein, inkl. Libraries
  • du MUSST nodejs8.10 oder nodejs10.x verwenden
  • die Funktion darf nicht mehr als 128mb RAM verwenden
  • die Funktion darf nicht länger als 5s laufen
  • Die LOGS der Aufrufe über CLOUDFRONT werden nicht in Cloudwatch “North Virginia (us-east-1)” abgelegt, sondern in der Area, WO SIE HERKOMMEN. In meinem Fall also “EU (Frankfurt)”. Wenn man die Funktion selbst per Testcall in der Lambda Oberfläche aufruft, DANN landen die Logs in “North Virginia (us-east-1)”. Es hat mich mehrere Tage gekostet, darauf zu kommen…
  • Cookies, die man an die Funktion überträgt, werden im Cookie Array (event.Records[0].cf.request.headers.cookie) nicht als “key: value” übergeben, sondern als “cookie: key=value”

Etwas fies ist, dass die Fehlercodes sich überlappen. In meinem Fall bekam ich immer wieder einen 503 Fehler angezeigt, sobald ich meine Funktion über Cloudfront aufrief. Da ich zu diesem Zeitpunkt den “anderen Ort” der Logs nicht kannte, musste ich raten. Die 503 Fehlerseite gab aber ungünstigerweise noch den Hinweis, dass die Funktion wahrscheinlich nicht genügend Permissions oder Ressourcen hat – was mich die ganze Zeit auf die falsche Fährte lockte. Denn eigentlich warf meine Funktion die ganze Zeit selbst einen 500er Fehler, weil das Cookie Parsing nicht richtig klappte. Diese Unterscheidung sieht man aber nicht wirklich von aussen – sprich, eine fehlerhafte Konfiguration von Lambda@Edge Funktionen und Fehler im Script selbst sehen von aussen exakt gleich aus.

Nachdem ich die Logs dann endlich gefunden hatte, war das Problem schnell behoben (siehe Punkt “cookies”) in der oberen Liste, funktionierte meine Funktion nun wie gewünscht.

Chrome scheint Videosoftware unter MacOS auszubremsen

Creative Director Felipe Baez von der Agentur Cre8ive Beast hat bemerkt, dass sich Final Cut Pro deutlich langsamer wird, und teilweise sogar abstürzen kann. Grund dafür ist das “Video-Toolbox” Framework, welches von MacOS bereitgestellt wird. Chrome nutzt dieses Framework und klaut somit die Ressourcen anderen Programmen, wie eben Final Cut Pro. Das gleiche Problem tritt auch z.B. bei Handbrake auf, und somit wahrscheinlich auch bei weiteren Video-Editoren.

Aktuell ist der Ratschlag: sobald man irgendeine Art von Videoschnitt macht, sollte Chrome nicht laufen.

Bei dieser Gelegenheit rate ich wirklich JEDEM dazu, sich den aktuellen Firefox nochmal anzusehen. War er in den letzten Jahren eher langsam und behäbig geworden, ist er nun seit ca. 0,5-1 Jahr wieder in seiner alten Form zurück. Er ist super schnell (teilweise sogar schneller als Chrome), hat die gleichen Funktionen, und ganz wichtig: nimmt Privatsphäre und Datenschutz höchstwahrscheinlich deutlich ernster als andere Browserhersteller. Ich bin schon vor einer ganzen Weile umgestiegen (auf meinem Mac und auch auf iPhone/iPad) und bereue es in keinster Weise!

via Golem