Beheben Sie Probleme unter Docker. Es scheint, was hat GIT damit zu tun?



Docker unter Windows ist ein fortwährendes Abenteuer. Dann muss er das Betriebssystem aktualisieren, andernfalls werden die neuesten Versionen nicht installiert, und er vergisst, wie er sich mit dem Netzwerk verbindet. Im Allgemeinen jeden Tag von ihm Nachrichten. Bei „Festlegen und Vergessen“ geht es nicht um Docker Desktop für Windows. Vor allem, wenn es nicht genau so verwendet wird, wie es die Entwickler empfehlen. Aus irgendeinem Grund ist es nicht zulässig, externe Fenster als lokal mit Netzwerklaufwerken zu verbinden. Der Zugriff auf Netzwerkordner, die sich ebenfalls auf dem Hostcomputer befinden, wird nicht genehmigt. Sie schreiben, dass dies aus Sicherheitsgründen Horror-Horror ist. Sie benötigen alle Arten von Schlüsseln, z. B.: Damit der Befehl mount im Container funktioniert , und so weiter und so fort.

cap_add:
- SYS_ADMIN
- DAC_READ_SEARCH




Im Allgemeinen war ich nicht besonders überrascht, als die Dienste nach dem Hochladen der Container auf den Server des Kunden keine Netzlaufwerke mehr sahen. Dies ist bereits geschehen, und für die Support-Gruppe wurde sogar eine schrittweise Anleitung geschrieben, wie und was neu gestartet werden soll, wenn die Docker-Netzwerkeinstellungen unterbrochen werden.

Also öffne ich meine Anweisungen und ergreife Maßnahmen. Das Neustarten von Containern hilft nicht. Ich starte durch Docker-Compose mit Wiederherstellung einer Infrastruktur neu - hilft nicht. Ich habe die Docker-Einstellungen auf die Werkseinstellungen zurückgesetzt, die Einstellungen für die virtuelle Maschine wiederhergestellt, die Images neu geladen, Docker-Compose durchlaufen - wieder ist alles wie zuvor - das Netzwerk wird nicht angezeigt. Genauer gesagt wird keine Verbindung zu Netzwerkbällen hergestellt, obwohl ein Ping vom Container zum SMB-Server normal ist. Der letzte Punkt ist, den Server neu zu starten und Docker neu zu installieren, während ich überspringe, da ich den Server wirklich nicht neu starten möchte. Auf diese Anweisung endete.

Ok, ich ziehe auf meinen Heimcomputer um. Hier habe ich auch Docker für Windows, aber eine etwas neuere Version. Ich überprüfe es. Die gleichen Eier:

Es gibt keine Verbindung, aber Sie halten!

Ja. Nun, wirklich, ich denke, Docker hat das Update mit einer Art Sicherheit aufgerollt und jetzt starten meine Skripte aus diesem Grund nicht? Die letzte Überprüfung besteht darin, Docker vollständig vom Computer zu entfernen und neu zu installieren. Dies sollte kühler sein als das Zurücksetzen auf die Werkseinstellungen. Ich mache die gesamte Liste aus dem vorherigen Schritt, nur zusätzlich starte ich mein Auto neu, so dass es völlig ironisch ist. Ich habe Docker von Grund auf neu erstellt, Bilder hochgeladen, Docker-Compose gestartet - eprst! Alle Dienste haben den Netzwerkball nicht gesehen und schreiben beim Laden weiterhin "Mount-Fehler (22): Ungültiges Argument".

Ich versuche, das Skript zeilenweise über die Befehlszeile auszuführen: Ich verbinde mich mit dem Container, führe Befehle nacheinander aus und stelle fest, dass alles wie verbunden ist und funktioniert müssen:

mkdir -p $SMB_MOUNT_POINT
mount -t cifs $SMB_SHARE $SMB_MOUNT_POINT -o user=$SMB_USER,password=$SMB_PASSWORD,vers=2.0
ls $SMB_MOUNT_POINT

