从主机连接到docker容器中的mysql

gtu*_*rri 79 mysql docker

(这可能是一个愚蠢的问题,因为我对Docker或mysql管理的知识有限,但因为我在这个问题上度过了整整一个晚上,我敢问它.)

简而言之

我想在docker容器中运行mysql并从我的主机连接到它.到目前为止,我所取得的成就是最好的

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Run Code Online (Sandbox Code Playgroud)

更多细节

我正在使用以下内容 Dockerfile

FROM ubuntu:14.04.3
RUN apt-get update && apt-get install -y mysql-server

# Ensure we won't bind to localhost only
RUN grep -v bind-address /etc/mysql/my.cnf > temp.txt \
  && mv temp.txt /etc/mysql/my.cnf

# It doesn't seem needed since I'll use -p, but it can't hurt
EXPOSE 3306

CMD /etc/init.d/mysql start && tail -F /var/log/mysql.log
Run Code Online (Sandbox Code Playgroud)

在有这个文件的目录中,我可以成功构建映像并运行它

> docker build -t my-image .
> docker run -d -p 12345:3306 my-image
Run Code Online (Sandbox Code Playgroud)

当我附加到图像时,它似乎工作得很好:

# from the host
> docker exec -it <my_image_name> bash

#inside of the container now
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
[...]
Run Code Online (Sandbox Code Playgroud)

但是我没有从主持人那里获得那么多成功:

> mysql -P 12345 -uroot
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Run Code Online (Sandbox Code Playgroud)

更多细节

  • 我看到有一个看起来像我的问题.但是,它实际上并不相同(并且它无论如何都没有任何答案)
    • 我已经看到有专门用于mysql的图像,但我没有用它们取得更多成功
    • grep -v可能觉得很奇怪.无可否认,可能有更清洁的方法.但是,当我附加到我的图像时,我可以观察它实际上按预期工作(即:删除了bind-address).我可以在容器中看到/var/log/mysql/error.log

服务器主机名(bind-address):'0.0.0.0'; port:3306 - '0.0.0.0'解析为'0.0.0.0'; 在IP上创建的服务器套接字:'0.0.0.0'.

man*_*ekq 129

如果您的Docker MySQL主机运行正常,您可以从本地计算机连接到它,但您应该指定主机,端口和协议,如下所示:

mysql -h localhost -P 3306 --protocol=tcp -u root
Run Code Online (Sandbox Code Playgroud)

将3306更改为您从Docker容器转发的端口号(在您的情况下,它将是12345).

因为您在Docker容器中运行MySQL,所以套接字不可用,您需要通过TCP连接.在mysql命令中设置"--protocol"将改变它.

  • 经过长时间的努力,我找到了这个金色的答案,`--protocol = tcp`终于使连接工作了.感谢@maniekq通过您的评论获得了很好的答案以及您对套接字的解释! (6认同)
  • 我不是Unix通信方面的专家,但据我所知,socket是一个表示为文件的连接.由于套接字文件不在Docker容器和主机之间共享,因此MySQL客户端无法使用Docker容器内部的一个.要从主机连接到Docker容器内的MySQL服务器,你可以:1.设置MySQL服务器将套接字放在指定位置`--socket =/var/run/mysqld/mysqld.sock` 2.将此文件挂载到Docker容器3.使用`--socket =/host/mysql.sock`指定MySQL客户端中套接字的路径 (5认同)
  • 你能解释一下为什么mysql套接字不可用吗?你的命令有效,但我想知道是否有办法将 mysql 套接字从容器安装到主机。 (4认同)
  • 这对我有用。我只需要在末尾添加“-p”,这样 MySQL 就会要求输入密码。 (3认同)
  • 这不应该是公认的答案,因为他明确表示他不了解 UNIX 文件通信。 (2认同)

Vas*_*cal 36

如果您使用"127.0.0.1"而不是localhost,mysql将使用tcp方法,您应该能够连接容器:

mysql -h 127.0.0.1 -P 3306 -u root
Run Code Online (Sandbox Code Playgroud)

  • 我可以验证一旦我将 localhost 更改为 127.0.0.1 并删除了协议标志,它的工作方式是一样的 (5认同)
  • 我不相信是这种情况。不投票,因为我不是 100% 确定,但根据我的经验 localhost 和 127.0.0.1 总是尝试使用套接字,除非您添加 --protocol=tcp (2认同)
  • 我认为这是简短而最好的答案;) (2认同)
  • 这就是我对任何更高职责的数据库的推荐。它就像“-v socketfile.sock”一样简单,然后是 mysql --socket /path/file.sock 而不会污染tcp/ip堆栈。 (2认同)

