无法在两个泊坞容器之间进行通信

时间:2018-02-05 10:11:44

标签: java mysql spring docker spring-boot

我是docker的新手,我正在尝试将运行到我的 boot-example docker容器中的spring boot app连接到运行到我的 mymysql 的mysql服务器端口6603上的docker容器,两者都在同一台机器上运行。 事实是:如果我将我的spring-boot应用程序连接到我的 mymysql docker容器以便与数据库通信,我没有错误,一切正常。

我将弹簧启动应用程序移动到我的启动示例容器中并尝试通过Hibernate与 mymysql 容器进行通信,然后我收到这个错误:

2018-02-05 09:58:38.912 ERROR 1 --- [           main] o.a.tomcat.jdbc.pool.ConnectionPool      : Unable to create initial connections of pool.

com.mysql.jdbc.exceptions.jdbc4.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 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]

我的spring boot application.properties是:

server.port=8083
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://localhost:6603/mydockerdb
spring.datasource.username=root
spring.datasource.password=mypassword

它工作正常,直到我的春季启动应用程序在端口8082上的docker容器中运行(在正确构建docker镜像之后):

docker run -it -p 8082:8083 boot-example 

3 个答案:

答案 0 :(得分:10)

您不能在容器内使用localhost,它是容器本身。因此,您将始终收到连接拒绝错误。

你可以做以下事情 -

  1. 在Spring Boot应用程序的application.properties文件中添加主机IP。 (不推荐,因为它破坏了泊坞窗可移植性逻辑)

  2. 如果您想使用localhost,请在启动容器时使用--net=host(由于不存在逻辑网络层,因此不建议用于生产)

  3. 使用--links进行与DNS名称的容器通信。的(弃用/遗留)

  4. 创建撰写文件&使用服务名称从spring boot app调用您的数据库,因为它们将位于同一网络和高度整合。的(推荐)

  5. PS - 每当您需要将多个容器集成在一起时,请始终选择docker-compose version 3+。使用docker run|build了解基本面和&进行干/试运行。

答案 1 :(得分:5)

@ vivekyad4v建议 - 实现您的愿望的最简单方法是使用具有更好容器通信集成的docker-compose

Docker-compose是一个管理单个或多个docker容器的工具。它使用名为docker-compose.yml的单个配置文件。

有关docker-compose的更多信息,请查看documentationcompose file reference

根据我的经验,遵循SRP(单一责任原则)是一种好习惯,因此 - 为您的数据库创建一个容器,为您的应用程序创建一个容器。它们都使用您在配置中指定的网络进行通信。

以下docker-compose.yml示例可能会对您有所帮助:

version: '2'
 networks: 
 # your network name
  somename:
    driver: bridge

services:
   # PHP server
  php:
   image: dalten/php5.6-apache
   ports:
    - 80:80
   volumes:
    - .application_path:/some/application/path
   # your container network name defined at the beggining 
   networks: 
    - somename

   # Mysql server for backend
  mysql:
   image: dalten/mysql:dev
   ports:
    - 3306:3306
   # The /var/lib/mysql volume MUST be specified to achieve data persistence over container restart
   volumes:
    - ./mysql_data:/var/lib/mysql
   environment:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_DATABASE: backend
   # your container network name defined at the beggining 
   networks: 
      - somename

注意:可以通过从容器内部调用service name来实现网络内容器之间的通信。

PHP中MySQL容器的连接参数,在本例中为:

hostname: mysql
port: 3306
database: backend
user: root
password: root

答案 2 :(得分:2)

根据上述建议,Docker-compose是一种方式,但如果您不想使用compose / swarm模式。

  1. 只需使用docker network create myNet
  2. 创建自己的网络即可
  3. 在已创建的网络--network myNet
  4. 上部署您的容器
  5. 将spring.datasource.url更改为jdbc:mysql://mymysql:6603/mydockerdb
  6. 通过使用docker demon的DNS解析,容器可以相互发现,因此可以进行通信。 [默认网桥不支持DNS。使用网桥的用户定义网络。]

    有关详细信息:https://docs.docker.com/engine/userguide/networking/