Docker:MySQL拒绝主机IP,除非我手动重新启动

这是我的Dockerfile:

FROM debian:jessie-backports RUN apt-get update --yes && apt-get upgrade --yes RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ git \ curl \ build-essential\ libssl-dev\ ca-certificates\ mysql-server\ redis-server\ elasticsearch USER root ENV HOME /root # MYSQL SETUP RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/#bind-address = 0.0.0.0/" /etc/mysql/my.cnf RUN sed -i -e"s/^#max_connections\s*=\s*100/max_connections = 200/" /etc/mysql/my.cnf RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf VOLUME ["/var/lib/mysql", "/var/log/mysql"] EXPOSE 3306 # REDIS SETUP RUN echo "daemonize yes\nbind 0.0.0.0" >> /etc/redis/redis-serve.conf RUN sed 's/^daemonize no/daemonize yes/' -i /etc/redis/redis.conf \ && sed 's/^bind 127.0.0.1/bind 0.0.0.0/' -i /etc/redis/redis.conf \ && sed 's/^# unixsocket /unixsocket /' -i /etc/redis/redis.conf \ && sed 's/^# unixsocketperm 755/unixsocketperm 777/' -i /etc/redis/redis.conf \ && sed '/^logfile/d' -i /etc/redis/redis.conf VOLUME ["/var/lib/redis", "/var/log/redis"] EXPOSE 6379 6380 # ELASTICSEARCH SETUP RUN sed 's/^#START_DAEMON=true/START_DAEMON=true/' -i /etc/default/elasticsearch VOLUME ["/opt/elasticsearch/data", "/opt/elasticsearch/logs"] EXPOSE 9200 9300 ADD docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh RUN chmod 777 /usr/local/bin/docker-entrypoint.sh ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] 

入口点:

 #!/bin/bash /etc/init.d/mysql start /etc/init.d/redis-server start /etc/init.d/elasticsearch start /bin/bash 

而我运行的命令启动容器:

 docker run -i -t -p 3306:3306 -p 6379:6379 -p 9200:9200 -p 9300:9300 assethost 

我想从主机连接到在容器中运行的MySQL服务器,但这是我尝试连接时发生的情况:

ERROR 1130 (HY000): Host '192.168.99.1' is not allowed to connect to this MySQL server

Redis和Elasticsearch都暴露自己就好了。 MySQL只会开始接受外部主机,如果我从运行该容器时入口出现的Bash shell手动重新启动它。 我必须运行/etc/init.d/mysql restart 。 只有这样,我才能使用MySQL客户端从主机成功连接。

请注意,我正在使用docker-machine ,所以我必须为MySQL客户端提供主机IP才能连接。

我怎么能够从主机连接到容器中运行的MySQL实例,而不必手动重新启动MySQL?

Docker版本1.12.1,build 23cf638

我想出了一个方法来获得skip-grant-tables选项在启动时应用。

解决方法

在docker-entrypoint.sh中,我将/etc/init.d/mysql start更改为

HOME=/etc/mysql /usr/bin/mysqld_safe > /dev/null 2>&1 &

其他变化

由于在my.cnf中已经有一个[mysqld]部分,所以我在Dockerfile RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf修改了下面一行: RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf

RUN sed -i '/\[mysqld\]/ a skip-grant-tables\nskip-name-resolve' /etc/mysql/my.cnf

我添加了skip-name-resolve所以mysql不会为本地IP地址parsing名字。

注意事项

执行/etc/init.d/mysql restart时,解决方法不再有效,但是/etc/init.d/mysql stop; /etc/init.d/mysql start /etc/init.d/mysql stop; /etc/init.d/mysql start保存了'skip-grant-tables'选项。

我猜MySQL安装后已经启动了,运行sed改变configuration不会生效。 入口点你有mysql start但它可能是看到MySQL已经运行,没有做任何事情。 尝试改变这个命令到mysql restart ,所以你的入口点bash脚本变成:

 #!/bin/bash /etc/init.d/mysql restart /etc/init.d/redis-server start /etc/init.d/elasticsearch start /bin/bash 

您正在使用skip-grant-tables标志来login而不使用密码。 我觉得由于/etc/init.d/mysql脚本的某些原因,第一次启动时忽略该标志,使得来自root@192.168.99.1的连接被拒绝。 我相信Docker与这个问题无关。

要回答您的问题, 您不必手动重新启动 ,您可以将您的入口点更改为:

 #!/bin/bash /etc/init.d/mysql start # Wait for mysql to be fully up, then restart (eg, 5 seconds) sleep 5 /etc/init.d/mysql restart /etc/init.d/redis-server start /etc/init.d/elasticsearch start /bin/bash 

或者,不要使用/etc/init.d/mysql start ,而是直接调用mysqld

 #!/bin/bash mysqld & /etc/init.d/redis-server start /etc/init.d/elasticsearch start /bin/bash 

另外,虽然在my.cnf中创build一个[mysqld]组不是问题,但是应该在现有的组中添加新的configuration:

 RUN sed -i '/\[mysqld\]/a skip-grant-tables' /etc/mysql/my.cnf 

参考文档中的几种启动/停止Mysql服务器的方法