docker-compose 如何访问外部容器? docker容器间访问的网络设置浅谈

本文详细介绍了如何使Docker Compose创建的容器能够访问外部已存在的MySQL容器。主要步骤包括创建自定义网络、将MySQL容器加入自定义网络以及在docker-compose.yml中配置网络,确保所有容器在同一网络环境下,从而实现互通。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

docker-compose是用于定义和运行多容器 Docker 应用程序的工具,通过docker-compose可以方便地协调多个容器的运行。
一般在使用docker-compose启动服务时,被同一个docker-compose.yml定于的服务(容器)会运行在一个隔离环境中,也就是说在这个环境中的容器是不能直接访问(如果没有设置的话)当前docker-compose外部的其它容器的,那么如何设置才能使compose中的容器访问外部容器呢?
本文以能够使compose启动的容器可以访问docker中已存在的mysql容器为目标进行讲解。docker容器间互相访问和docker-compose访问外部容器的原理是相同的。

环境

CentOS7 虚拟机环境
mysql 5.7
docker 19.03
docker-compose 1.29.1

问题描述

安装Docker时,Docker会默认创建一个内部的桥接网络docker0,每创建一个容器分配一个虚拟网卡,容器之间可以根据ip互相访问。

[root@master ~]# ifconfig 
docker0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:ecff:fefb:4f56  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ec:fb:4f:56  txqueuelen 0  (Ethernet)
        RX packets 439143754  bytes 128557512771 (119.7 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 204101251  bytes 111401928320 (103.7 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

显然上面网卡的地址是172.17.0.1,然后看一下其他容器的IP地址,如:

[root@master ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
13ed457ceeff        redis               "docker-entrypoint.s…"   6 months ago        Up 5 hours          0.0.0.0:6379->6379/tcp              redis
b7c1837830d4        mysql:5.7           "docker-entrypoint.s…"   6 months ago        Up 6 minutes        0.0.0.0:3306->3306/tcp, 33060/tcp   mysql

mysql的这个容器(b7c1837830d4)已经提前创建,并进行了端口映射,映射到了宿主机的3306端口,可以在外部直接访问本mysql;
查看docker内mysql的地址:

[root@master ~]# docker inspect b7c1837830d4
...
  "Networks": {
       "bridge": {
           "IPAMConfig": null,
           "Links": null,
           "Aliases": null,
           "NetworkID": "4f2301f96036e312cf04bc2d893764f39493090e35d15a3d0bc46980a3817e9a",
           "EndpointID": "1cc6ba035ff2f68d85db21651a2c0b09be94f54f84fd8cfca5ee779703fa1130",
           "Gateway": "172.17.0.1",   //关键
           "IPAddress": "172.17.0.2", //关键
           "IPPrefixLen": 16,
           "IPv6Gateway": "",
           "GlobalIPv6Address": "",
           "GlobalIPv6PrefixLen": 0,
           "MacAddress": "02:42:ac:11:00:04",
           "DriverOpts": null
       }
   }
...

如果不设置,默认创建的容器在172.17.0.0 网段下,gateway都是172.17.0.1,此时这些同一网段的容器是可以互通的。
但是使用docker-compose创建的容器一般都处于另一个网段,在本例中启动的docker-compose都在172.18.0.0的网段中,因此compose中的容器无法访问到mysql容器。

前置知识

docker的network模式

docker中有三种网络模式:

  • bridge:桥接 docker (默认)
  • none:不配置网络
  • host:和宿主机共享网络
    可通过以下命令查看:
[root@centos703 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
72f43ccbceb3        bridge              bridge              local
224a641ac129        host                host                local
4ce41b9297c2        none                null                local

创建出的容器默认都是bridge,可以通过以下命令查看当前network下有哪些容器(通过name和容器id辨识):

docker network inspect network名称

[root@centos703 ~]# docker network inspect bridge
...
"Containers": {
            "13ed457ceeff98a4f47898016285a7cd84aab6655153c191c1cdb44b1ac8ee3f": {
                "Name": "redis",
                "EndpointID": "16b2fbb4a5893bdce43aac784a7f1dd52dda3bfd4930014b0bfae23aacb27a03",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "aded9df072e329423c7c24cc2f5722d49c5725a0eef024f3d382d4a09a84d826": {
                "Name": "stupefied_perlman",
                "EndpointID": "04db10227da5a189c23b80fab649573e96e510a71f62e4e1e2bb92841d91e5ed",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
...

如果想要使docker容器之间可以互通,最方便的方法就是让容器处于同一个network之下!

实现步骤

创建自定义network

这一步的目的是自己创建一个network,然后把docker-compose还有我们已有的mysql容器都放到这个network下,这样他们就可以互通了。

[root@centos703 ~]# docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1  mynet

--driver bridge 网络模式为 桥接模式
--subnet 172.18.0.0/16 设置子网
--gateway 172.18.0.1 设置网关
--mynet 自定义的network名

查看:

[root@centos703 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
72f43ccbceb3        bridge              bridge              local
224a641ac129        host                host                local
9832e7cfc6fd        mynet               bridge              local
4ce41b9297c2        none                null                local

我们新创建的network —— mynet已经出现了。

把已有容器(mysql)的network修改为自定以network

###解除容器绑定的网络  bridge:容器以前的network  b7c:容器标识符(容器id前缀,也可写完整)
[root@centos703 ~]# docker network disconnect bridge b7c
##为容器重新指定自定义网络
[root@centos703 ~]# docker network connect b7c mynet
##重新启动容器
[root@lcentos703 ~]# docker restart b7c

查看效果:

[root@centos703 ~]# docker inspect mynet
...
"Containers": {
			"b7c1837830d4584d2e82f697bcb867e3f63801e5b51796f152e5815e0c48b01e": {
                "Name": "mysql",
                "EndpointID": "222689b1a48bce1fbce63b299b5cdd6026bf0e52bf1e04d0b924d5a49257d805",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
...

可以看到mynet的容器中出现了mysql(b7c);
查看容器的信息:

[root@centos703 ~]# docker inspect b7c
...
"Networks": {
                "mynet": {
                    "IPAMConfig": {},
                    "Links": null,
                    "Aliases": [
                        "b7c1837830d4"
                    ],
                    "NetworkID": "9832e7cfc6fd3d7557623178ad4b551c391f96fe7ce8636606005b531a1edd50",
                    "EndpointID": "222689b1a48bce1fbce63b299b5cdd6026bf0e52bf1e04d0b924d5a49257d805",
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:12:00:02",
                    "DriverOpts": {}
                }
            }
...

可以看到,网段已经变动到172.18.0.0了。

设置docker-compose的配置文件

设置docker-compose的配置文件可以参看官方文档或者中文介绍
在这里因为我们已经自定义了一个network,为了使docker-compose启动的容器和mysql容器在同一个network下,要在docker-compose.yml中指定使用已存在的network:

version: '2'

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

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

这是官网给的例子,需要在networks标签下使用external选项,指定已有的networks。
在本具体案例中,如下,设置networks - default - external - name: mynet, 并且把所有连接mysql的ip都改为上边查出来的172.18.0.2


version: '3.6'
services:
  xxl-job:
    image: registry.xx.aliyuncs.com/xxx/xxx:0.3
    container_name: xxl-job
    environment:
      #修改数据源连接
      spring_datasource_url: jdbc:mysql://172.18.0.2:3306/xxl_job?Unicode=true&characterEncoding=UTF-8
      spring_datasource_username: xxx
      spring_datasource_password: xxx
      spring_mail_host: smtp.qq.com
      spring_mail_port: 25
      spring_mail_username: xxx@qq.com
      spring_mail_password: xxx
      xxl_job_accessToken:
      xxl_job_i18n:
    ports:
      - '10052:10052'
    expose:
      - '10052'
    #networks: 可以在此处单独配置
     # networkname

    command: bash -c "/opt/froxxx/start.sh xxl-job"

  
  froxxx-monitor:
    image: registry.xxx.com/xxx/xxx:0.3
    container_name: froxxx-monitor
    environment:
      # 修改数据源连接
      datasource_frosxxx_url: jdbc:mysql://172.18.0.2:3306/froxxx?useSSL=false&verifyServerCertificate=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
      datasource_frosxxx_username: xxx
      datasource_frosxxx_password: xxx
      ...
    ports:
      - '10054:10054'
      - '9999:9999'
    expose:
      - '10054'
      - '9999'
    depends_on:
      - frosxxx-spi
    #networks: 可以在此处单独配置
     # networkname

    command: bash -c "/opt/frosxxx/start.sh frosxxx-monitor"

# 网络设置
networks:
  #可以自定义network名称,这里使用default表示如果不在service中单独配置就使用该设置 
  default: 
    external: 
      #使用自定义network
      name: mynet

修改完成后,按照docker-compose的正常启动方法启动即可:

docker-compose up

记得要把以前错误的先docker-compose down删除掉。

这时再使用下边这两条命令

# docker network inspect mynet
# docker inspect 容器名 

查看mynet下是否出新了docker-compose启动的容器,以及docker-compose启动的容器是否已经和mysql容器在同一网段,如果相同,此时docker-compose中的容器就可以和mysql互通了。

总结

关键点在于docker中network的设置。

参考

官方 Networking in Compose
Docker系列教程24-Docker Compose网络设置
docker 自定义网络设置
docker容器网络更改
docker compose 菜鸟教程

<think>嗯,用户问的是docker-compose是否必须安装。我需要先理解docker-compose的作用,以及它在Docker生态系统中的位置。Docker本身是用来管理容器的,而docker-compose则用于多容器应用的编排。 首先,要确认用户可能的使用场景。如果他们只是运行单个容器,可能不需要docker-compose。但如果是开发或测试多服务应用,比如需要数据库、后端和前端一起运行,这时候docker-compose就很有用了。 接下来,用户的身份可能是开发者或者系统管理员。开发者更可能需要管理多个服务,而系统管理员可能更关注部署和维护。不过,docker-compose对两者都有帮助,尤其是在定义服务配置方面。 然后,用户可能的需求是什么?他们可能想知道是否必须安装,或者是否有替代方案。比如,是否可以使用Docker命令手动管理多个容器,或者是否有其他编排工具如Kubernetes。不过Kubernetes更适用于生产环境的大规模编排,而docker-compose更适合本地开发和测试。 还要考虑安装docker-compose的便利性。在Docker Desktop中,它已经包含在内,但在Linux上可能需要单独安装。用户可能关心安装的复杂性和必要性。 另外,是否需要强调docker-compose的优势,比如通过YAML文件简化配置,一键启动所有服务,环境隔离等。这些优点对于项目可维护性和团队协作很重要,特别是当项目规模扩大时。 最后,要给出建议,根据用户的具体情况。如果他们只是学习Docker或运行简单应用,可能不需要。但如果是实际项目开发,尤其是多服务的情况,推荐安装。同时,可以提到替代方案,但指出docker-compose是官方推荐的工具,适合大多数情况。</think>Docker Compose 并不是 Docker 必须安装的组件,但根据使用场景的不同,它的作用会显著影响开发效率。以下是分层次解析: --- ### 一、**核心作用** Docker ComposeDocker 官方提供的**容器编排工具**,核心功能是通过 YAML 文件(`docker-compose.yml`)定义和运行多个容器组成的应用。例如: ```yaml services: web: image: nginx ports: - "80:80" db: image: mysql environment: MYSQL_ROOT_PASSWORD: example ``` --- ### 二、**必须安装的场景** 1. **多容器协作开发** 如果项目需要同时运行数据库、后端、缓存等多个服务(例如:MySQL + Redis + Spring Boot),手动通过 `docker run` 逐个启动效率低下,Docker Compose 可实现一键启动。 2. **环境配置标准化** 团队协作时,通过共享 `docker-compose.yml` 文件确保所有成员使用完全相同的环境配置,避免“在我机器上能跑”的问题。 3. **依赖关系管理** 支持定义服务启动顺序(`depends_on`)、网络隔离、存储卷挂载等复杂需求。 --- ### 三、**可不安装的场景** 1. **仅操作单个容器** 如果只需运行独立容器(例如:临时测试一个 Nginx 镜像),直接使用 `docker run` 即可满足需求。 2. **已使用其他编排工具** 若项目部署到生产环境,可能使用 Kubernetes 或 Docker Swarm 等更复杂的编排工具,此时 Docker Compose 仅用于本地开发。 --- ### 四、**安装建议** 1. **开发环境强烈推荐安装** Docker Compose 能简化开发流程,尤其适合微服务架构项目。 - Linux 安装命令: ```bash sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose ``` - Windows/macOS 用户安装 Docker Desktop 后已自带。 2. **生产环境按需选择** Docker Compose 适用于小型项目部署,但大规模生产环境建议使用 Kubernetes。 --- ### 五、**替代方案** - **手动编写 Shell 脚本**:通过脚本调用多个 `docker run` 命令,但维护成本高。 - **Makefile 工具**:定义容器启动规则,但灵活性低于 Docker Compose--- ### 总结 是否安装 Docker Compose 取决于项目复杂度: ✅ **需要**:多服务开发/测试、团队协作、环境标准化 ❌ **不需要**:单容器操作、已有高级编排工具
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值