Docker容器内连接宿主机即CentOS的Mysql服务器
docker的宿主机是虚拟机下的CentOS
博主最近遇到一种情况,从服务器拷贝了一份数据库在宿主机Mysql服务器上,想要用本地的数据库测试自己的代码正确性,但是项目程序都是靠docker一键部署的,于是必定要在docker容器里访问到本地的数据库。在探索中遇到了问题并得到了解决。
在docker容器里localhost并不是指宿主机的localhost
由此原因,并不能在容器中通过localhost:3306访问到宿主机的mysql
docker在运行时就建立了虚拟网卡,并命名为docker0
我们可以在宿主机上运行ifconfig看到它,这就是宿主机建立的网桥,用于与各个容器之间通信
宿主机在与容器同一局域网的IP地址一般是docker0对应的IP地址段的首个地址(如172.17.0.1)
我们可以在容器里通过172.17.0.1:3306访问到宿主机的mysql服务器
mysql服务器默认的设置为允许127.0.0.1段的ip地址访问
所以此时用172.17.0.1:3306仍然无法访问到宿主机
此时需要在设置一下mysql
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
mysql>flush privileges;
// 其中各字符的含义:
// *.* 对任意数据库任意表有效
// "root" "123456" 是数据库用户名和密码
// '%' 允许访问数据库的IP地址,%意思是任意IP,也可以指定IP
// flush privileges 刷新权限信息
docker内的应用访问宿主机上的mysql和Redis
背景:宿主机部署MySQL、Redis,docker内部署tomcat、jdk
需求:tomcat内的应用访问宿主机的MySQL和Redis
方法:
一、连接地址切记不能用localhost和127.0.0.1
这些地址代表的都是容器内的系统,根本没有访问到宿主机,会一直报连接mysql/redis异常。
二、用docker的虚拟网卡地址
在宿主机查询网卡情况------ifconfig
docker0这块虚拟网卡的 inet 地址就是正确的本地ip(如172.17.0.1)
解决Docker容器内访问宿主机MySQL数据库服务器的问题
懒得描述太多,总归是解决了问题,方法简要记录如下,虽然简要,但是完整,一来纪念处理该问题耗费的大半天时间,二来本着共享精神帮助其他遇到该问题的哥们儿,当然这个方法并不一定能解决你们的问题,但是多少能提供些解决思路.
第一,先检查防火墙,通常应该没什么问题
(问题解决之后我把这块规则去掉了,发现没什么影响,所以容器的话,可能docker已经解决了防火墙的问题,但是不排除其他人会有这个问题.)
添加规则
针对特定地址开放3306端口,一定程度上保证数据库的安全 iptables -I INPUT -s 172.17.0.2 -p tcp --dport 3306 -j ACCEPT 展示当前规则 iptables-save 将规则输出至文件 iptables-save > iptables.rules.backup 将文件内规则导出至当前防火墙,规则生效 iptables-restore < iptables.rules.backup
第二,修改MySQL配置文件,将绑定的配置注释掉,然后添加数据库user表中root用户Host记录,使该用户可以在该IP地址远程连接数据库
引起的问题:
Can’t connect to MySQL server on (111 “Connection refused”)
解决:
找到自己MySQL数据库配置文件的位置,编辑
/etc/mysql/mysql.conf.d# vi mysqld.cnf
将 bind 127.0.0.1 注释掉
开放远程连接后,会出现第二个问题:
"Host '172.17.0.2' is not allowed to connect to this MySQL server"
解决办法:
root 进入数据库,执行下方两行命令:
grant all privileges on *.* to 'root'@'172.17.0.2' identified by 'pswd' with grant option;
开放所有权限给root,当root以pswd(不一定是root登录密码,仅作为情景下登录的密码)密码从 172.17.0.2 登入的时候,允许其操作所有数据库下的所有表(也可以将 *.* 改成特定数据库下的特定表,这个随意).
flush privileges;
刷新
重启数据库
/etc/init.d/mysql stop
/etc/init.d/mysql start
再从docker访问数据库的时候就可以了
root@2395caf9da2b:~/backends# telnet 172.17.0.1 3306
Trying 172.17.0.1...
Connected to 172.17.0.1.
Escape character is '^]'.
这样的结果就是,仅开放一个IP地址的权限
注意,网上有许多好心的哥们儿也提供了修改的命令,grant all privileges on *.* to 'root'@'%' identified by 'pswd' with grant option;
就是把IP地址改成了%,这样的结果就是当root从任意机器远程连接的时候只要密码正确,都会接受,一劳永逸,不过这样多少优点安全隐患,自己把握吧.