问题情景:

师弟在阿里云服务器上通过Tomcat部署java Web项目 程序端口8080 mysql端口3306

我通过Dokcer部署了前后端分离项目,为了避免端口冲突,服务器6612:3306映射端口。

本以为需要在java后端配置文件中更改url为:

 url: jdbc:mysql://localhost:6612/liquid?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai

但是更改之后重新部署到服务器,发现程序无法连接到mysql,抛出JDBC连接异常

重新更改url为

 url: jdbc:mysql://localhost:3306/liquid?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai

 发现可以正常访问 ,前后端程序一切正常。

为什么?

使用docker-compose创建启动容器时,将各个容器之间通过network连接起来,dokcer存在着多个组网, 使用docker inspect containerId 可以查看容器信息,查看其中的网络信息。查看容器属于哪个组网。当前项目的app和mysql虽然容器ip映射到了宿主机不同的ip。但是在network:sb-10-docker_default组网中可以通过容器端口实现互联。

 

 

docker network 的 bridge模式将容器ip映射到宿主机ip,可以通过外部端口进行访问。

 

docker-compose配置networks

默认网络

例如, 假设有一个项目,目录名myapp, docker-compose.yml 配置如下:

version: "3"
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

当执行 docker-compose up 的时候。会发生以下事情:

  1. 会创建一个名字是 myapp_default网络(networks)
  2. web这个容器会加入到 myapp_default网络中,并且在网络中的名称为:web
  3. db这个容器会加入到 myapp_default网络中,并且在网络中的名称为:db

这里,每个容器都能通过应用名找到对方,例如,web容器可以通过 postgres://db:5432 来使用 Pg数据库

上面例子还有一个注意点就是端口号,注意区分HOST_PORTCONTAINER_PORT,以上面的db为例:

  • 8001 是宿主机的端口
  • 5432(postgres的默认端口) 是容器的端口

当容器之间通讯时 , 是通过 CONTAINER_PORT 来连接的。

这里有宿主机端口,那么容器就可以通过宿主机端口和外部应用连接。

更新容器

对已经启动的容器,再执行 docker-compose up 的时候,旧容器删除,然后创建一个新的容器。

新容器会加入到网络,相同的网络名称,但容器IP是不一样的。已经连接的其他容器会自己重连到新的容器IP上。

自定义网络

可能通过一级配置networks来自定义网络,可以创建更复杂的网络选项和配置,也可以用来连接已经存在的网络(不是通过compose创建的)

每个service 配置下也可以指定networks配置,来指定一级配置的网络

例如:

version: "3"
services:

  proxy:
    build: ./proxy
    networks:
      - frontend
  app:
    build: ./app
    networks:
      - frontend
      - backend
  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
    # Use a custom driver
    driver: custom-driver-1
  backend:
    # Use a custom driver which takes special options
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"
  1. 一级配置networks 用来创建自定义的网络 。这里配置了两个frontendbackend . 且自定义了网络类型。
  2. 每一个serviceg下,proxy , app , db都定义了一下networks配置。
    1. proxy 只加入到 frontend网络
    2. db 只加入到backend网络
    3. app同时加入到 frontendbackend
    4. dbproxy不能通讯,因为不在一个网络中。
    5. app和两个都能通讯,因为app在两个网络中都有配置。
    6. dbproxy要通讯,只能通过app这个应用来连接。

配置默认网络

不指定网络时,默认的网络也是可以配置的。不配置的话,默认是使用:brige,也可以修改为其他 的。

version: "3"
services:

  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres

networks:
  default:
    # Use a custom driver
    driver: custom-driver-1

指定一个已经存在的网络

多个容器,不在相同的配置中,也会有网络通讯的需求 。那么就可以使用公共的网络配置。

容器可以加入到已经存在的网络

networks:
  default:
    external:
      name: my-pre-existing-network

这里name就是指定已经存在的网络名称。
 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