l3x*_*l3x 22

我建议查看docker-compose.这是如何工作的:

创建一个名为docker-compose.yml的文件,如下所示:

version: '2'

services:

  mysql:
    image: mariadb:10.1.19
    ports:
      - 8083:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: wp
Run Code Online (Sandbox Code Playgroud)

接下来,运行:

$ docker-compose up

笔记:

现在,您可以这样访问mysql控制台:

$ mysql -P 8083 --protocol = tcp -u root -p

Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.5.5-10.1.19-MariaDB-1~jessie mariadb.org binary distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 您可以传递-d标志以在分离/后台模式下运行mysql/mariadb容器.

  • 密码是"wp",它在docker-compose.yml文件中定义.

  • 与maniekq相同的建议,但与docker-compose的完整示例.

  • --protocol = tcp为我解决了所有问题。谢谢! (3认同)

Job*_*bin 16

简单的方法是将mysql unix套接字共享给主机.然后通过套接字连接

脚步:

  • 为主机创建共享文件夹,例如: mkdir /host
  • 使用卷装入选项运行docker容器docker run -it -v /host:/shared <mysql image>.
  • 然后更改mysql配置文件/etc/my.cnf并将文件中的套接字条目更改为socket=/shared/mysql.sock
  • service mysql restart在docker中重启MySQL服务
  • 最后通过套接字从主机连接到MySQL servver mysql -u root --socket=/host/mysql.sock.如果密码使用-p选项


Enr*_*uti 11

您应该检查分配给正在运行的容器的 IP 地址,然后连接到该主机:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container name or id>

您可以连接:

mysql -h <IP provided by inspect command> -P <port> -u <user> -p <db name>

https://mariadb.com/kb/en/installing-and-using-mariadb-via-docker/#connecting-to-mariadb-from-outside-the-container

  • 谢谢,这正是我正在寻找的通过 mysql 客户端连接到数据库的方法。 (3认同)

小智 7

在您的终端中运行:docker exec -it container_name /bin/bash 然后:mysql

  • 问题询问如何从主机连接。问题描述指出他们能够从容器内进行连接。 (3认同)

cxw*_*gyi 7

好的。我终于解决了这个问题。以下是我在https://sqlflow.org/sqlflow 中使用的解决方案。

完整的解决方案

为了使演示自包含,我将所有必要的代码移至https://github.com/wangkuiyi/mysql-server-in-docker

解决方案的关键

我不使用 DockerHub.com https://hub.docker.com/r/mysql/mysql-server上的官方镜像。相反,我通过在 Ubuntu 18.04 上安装 MySQL 来创建自己的。这种方法让我有机会启动 mysqld 并将其绑定到 0.0.0.0 (all IPs)

有关详细信息,请参阅我的 GitHub 存储库中的这些行

SQLFLOW_MYSQL_HOST=${SQLFLOW_MYSQL_HOST:-0.0.0.0}

echo "Start mysqld ..."
sed -i "s/.*bind-address.*/bind-address = ${SQLFLOW_MYSQL_HOST}/" \
    /etc/mysql/mysql.conf.d/mysqld.cnf
service mysql start
Run Code Online (Sandbox Code Playgroud)

验证我的解决方案

  1. Git 克隆上述 repo。
    git clone https://github.com/wangkuiyi/mysql-server-in-docker
    cd mysql-server-in-docker
    
    Run Code Online (Sandbox Code Playgroud)
  2. 构建 MySQL 服务器 Docker 镜像
    docker build -t mysql:yi .
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在容器中启动 MySQL 服务器
    docker run --rm -d -p 23306:3306 mysql:yi
    
    Run Code Online (Sandbox Code Playgroud)
  4. 如果尚未在主机上安装 MySQL 客户端。我在主机(我的工作站)上运行 Ubuntu 18.04,所以我使用apt-get.
    sudo apt-get install -y mysql-client
    
    Run Code Online (Sandbox Code Playgroud)
  5. 从主机连接到容器中运行的 MySQL 服务器。
    mysql --host 127.0.0.1 --port 23306 --user root -proot
    
    Run Code Online (Sandbox Code Playgroud)