Das heißt, was ist das, eine Art Mist, bei dem Parameter an das Skript übergeben werden, wenn der Container startet?

Wir suchen nach weiteren Ideen. Alle Optionen bei einem Docker-Neustart sind flach. Es gibt Optionen mit möglichen Änderungen im übergeordneten Image. Mein Image basiert auf openjdk: 8-jdk-alpine , es ist keine bestimmte Version angegeben, sodass Sicherheitsverbesserungen meine Skripte beschädigen können . Vielleicht haben sie etwas in OpenJDK oder einer Tochtergesellschaft von Alpine geändert?

Ich überprüfe die Projektprotokolle und versuche, das ältere openjdk auszuwählen: 8-jdk-alpine-3.8, openjdk: 8-jdk-alpine-3.7 usw. - Überprüfen Sie jedes Mal, wenn ich den Container neu aufbaue, dass alles wie zuvor ist.

Verdammt! Vielleicht habe ich in meiner Versammlung noch etwas geändert? Vor einem Monat aus der GIT'a-Version des Projekts entladen, gesammelt - die gleichen Pannen. Vor drei Monaten - das Problem ist immer noch da. Wie das? Was hat sich geändert? Die Docker-Konfiguration funktioniert derzeit garantiert, die Image-Konfiguration hat sich ebenfalls nicht geändert, die Projektquellen sind dieselben (GIT speichert alles). Es gibt keine Wunder - Sie müssen verstehen, wo die Änderungen dennoch erschienen sind. In prod starte ich die Verbindungsbefehle zu den Bällen manuell - bis zum Neustart funktionieren die Dienste also einwandfrei und gehen in den Ruhezustand. Der Morgen ist weiser als der Abend.

Es gibt keine Verbindung, aber Sie halten!

Am nächsten Morgen kommt die Idee - dass es wahrscheinlich Zeit ist herauszufinden, was genau das Skript bei der Ausführung nicht mag.

Die Meldung "Mount-Fehler (22): Ungültiges Argument" ist nicht sehr informativ. Ich finde, dass es einen magischen Schlüssel für die Bash gibt, mit dem Debugging-Informationen beim Ausführen von Skripten angezeigt werden.

Starten Sie das Debuggen in sh:

/ # sh -x /entry-point.sh
' echo 'Mount //<private_ip>/Exchange/Pipeline to /pipeline
Mount //<private_ip>/Exchange/Pipeline to /pipeline
' mkdir -p '/pipeline
' mount -t cifs //<private_ip>/Exchange/Pipeline /pipeline -o 'user=<private_user>,password=<private_password>,vers=2.0
mount error(22): Invalid argument
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
mount: mounting //<private_ip>/Exchange/Pipeline on /pipeline failed: Invalid argument
' ls '/pipeline
+ exec

Und hier erscheinen einige seltsame Momente - die Zeile beginnt mit Anführungszeichen, dann mit Anführungszeichen am Ende ... Woher kommen die Anführungszeichen?

Idee - kann das Starten mit Real Bash informativer sein?

Im BASH-Container installieren:

apk add bash

Ich beginne zu debuggen:

/ # bash -x /entry-point.sh
' echo 'Mount //<private_ip>/Exchange/Pipeline to /pipeline
Mount //<private_ip>/Exchange/Pipeline to /pipeline
+ mkdir -p $'/pipeline\r'
+ mount -t cifs //<private_ip>/Exchange/Pipeline /pipeline -o $'user=<private_user>,password=<private_password>,vers=2.0\r'
mount error(22): Invalid argument
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
mount: mounting //<private_ip>/Exchange/Pipeline on /pipeline failed: Invalid argument
+ ls $'/pipeline\r'
+ exec

Verdammt, es scheint, als würde die Zeile mit einem Plus beginnen - es ist gut, aber es wurden einige Optionen \ r und $ '...' angezeigt .

