Solucione problemas en Docker. Parecería, ¿qué tiene que ver GIT con eso?



Docker bajo Windows es una aventura en curso. Luego necesita actualizar el sistema operativo, de lo contrario las últimas versiones no están instaladas, luego se olvida de cómo conectarse a la red. En general, todos los días de él noticias. "Establecer y olvidar" no se trata de Docker Desktop para Windows. Especialmente cuando no se usa exactamente como recomiendan sus desarrolladores. Y por alguna razón, no aprueban la conexión de ventanas externas a unidades de red como locales. Y no aprueban el acceso a las carpetas de red que también se encuentran en la máquina host. Escriben que esto es horror-horror desde el punto de vista de la seguridad, requieren todo tipo de claves, tales como: para que el comando de montaje funcione en el contenedor, y así sucesivamente.

cap_add:
- SYS_ADMIN
- DAC_READ_SEARCH




En general, cuando una vez más, después de cargar los contenedores en el servidor del cliente, los servicios dejaron de ver unidades de red, no me sorprendió especialmente. Esto ya sucedió, e incluso se escribió una instrucción paso a paso para el grupo de soporte, cómo y qué reiniciar cuando se rompe la configuración de la red del acoplador.

Entonces abro mis instrucciones y tomo medidas. Reiniciar contenedores no ayuda. Reinicio a través de docker-compose con recreación de una infraestructura, no ayuda. Restablezco la configuración de Docker a la configuración de fábrica, restauro la configuración de la máquina virtual, vuelvo a cargar las imágenes, ejecuto Docker-compose, una vez más, todo está como antes, no ve la red. Más precisamente, no se conecta a las bolas de red, aunque es normal hacer ping desde el contenedor al servidor SMB. El último punto es reiniciar el servidor y reinstalar Docker, mientras omito, porque realmente no quiero reiniciar el servidor. En esta instrucción terminó.

Ok, me estoy mudando a mi máquina doméstica, aquí también tengo Docker para Windows, pero una versión un poco más nueva. Lo reviso. Los mismos huevos:

No hay conexión, pero espera!

Si. Bueno, de verdad, creo que Docker terminó la actualización con algún tipo de seguridad y ahora mis scripts no comienzan debido a esto. La última comprobación es eliminar por completo Docker de la máquina y volver a instalarlo. Esto debería ser más frío que restablecer la configuración de fábrica. Estoy haciendo toda la lista del paso anterior, solo que además de esto también estoy reiniciando mi automóvil para que sea completamente irónico. Pongo Docker desde cero, subo imágenes, lanzo Docker-compose, ¡primero! Todos los servicios no vieron la bola de la red y continúan escribiendo "error de montaje (22): argumento no válido" al cargar.

Intento ejecutar el script línea por línea desde la línea de comando: conectarme al contenedor, ejecutar comandos a su vez y ver que todo se conecta y funciona como Necesitar:

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

Es decir, ¿qué es esto, algún tipo de basura con pasar parámetros al script cuando se inicia el contenedor?

Estamos buscando más ideas. Todas las opciones con un reinicio de Docker son poco profundas, hay opciones con posibles cambios en la imagen principal. Mi imagen se basa en openjdk: 8-jdk-alpine , no se especifica una versión específica, por lo que cualquier mejora de seguridad podría romper mis scripts. ¿Quizás cambiaron algo en OpenJDK o una subsidiaria de Alpine?

Compruebo los registros del proyecto, trato de seleccionar el openjdk anterior: 8-jdk-alpine-3.8, openjdk: 8-jdk-alpine-3.7, etc. - cada vez que reconstruyo el contenedor, compruebe - todo está como antes.

¡Maldición! ¿Quizás todavía cambié algo en mi asamblea? Descargar de GIT'a versión del proyecto hace un mes, recoger - los mismos problemas técnicos. Hace tres meses, el problema sigue ahí. ¿Cómo es eso? ¿Qué cambió? La configuración de Docker actualmente está garantizada para funcionar, la configuración de la imagen tampoco ha cambiado, las fuentes del proyecto son las mismas (GIT guarda todo). No hay milagros; sin embargo, debe comprender dónde aparecieron los cambios. En prod, inicio manualmente los comandos de conexión a las bolas, por lo que hasta el reinicio los servicios funcionarán bien y me iré a dormir. La mañana es más sabia que la tarde.

