Résoudre les problèmes sous Docker. Il semblerait, qu'est-ce que GIT a à voir avec ça?



Docker sous Windows est une aventure en cours. Ensuite, il doit mettre à jour le système d'exploitation, sinon les dernières versions ne sont pas installées, puis il oublie comment se connecter au réseau. En général, chaque jour de lui des nouvelles. «Définir et oublier» ne concerne pas Docker Desktop pour Windows. Surtout quand il n'est pas utilisé exactement comme le recommandent ses développeurs. Et pour une raison quelconque, ils n'approuvent pas la connexion de fenêtres externes aux lecteurs réseau en tant que local. Et ils n'approuvent pas l'accès aux dossiers réseau qui se trouvent également sur la machine hôte. Ils écrivent que c'est horreur-horreur du point de vue de la sécurité, ils ont besoin de toutes sortes de clés telles que: pour que la commande mount fonctionne dans le conteneur, et ainsi de suite.

cap_add:
- SYS_ADMIN
- DAC_READ_SEARCH




En général, lorsque, une fois de plus, après que les conteneurs ont été téléchargés sur le serveur du client, les services ont cessé de voir les lecteurs réseau, je n'ai pas été particulièrement surpris. Cela s'est déjà produit, et même une instruction étape par étape a été écrite pour le groupe de support, comment et quoi redémarrer lorsque les paramètres réseau du docker se cassent.

J'ouvre donc mes instructions et passe à l'action. Le redémarrage des conteneurs n'aide pas. Je redémarre via docker-compose avec recréation d'une infrastructure - n'aide pas. Je réinitialise les paramètres Docker aux paramètres d'usine, restaure les paramètres de la machine virtuelle, recharge les images, exécute via docker-compose - encore une fois, tout est comme avant - il ne voit pas le réseau. Plus précisément, il ne se connecte pas aux boules réseau, bien que le ping depuis le conteneur vers le serveur SMB soit normal. Le dernier point est de redémarrer le serveur et de réinstaller Docker, pendant que je saute, car je ne veux vraiment pas redémarrer le serveur. Sur cette instruction a pris fin.

Ok, je déménage sur ma machine personnelle, ici j'ai aussi Docker pour Windows, mais une version légèrement plus récente. Je vérifie. Les mêmes œufs:

Il n'y a pas de connexion, mais vous tenez bon!

Ouais. Eh bien, vraiment, je pense que Docker a mis à jour la mise à jour avec une sorte de sécurité et maintenant mes scripts ne démarrent pas à cause de cela? La dernière vérification consiste à supprimer complètement Docker de la machine et à le réinstaller. Cela devrait être plus frais que de réinitialiser les paramètres d'usine. Je fais toute la liste de l'étape précédente, mais en plus de cela, je redémarre également ma voiture pour que ce soit complètement ironique. Je mets Docker à zéro, je télécharge des images, je lance docker-compose - tout de suite! Tous les services n'ont pas vu la boule du réseau et continuent d'écrire «erreur de montage (22): argument non valide» lors du chargement.

J'essaie d'exécuter le script ligne par ligne à partir de la ligne de commande: connectez-vous au conteneur, exécutez les commandes à tour de rôle et voyez que tout se connecte et fonctionne comme besoin de:

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

Autrement dit, qu'est-ce que c'est, une sorte de merde avec le passage de paramètres au script lorsque le conteneur démarre?

Nous recherchons plus d'idées. Toutes les options avec un redémarrage de docker sont peu profondes, il y a des options avec des changements possibles dans l'image parent. Mon image est construite sur la base de openjdk: 8-jdk-alpine , aucune version spécifique n'est spécifiée, donc toute amélioration de la sécurité pourrait casser mes scripts. Peut-être ont-ils changé quelque chose dans OpenJDK ou une filiale d'Alpine?

Je vérifie les journaux du projet, j'essaie de sélectionner l'ancien openjdk: 8-jdk-alpine-3.8, openjdk: 8-jdk-alpine-3.7, etc. - chaque fois que je reconstruis le conteneur, vérifiez - tout est comme avant.

Bon sang! Peut-être que j'ai encore changé quelque chose dans mon assemblage? Déchargement de la version GIT'a du projet il y a un mois, collecte - les mêmes problèmes. Il y a trois mois - le problème est toujours là. Comment? Qu'est ce qui a changé? La configuration du docker est actuellement garantie de fonctionner, la configuration de l'image n'a pas changé non plus, les sources du projet sont les mêmes (GIT enregistre tout). Il n'y a pas de miracles - vous devez comprendre où les changements sont néanmoins apparus. Dans prod, je lance manuellement les commandes de connexion aux boules - donc jusqu'au redémarrage, les services fonctionneront bien et s'endormiront. Le matin est plus sage que le soir.

