16 votes

Comment exposer un fichier socket Linux depuis un conteneur Docker (MySQL, MariaDB, etc.) vers un hôte ?

Avertissement : je ne cherche pas à configurer MySQL/MariaDB pour qu'il utilise des connexions TCP. Je connais cette option et la question ne porte pas sur cet aspect.

Je n'arrive pas à lier un fichier socket à l'intérieur d'un conteneur au système de fichiers de l'hôte. Je m'attendais à ce qu'une simple entrée docker-compose comme celle-ci fonctionne :

    volumes:
      - /srv/docker/sockets/mariadb.container.sock:/var/run/mysqld/mysqld.sock

Mais cela n'a pas fonctionné. Au lieu de cela, j'ai reçu les messages d'erreur suivants :

its_sql_dev    | 190305 10:31:23 [ERROR] Can't start server : Bind on unix socket: Address already in use
its_sql_dev    | 190305 10:31:23 [ERROR] Do you already have another mysqld server running on socket: /var/run/mysqld/mysqld.sock ?

L'état du fichier dans le système hôte ne semble pas avoir d'importance - qu'il ait déjà existé, qu'il ait existé avec a+rwx ou n'existait pas du tout ne semble pas avoir d'incidence sur le démarrage du conteneur.

Le résultat final dans le système de fichiers de l'hôte est peut-être le plus déconcertant :

[user@server mariadb]# ls -alsh /srv/docker/shared/
total 16K
4.0K drwxrwxrwx 4 root    root     4.0K Mar  5 11:31 .
4.0K drwxr-xr-x 7 root    root     4.0K Mar  1 13:09 ..
4.0K drwxr-xr-x 2 root    root     4.0K Mar  5 11:31 mariadb.container.sock

Il s'est avéré que le fichier .sock s'est transformé en un répertoire (vide) sur l'hôte !

J'ai eu un peu plus de chance en déplaçant le fichier socket dans son propre répertoire et en montant ce répertoire sur l'hôte, dans ce cas cela fonctionnerait une fois, mais pas après un redémarrage du conteneur.

20voto

WingManEXE Points 611

Le problème est que les montages de liaison servent à exposer quelque chose sur le site web de l hôte au conteneur. Ainsi, lorsque vous faites cela :

volumes:
  - /srv/docker/sockets/mariadb.container.sock:/var/run/mysqld/mysqld.sock

Vous essayez de monter /srv/docker/sockets/mariadb.container.sock -- qui n'existe pas -- sur /var/run/mysqld/mysqld.sock à l'intérieur du conteneur. Puisque l'objet source n'existe pas, Docker va créer un répertoire vide à cet endroit et le monter dans le conteneur... ce qui signifie bien sûr que mysqld ne peut pas créer le socket au démarrage.

La solution correcte consiste à monter un répertoire hôte sur /var/run/mysqld/ par exemple :

volumes:
  - /srv/docker/sockets/mariadb:/var/run/mysqld

Ensuite, sur votre hôte, le socket sera disponible en tant que /srv/docker/sockets/mariadb/mysqld.sock .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X