问题说明
解决:Mac中的Docker宿主机与容器不能通信!
之前我遇到一个问题,好久不能得到解答,前几天终于茅塞顿开,为此我在放假期间,特意学了一遍Docker,Dockerfile、数据存储volume、网络通信 从数据卷、网络方面入手,我当时所困惑的问题是为什么用客户端从外网可以访问,但是我容器中的PHP代码不能访问呢?
访问代码:
$redis = new Redis();
try{
$redis->connect('172.17.0.4',6379 );
echo "Connection to server successfully".PHP_EOL;
//查看服务是否运行
echo "Server is running: " . $redis->ping().PHP_EOL;
}catch ( Exception $e ){
echo $e->getMessage();
}
“Connection refused”报错信息,是因为没有开启服务端,或者网络不通。我想尽办法都还是不行。
后来知道了底层的网络原理,原因是这样的,Docker的通信默认是网桥,宿主机和容器不在同一个网桥里,Mac的网桥里少了Docker0网段,外部部署的网络之所以能通是因为访问服务时,网段进行了网络的Nat的自动转换,原来是这样。
知道的原理确实是不一样的,之后我也遇见过类似的问题,便可轻松化解,下面我说一下这个问题的解决办法。
1. 使用 docker-connector,然后执行以下命令把 docker 的所有 bridge 网络都添加到路由中。
brew install wenjunxiao/brew/docker-connector
docker network ls --filter driver=bridge --format "{{.ID}}" | xargs docker network inspect --format "route {{range .IPAM.Config}}{{.Subnet}}{{end}}" >> /usr/local/etc/docker-connector.conf
也可以手动修改 /usr/local/etc/docker-connector.conf 文件中的路由,格式是:
route 172.17.0.0/16
配置完成,直接启动服务(需要 sudo,路由配置启动之后仍然可以修改,并且无需重启服务立即生效)
sudo brew services start docker-connector
docker run -it -d --restart always --net host --cap-add NET_ADMIN --name connector wenjunxiao/mac-docker-connector
查看容器,启动成功了,问题就解决了,访问时把容器Ip绑定在Dns上就可以了。
~ docker ps
7c25a002e978 wenjunxiao/mac-docker-connector "mac-receiver"
测试一下,Mysql、Redis都可以链接了!
$redis = new Redis();
try{
$redis->connect('172.17.0.4',6379 );
echo "Connection to server successfully".PHP_EOL;
//查看服务是否运行
echo "Server is running: " . $redis->ping().PHP_EOL;
}catch ( Exception $e ){
echo $e->getMessage();
}