Docker - 一个命令部署完MySQL容器,从另外一个容器中无法访问?解决方案

Posted daopinz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker - 一个命令部署完MySQL容器,从另外一个容器中无法访问?解决方案相关的知识,希望对你有一定的参考价值。

        在同一台服务器上,分别部署了Tomcat,mysql,Redis三个容器

docker run -p 3308:3306 --name mysql_8.0_3308 -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
docker run -d --name redis_5.0_6739 -p 6379:6379 redis:5.0 --requirepass "redis"
docker run --privileged=true --restart=always --name mytomcat -p 8091:8080 -v ~/mytomcat/tomcat/webapps:/usr/local/tomcat/webapps/ -d 739cdf17cc12

        Tomcat容器内的服务启动时,需要分别连接MySQL数据库以及Redis,然后才能正常启动起来,他们的连接信息

jdbc.url=jdbc:mysql://localhost:3306/database_name?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
redis.hosts=127.0.0.1:6379

        在我本地电脑上,安装了MySQL和Redis,使用上面的连接是可以启动起来的,但是使用docker启动成容器,怎么就不行啊?

2022-02-10 02:53:47 393|ERROR|DruidDataSource.java.init:745|init datasource error, url: jdbc:mysql://localhost:3306/database_name?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
... ...
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:59)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:103)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:149)
        at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:165)
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:92)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:152)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:982)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:852)
        ... 131 more
Caused by: java.net.ConnectException: Connection refused (Connection refused)
        at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
        at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
        at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.base/java.net.Socket.connect(Socket.java:609)
        at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:173)
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:66)
        ... 134 more
2022-02-10 02:53:47 412|ERROR|DruidDataSource.java.init:776|dataSource-1 init error

        从报错的字面意思来看,数据报已经发出去了,但是没有回包回来,什么鬼、、、,明明就是没有连上数据库好嘛。。。

        其实不能怪她,她也只是按照你给它配置的连接信息,老老实实任劳任怨的吭哧吭哧的给你链接,死活也连不上。。。

        是因为docker的沙箱机制,每一个容器的环境都是独立的,即便是他们都在同一台虚拟机或者物理主机上,也是完全隔离的,想要彼此访问,要么就从外网绕一圈通过公网地址访问,要么就想办法,打通他们之间的网络连接。

Redis:

        增加一个配置文件在容器启动的时候,redis.conf

#bind 127.0.0.1
protected-mode no
appendonly yes
requirepass redis
docker run -d --name redis_5.0_6739 -v /root/docker/redis/conf/redis.conf:/etc/redis/redis.conf -p 6379:6379 redis:5.0 --requirepass "redis"

        配置文件中取消默认绑定的127.0.0.1,redis会绑定到容器的ip上

         那么,就需要改一下redis的连接串就行了; 

redis.hosts=172.17.0.3:6379

MySQL:

        嗯。。。保持不变,我们修改Tomcat

Tomcat:

        --link mysql_8.0_3308:mysql_8 的含义:mysql_8.0_3308是MySQL容器的名称;mysql_8是给他起个别名,会在在mysql数据库连接串中,代替之前配置的localhost;

        739cdf17cc12 的含义:是tomca的docker镜像

docker run --link mysql_8.0_3308:mysql_8 --privileged=true --restart=always --name mytomcat -p 8091:8080 -v ~/mytomcat/tomcat/webapps:/usr/local/tomcat/webapps/ -d 739cdf17cc12
jdbc.url=jdbc:mysql://mysql_8:3306/database_name?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false

        OK,再重启一下Tomcat容器,服务就可以正常访问啦~

以上是关于Docker - 一个命令部署完MySQL容器,从另外一个容器中无法访问?解决方案的主要内容,如果未能解决你的问题,请参考以下文章

Docker - 一个命令部署完MySQL容器,从另外一个容器中无法访问?解决方案

Docker - 一个命令部署完MySQL容器,从另外一个容器中无法访问?解决方案

Docker - 一个命令部署完MySQL容器,从另外一个容器中无法访问?解决方案

Docker容器简介及命令

Docker多容器部署LNMP环境

(Docker Nginx) Spring boot+Vue 前后端分离部署 详细完整版