Wir haben Midnight Commander so eingestellt, dass sie mit Annehmlichkeiten experimentieren apk add mcund das Skript zur Bearbeitung öffnen, und dort:



Oppa! ^ M am Ende jeder Zeile. Schauen Sie sich das lokale Projekt an - was ist mit den Zeilenenden? CRLF. Wir arbeiten jedoch unter Windows.

Ändern Sie in dieser spezifischen CRLF-Datei in LF (es lebe Notepad ++!), Sammeln Sie das Projekt - Bingo! Es funktioniert wie es sollte.

Warum war es vorher in Ordnung, aber jetzt ist alles geflogen? Ich sehe mir die Commits an - es gab keine Änderungen. Und dann erinnere ich mich, dass GIT Linefeeds im laufenden Betrieb bearbeiten kannTextdateien. Und neulich habe ich ein neues Repository verbunden und möglicherweise alle Dateien von dort mit Konvertierung in CRLF hochgeladen.

Infolgedessen fügen wir die .gitattributes- Datei zum Projekt hinzu , was darauf hinweist, dass in separaten Dateien das Zeilenendezeichen wie in UNIX gespeichert werden muss:

# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

# Declare files that will always have LF line endings on checkout.
*.sh text eol=lf

Moral - manchmal fällt der Täter nicht einmal in den Kreis der ursprünglichen Verdächtigen.

P.S.


Nach dem Update auf die neueste Version von Docker Desktop für Windows 2.2.0.3 funktionierte alles nicht mehr. Dieses Mal ging ich sofort in die Container und begann zu debuggen. Es stellte sich heraus, dass die IP-Adresse 10.0.75.1 für den Zugriff auf den Hostcomputer nicht mehr funktioniert, DockerNat jetzt vom System entfernt wird und die virtuelle DockerDesktopVM-Maschine nicht einmal über einen externen Netzwerkadapter verfügt, d. H. Die Kommunikation damit erfolgt nicht über ein Standardnetzwerk, sondern irgendwie anders. Und um auf den Host zuzugreifen, müssen Sie host.docker.internal verwenden . Mitentwickler und schrieb das
DockerNAT wurde aus Docker Desktop 2.2.0.0 entfernt, da die Verwendung einer IP-Adresse für die Kommunikation vom Host zu einem Container keine unterstützte Funktion ist. Um von einem Container zum Host zu kommunizieren, müssen Sie den speziellen DNS-Namen host.docker.internal verwenden.

Ok, ich habe die Konfigurationen für die Testumgebung korrigiert, die Datenbank wurde abgerufen und vom Container an host.docker.internal übergeben, aber die Netzwerklaufwerke sind nicht verbunden. Ich versuche, mount manuell über die Shell auszuführen, und erhalte den bekannten Fehler "mount error (22): Ungültiges Argument".

Ich entferne die Argumente der Reihe nach - ich führe nur "mount -t cifs //host.docker.internal/playground / Pipeline" aus - es scheint zu funktionieren, aber es klopft vom Root-Benutzer.

Benutzer hinzufügen : mount -t cifs //host.docker.internal/playground / Pipeline -o user = smbuser - fragt nach einem Passwort und stellt eine Verbindung her!

Die Vollversion funktioniert auch:

mount -t cifs //host.docker.internal/playground /pipeline -o user=smbuser,password=smbpassword

" mount -t cifs //host.docker.internal/playground / pipe -o user = smbuser, password = smbpassword, vers = 2.0 " pflügt jedoch nicht.

Ich ändere den letzten Parameter auf vers = 2.1 - Prost, es funktioniert!

Es scheint, dass Docker in seiner neuesten Version eine eigene Implementierung des SMB-Servers mit Blackjack vorgenommen hat, jedoch ohne 2.0-Unterstützung. Unsinn natürlich im Vergleich zu anderen Nachrichten.

Alle Güte, Kraft und Ausdauer!

Die Abbildung für den Artikel stammt von blog.eduonix.com/software-development/learn-debug-docker-containers

All Articles