No hay conexión, pero espera!

A la mañana siguiente surge la idea: que probablemente sea hora de averiguarlo y qué es exactamente lo que no le gusta al script cuando se ejecuta.

El mensaje "error de montaje (22): argumento no válido" no es muy informativo. Me parece que hay una clave mágica para el bash con la que muestra información de depuración al ejecutar scripts.

Comience a depurar dentro de 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

Y aquí aparecen algunos momentos extraños: la línea comienza con comillas, luego las comillas al final ... ¿De dónde son las comillas?

Idea: ¿el lanzamiento con bash real puede ser más informativo?

Instalar en el contenedor BASH:

apk add bash

Empiezo a depurar:

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

Maldición, parece que cuando la línea comienza con un plus, es bueno, pero apareció una especie de opciones de \ r y $ '...'.

Configuramos Midnight Commander para experimentar con las comodidades apk add mcy abrir un guión para editar, y allí:



¡Oppa! ^ M al final de cada línea. Bueno, bueno, mira el proyecto local, ¿qué pasa con los finales de línea? CRLF. Trabajamos bajo Windows, sin embargo.

Cambie este archivo CRLF específico a LF (¡viva el Bloc de notas ++!), Recoja el proyecto - ¡bingo! Funciona como deberia.

¿Por qué estaba bien antes, pero ahora todo ha volado? Miro las confirmaciones: no hubo cambios. Y luego recuerdo que GIT puede editar avances de línea sobre la marchaarchivos de texto Y el otro día conecté un nuevo repositorio, y posiblemente cargué todos los archivos desde allí con la conversión a CRLF.

Como resultado, agregamos el archivo .gitattributes al proyecto , lo que indica que en archivos separados es necesario guardar los caracteres de final de línea como en 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

Moralidad: a veces el culpable ni siquiera cae en el círculo de los sospechosos iniciales.

PD


Después de actualizar a la última versión de Docker Desktop para Windows 2.2.0.3, todo dejó de funcionar. Esta vez, inmediatamente entré en los contenedores y comencé a depurar. Resultó que la dirección IP 10.0.75.1 para acceder a la máquina host dejó de funcionar, DockerNat ahora se elimina del sistema y la máquina virtual DockerDesktopVM ni siquiera tiene un adaptador de red externo, es decir. la comunicación con él no pasa por una red estándar, sino de alguna manera diferente. Y para acceder al host, debe usar host.docker.internal . Compañeros desarrolladores y escribieron que
DockerNAT se ha eliminado de Docker Desktop 2.2.0.0 ya que el uso de una dirección IP para comunicarse desde el host a un contenedor no es una característica compatible. Para comunicarse desde un contenedor al host, debe usar el nombre DNS especial host.docker.internal.

Ok, arreglé las configuraciones para el entorno de prueba, recogí la base de datos, hice ping desde el contenedor a los pases host.docker.internal, pero las unidades de red no están conectadas. Intento ejecutar mount manualmente desde el shell y aparece el error familiar "error de montaje (22): argumento no válido". Elimino

los argumentos a su vez. Simplemente ejecuto "mount -t cifs //host.docker.internal/playground / pipeline" . Parece que funciona, pero está tocando desde el usuario root.

Añadir usuario: mount -t cifs //host.docker.internal/playground / pipeline -o user = smbuser : ¡solicita una contraseña y se conecta!

La versión completa también funciona:

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

pero " mount -t cifs //host.docker.internal/playground / pipeline -o user = smbuser, password = smbpassword, vers = 2.0 " no funciona.

Cambio el último parámetro a vers = 2.1 - ¡salud, funciona!

Parece que Docker en su última versión hizo su propia implementación del servidor SMB con blackjack, pero sin soporte 2.0. Tonterías, por supuesto, en comparación con otras noticias.

¡Toda bondad, fuerza y ​​perseverancia!

La ilustración del artículo fue tomada de blog.eduonix.com/software-development/learn-debug-docker-containers

All Articles