从同一主机上的另一个容器连接

我们甚至可以从另一个容器(在同一主机上)运行 MySQL 客户端。

docker run --rm -it --net=host mysql/mysql-server mysql \
   -h 127.0.0.1 -P 13306 -u root -proot
Run Code Online (Sandbox Code Playgroud)

从另一台主机连接

在我的 iMac 上,我使用 Homebrew 安装 MySQL 客户端。

brew install mysql-client
export PATH="/usr/local/opt/mysql-client/bin:$PATH"
Run Code Online (Sandbox Code Playgroud)

然后,我可以访问上面的Ubuntu主机(192.168.1.22)。

mysql -h 192.168.1.22 -P 13306 -u root -proot
Run Code Online (Sandbox Code Playgroud)

从运行在另一台主机上的容器连接

我什至可以在 iMac 上运行的容器中运行 MySQL 客户端,以连接到我的 Ubuntu 工作站上容器中的 MySQL 服务器。

docker run --rm -it --net=host mysql/mysql-server mysql \
    -h 192.168.1.22 -P 13306 -u root -proot
Run Code Online (Sandbox Code Playgroud)

特例

如果我们在同一主机上运行的不同容器中运行 MySQL 客户端和服务器——这可能发生在我们设置 CI 时,我们不需要构建我们自己的 MySQL 服务器 Docker 映像。相反,我们可以--net=container:mysql_server_container_name在运行客户端容器时使用 。

启动服务器

docker run --rm -d --name mysql mysql/mysql-server
Run Code Online (Sandbox Code Playgroud)

启动客户端

docker run --rm -it --net=container:mysql mysql/mysql-server mysql \
 -h 127.0.0.1 -P 3306 -u root -proot
Run Code Online (Sandbox Code Playgroud)


小智 6

如果你在docker-machine下运行docker?

执行以获取IP:

docker-machine ip <machine>
Run Code Online (Sandbox Code Playgroud)

返回机器的ip并尝试连接mysql:

mysql -h<docker-machine-ip>
Run Code Online (Sandbox Code Playgroud)


小智 6

  • docker run -e MYSQL_ROOT_PASSWORD=pass --name sql-db -p 3306:3306 mysql

  • docker exec -it sql-db bash

  • mysql -u root -p


小智 5

我通过在服务器上运行一个临时Docker容器来做到这一点,所以我不必担心主机上安装了什么。首先,我定义我需要的(您应该针对自己的目的进行修改):

export MYSQL_SERVER_CONTAINER=mysql-db
export MYSQL_ROOT_PASSWORD=pswd 
export DB_DOCKER_NETWORK=db-net
export MYSQL_PORT=6604
Run Code Online (Sandbox Code Playgroud)

我总是创建一个新的docker网络,其他所有容器都需要:

docker network create --driver bridge $DB_DOCKER_NETWORK
Run Code Online (Sandbox Code Playgroud)

启动一个mySQL数据库服务器:

docker run --detach --name=$MYSQL_SERVER_CONTAINER --net=$DB_DOCKER_NETWORK --env="MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" -p ${MYSQL_PORT}:3306 mysql
Run Code Online (Sandbox Code Playgroud)

捕获新服务器容器的IP地址

export DBIP="$(docker inspect ${MYSQL_SERVER_CONTAINER} | grep -i 'ipaddress' | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])')"
Run Code Online (Sandbox Code Playgroud)

打开服务器的命令行界面:

docker run -it -v ${HOST_DATA}:/data --net=$DB_DOCKER_NETWORK --link ${MYSQL_SERVER_CONTAINER}:mysql --rm mysql sh -c "exec mysql -h${DBIP} -uroot -p"
Run Code Online (Sandbox Code Playgroud)

当您退出mySQL接口时,最后一个容器将自行删除,而服务器将继续运行。您还可以在服务器和主机之间共享卷,以使导入数据或脚本更加容易。希望这可以帮助!


Ham*_*fri 5

mysql -u root -P 4406 -h localhost --protocol=tcp -p
Run Code Online (Sandbox Code Playgroud)

请记住更改用户、端口和主机,使其与您的配置相匹配。如果您的数据库用户配置了密码,则需要 -p 标志