Il n'y a pas de connexion, mais vous tenez bon!

Le lendemain matin, l'idée vient - qu'il est probablement temps de découvrir, et ce que le script n'aime pas exactement lors de l'exécution.

Le message «erreur de montage (22): argument non valide» n'est pas très informatif. Je trouve qu'il existe une clé magique pour le bash avec laquelle il affiche des informations de débogage lors de l'exécution de scripts.

Commencez le débogage dans 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

Et ici quelques moments étranges apparaissent - la ligne commence par des guillemets, puis les guillemets à la fin ... D'où viennent les guillemets?

Idée - le lancement à l'aide de real bash peut-il être plus informatif?

Installez dans le conteneur BASH:

apk add bash

Je commence le débogage:

/ # 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

Merde, il semble que lorsque la ligne commence par un plus - c'est bien, mais une sorte d' options \ r et $ '...' sont apparues .

Nous avons configuré Midnight Commander pour expérimenter les commodités apk add mcet ouvrir le script pour l'édition, et là:



Oppa! ^ M à la fin de chaque ligne. Eh bien, regardez le projet local - qu'en est-il des fins de ligne ???? CRLF. Nous travaillons cependant sous Windows.

Changez ce fichier CRLF spécifique en LF (vive le Bloc-notes ++!), Récupérez le projet - bingo! Cela fonctionne comme il se doit.

Pourquoi ça allait avant, mais maintenant tout a volé? Je regarde les commits - il n'y a eu aucun changement. Et puis je me souviens que GIT peut éditer les sauts de ligne à la voléefichiers texte. Et l'autre jour, j'ai connecté un nouveau référentiel, et éventuellement téléchargé tous les fichiers à partir de là avec conversion en CRLF.

Par conséquent, nous ajoutons le fichier .gitattributes au projet , indiquant que dans des fichiers séparés, il est nécessaire d'enregistrer les caractères de fin de ligne comme sous UNIX:

# 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

Moralité - parfois, le coupable ne tombe même pas dans le cercle des suspects initiaux.

P.S


Après la mise à jour vers la dernière version de Docker Desktop pour Windows 2.2.0.3, tout a cessé de fonctionner. Cette fois, je suis immédiatement entré dans les conteneurs et j'ai commencé le débogage. Il s'est avéré que l'adresse IP 10.0.75.1 pour accéder à la machine hôte a cessé de fonctionner, DockerNat est maintenant supprimé du système et la machine virtuelle DockerDesktopVM n'a même pas d'adaptateur réseau externe, c'est-à-dire la communication avec elle ne passe pas par un réseau standard, mais en quelque sorte différemment. Et pour accéder à l'hôte, vous devez utiliser host.docker.internal . Fellow développeurs et a écrit que
DockerNAT a été supprimé de Docker Desktop 2.2.0.0 car l'utilisation d'une adresse IP pour communiquer de l'hôte à un conteneur n'est pas une fonctionnalité prise en charge. Pour communiquer d'un conteneur à l'hôte, vous devez utiliser le nom DNS spécial host.docker.internal.

Ok, j'ai corrigé les configurations pour l'environnement de test, la base de données a été récupérée, ping du conteneur aux passes host.docker.internal, mais les lecteurs réseau ne sont pas connectés. J'essaie d'exécuter le montage manuellement à partir du shell et j'obtiens l'erreur familière «erreur de montage (22): argument non valide».

Je supprime les arguments à mon tour - je lance simplement «mount -t cifs //host.docker.internal/playground / pipeline» - cela semble fonctionner, mais il frappe de l'utilisateur root.

Ajouter un utilisateur: mount -t cifs //host.docker.internal/playground / pipeline -o user = smbuser - demande un mot de passe et se connecte!

La version complète fonctionne également:

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

mais " mount -t cifs //host.docker.internal/playground / pipeline -o user = smbuser, password = smbpassword, vers = 2.0 " ne laboure pas.

Je change le dernier paramètre en vers = 2.1 - cheers, ça marche!

Il semble que Docker dans sa dernière version ait fait sa propre implémentation du serveur SMB avec blackjack, mais sans support 2.0. Un non-sens, bien sûr, par rapport à d'autres nouvelles.

Toute bonté, force et persévérance!

L'illustration de l'article provient de blog.eduonix.com/software-development/learn-debug-docker-containers

All Articles