现有一个windows系统(为方便描述,名称为A),在此系统上安装VirtualBox并安装一个centos7的虚拟机(名称为B),然后在B里安装docker及docker-compose。之后在B里启动一个docker容器(名称为C,启动容器的命令在下面)。它们的网络配置如下:

| 标识 | 类型 | ip | 子网掩码 | 网关 | | --- | --- | --- | --- | --- | | A | windows系统 | 192.168.1.5 | 255.255.255.0 | 192.168.1.1 | | B | 虚拟机| 192.168.1.115 | 255.255.255.0 | 192.168.1.1 | | C | 虚拟机中的docker | 172.23.0.2 | 255.255.0.0 | 172.18.0.1 |

其中C的ip是由docker自动分配的,使用 docker inspect mysqlTemp | grep IPAddress 可以查看到C的ip地址,每次重新创建C时ip地址会变动。

启动容器C的docker-compose.yml为

version: "3"

services:
  mysqlTemp:
    image: mysql:5.7
    container_name: mysqlTemp
    ports:
      - "13306:3306"
    command: 
      --character-set-server=utf8
      --collation-server=utf8_unicode_ci
      --max_allowed_packet=128M
      --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO" 
    environment:
      - MYSQL_ROOT_PASSWORD=abc123
      - MYSQL_DATABASE=test_db
      - MYSQL_USER=abc123
      - MYSQL_PASSWORD=abc123
      - TZ=Asia/Shanghai

问题:

问题一: A能ping通C吗?

问题二: A能访问C的端口吗?

答案:

答案一: 直接在A上ping C的ip地址172.23.0.2是不通的。但是先执行命令

route add 172.23.0.0 MASK 255.255.0.0 192.168.1.115

(此命令需要在windows系统即A上执行,其中172.23.0.0是根据C的ip地址设置的,注意把最后个数字置成0;255.255.0.0对就B系统中docker0网卡的掩码,执行ifconfig docker0即可看到,一般都是255.255.0.0;192.168.1.115是B系统的ip地址)

这时发现A能ping通C了。(若A不能ping通C,尝试将B系统的防火墙关闭,再尝试ping)

答案二:上述docker-compose.yml中配置的是将C的3306映射成B的13306,因为A能ping通B,所以A也能telnet通B的13306端口。

telnet 192.168.1.115 13306

(执行上面命令时注意关闭B的防火墙)

接下来我们尝试用A系统telnet 一下C的3306端口。

telnet 172.23.0.2 3306

竟然成功了!

这时我们把docker-compose.yml中的ports节点及其属性全部删除,再重启,这时C的ip会变动,根据ip去在A系统中执行答案一中的route命令,再次尝试在A系统telnet C,发现竟然能连通。

尽管能用。但是我也不知道原因。