如何从 Docker 容器(MySQL、MariaDB 等)向主机公开 Linux 套接字文件

Tor*_*que 8 linux mysql sockets mariadb docker

免责声明:我不是在寻找配置 MySQL/MariaDB 以使用 TCP 连接的方法。我知道这个选项,问题不在于那个方面。

我无法将容器内的套接字文件绑定到主机文件系统。我希望像这样一个简单的 docker-compose 条目可以工作:

    volumes:
      - /srv/docker/sockets/mariadb.container.sock:/var/run/mysqld/mysqld.sock
Run Code Online (Sandbox Code Playgroud)

但这没有用。相反,我遇到了以下错误消息:

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 ?
Run Code Online (Sandbox Code Playgroud)

主机系统中文件的状态似乎无关紧要——它是否已经存在、存在a+rwx权限、存在于正确的用户或根本不存在似乎对容器是否启动没有任何影响。

也许最令人困惑的是主机文件系统中的最终结果:

[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
Run Code Online (Sandbox Code Playgroud)

原来.sock文件变成了主机上的(空)目录!

我有更多的运气将套接字文件移动到它自己的目录并将该目录安装到主机,在这种情况下它可以工作一次,但不能在容器重新启动后工作。

lar*_*sks 16

问题是绑定挂载用于将主机上的某些内容暴露给容器。所以当你这样做时:

volumes:
  - /srv/docker/sockets/mariadb.container.sock:/var/run/mysqld/mysqld.sock
Run Code Online (Sandbox Code Playgroud)

您正在试图安装/srv/docker/sockets/mariadb.container.sock-这不存在-在/var/run/mysqld/mysqld.sock容器内。由于源对象不存在,Docker 将在该位置创建一个空目录并将其挂载到容器中……这当然意味着 mysqld 在启动时无法创建套接字。

正确的解决方案是将主机目录挂载到 上/var/run/mysqld/,例如:

volumes:
  - /srv/docker/sockets/mariadb:/var/run/mysqld
Run Code Online (Sandbox Code Playgroud)

然后在您的主机上,套接字将作为/srv/docker/sockets/mariadb/mysqld.sock.

  • 您可能还想将套接字文件放在另一个目录中(通过在 **custom-settings.cnf** 中更改为 `socket = /var/run/mysqld-socketdir/mysqld.sock` 并通过自定义卷附加它,例如`-./conf/mysql-conf.d:/etc/mysql/conf.d`)。这样,您只会将“/var/run/mysqld-socketdir”暴露给其​​他容器,以便其他容器无法访问“/var/run/mysqld”中的其他文件 (2认同)