繁体   English   中英

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

[英]Connect to mysql in a docker container from the host

(由于我对 Docker 或 mysql 管理的知识有限,这可能是一个愚蠢的问题,但由于我在这个问题上花了整整一个晚上,我才敢问。)

简而言之

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

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

更多细节

我正在使用以下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

在此文件所在的目录中,我可以成功构建映像并使用以下命令运行它:

> docker build -t my-image .
> docker run -d -p 12345:3306 my-image

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

# 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.
[...]

但是,我并没有从主持人那里取得那么大的成功:

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

更多细节

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

服务器主机名(绑定地址):'0.0.0.0'; 端口:3306 - “0.0.0.0”解析为“0.0.0.0”; 在 IP 上创建的服务器套接字:'0.0.0.0'。

如果你的 Docker MySQL 主机运行正常,你可以从本地机器连接到它,但你应该像这样指定主机、端口和协议:

mysql -h localhost -P 3306 --protocol=tcp -u root

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

因为你在 Docker 容器中运行 MySQL,所以 socket 不可用,你需要通过 TCP 连接。 在 mysql 命令中设置“--protocol”将改变它。

如果您使用“127.0.0.1”而不是 localhost mysql 将使用 tcp 方法,您应该能够通过以下方式连接容器:

mysql -h 127.0.0.1 -P 3306 -u root

我建议查看 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

接下来,运行:

$ 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>

笔记:

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

  • 密码是在 docker-compose.yml 文件中定义的“wp”。

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

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

脚步:

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

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

执行获取ip:

docker-machine ip <machine>

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

mysql -h<docker-machine-ip>

好的。 我终于解决了这个问题。 以下是我在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

验证我的解决方案

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

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

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

docker run --rm -it --net=host mysql/mysql-server mysql \
   -h 127.0.0.1 -P 13306 -u root -proot

从另一台主机连接

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

brew install mysql-client
export PATH="/usr/local/opt/mysql-client/bin:$PATH"

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

mysql -h 192.168.1.22 -P 13306 -u root -proot

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

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

docker run --rm -it --net=host mysql/mysql-server mysql \
    -h 192.168.1.22 -P 13306 -u root -proot

特例

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

启动服务器

docker run --rm -d --name mysql mysql/mysql-server

启动客户端

docker run --rm -it --net=container:mysql mysql/mysql-server mysql \
 -h 127.0.0.1 -P 3306 -u root -proot

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

export MYSQL_SERVER_CONTAINER=mysql-db
export MYSQL_ROOT_PASSWORD=pswd 
export DB_DOCKER_NETWORK=db-net
export MYSQL_PORT=6604

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

docker network create --driver bridge $DB_DOCKER_NETWORK

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

docker run --detach --name=$MYSQL_SERVER_CONTAINER --net=$DB_DOCKER_NETWORK --env="MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" -p ${MYSQL_PORT}:3306 mysql

捕获新服务器容器的 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])')"

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

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"

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

mysql -u root -P 4406 -h localhost --protocol=tcp -p

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

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

对于转换,您可以在主机中创建~/.my.cnf文件:

[Mysql]
user=root
password=yourpass
host=127.0.0.1
port=3306

然后下次只需为 mysql 客户端运行mysql以打开连接。

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

  • docker exec -it sql-db bash

  • mysql -u 根 -p

我能够使用以下命令连接在我的主机上运行的 sql server5.7:mysql -h 10.10.1.7 -P 3307 --protocol=tcp -u root -p 其中给定的 ip 是我的主机 ip,而 3307 是在 mysql docker 中转发端口。输入命令后键入 myql 的密码。就是这样。现在您已从主机连接了 mysql docker 容器

运行以下命令来运行容器

docker run --name db_name -e MYSQL_ROOT_PASSWORD=PASS--publish 8306:3306 db_name

运行此命令以在主机中获取 mysql db

mysql -h 127.0.0.1 -P 8306 -uroot  -pPASS

在你的情况下是

mysql -h 127.0.0.1 -P 12345 -uroot  -pPASS

您应该检查分配给正在运行的容器的 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

根据照片。 转到 docker 桌面应用程序中的项目 -> MySQL -> 检查选项卡并修改有关数据库 .env 文件的信息。

.env 文件示例:

DB_CONNECTION=mysql
DB_HOST=0.0.0.0:3306
DB_PORT=3306
DB_DATABASE=testdb
DB_USERNAME=sail
DB_PASSWORD=password

截图 1

截图 2

首先,查看日志是否有任何错误。

docker ps -a
docker logs container_name

如果有任何错误,请搜索该特定错误的解决方案,如果没有错误,您可以继续下一步。

请记住,启动容器后 MySQL 需要几分钟才能启动,因此请在 3-4 分钟后运行这些命令。

docker exec -it container_name bash
# ONCE YOU ARE INSIDE CONTAINER 
mysql -u root -p
SHOW DATABASES;
exit

从终端或命令提示符连接

mysql -h localhost -P 3306 --protocol=tcp -u root -p

如果这会帮助某人:

我的首选解决方案

添加 ~/.my.cnf 内容

[client]
user=<yourusername>
password=typethepasswordhere
host=127.0.0.1
port=3306

然后从终端运行>$ mysql ,你应该进入你的 sql cmd。

铁杆替代品

你也可以这样连接

docker exec -it containername mysql  

进入sql cmd

或者

docker exec -it contaiinername bash (or sh) 

在容器中连接,然后运行>$ mysql

我尝试过同样的事情,并且遇到了同样的问题,但我注意到一件事,每当我尝试使用 /bin/bash 运行 docker 容器时,如下所示:

docker 容器运行 -it --name test_mysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql:latest /bin/bash

点击上述命令后,我的容器启动但遇到相同的错误“错误2002(HY000):无法通过套接字'/var/run/mysqld/mysqld.sock'(2)连接到本地MySQL服务器”

现在,我尝试了而不是上面的命令,我使用了下面的命令:

docker 容器运行 -itd --name test_mysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql:latest

docker 容器执行 test_mysql /bin/bash

然后使用命令

mysql -uroot -P3306 -p

然后能够连接,希望这个想法适用于您的情况。

谢谢爱阿罗拉

将“localhost”更改为您的真实 con ip 地址
因为它是 mysql_connect()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM