一次centos Docker网桥模式无法访问宿主机Redis服务的故障排除经历

2020-06-17 07:05:45易采站长站整理

背景:

之前做了一个项目,需要在容器内访问宿主机提供的Redis 服务(这是一个比较常见的应用场景哈), 常规方案:

① 主机网络(

docker run --network=host
): 完全应用主机网络堆栈,在容器内localhost就是指向宿主机

② 网桥网络(

docker run --network=bridge
): 这也是docker容器默认的网络通信模式,容器内localhost 指向的是容器自身,不能使用 localhost 访问宿主机上localhost:6379承载的Redis服务 。

docker会默认建立docker0 网桥;

网桥有一个网关ip, 有一个子网段; 网桥内容器从子网段中确定容器ip( ip addr eth0), 网桥内容器可通过 service name相互访问;

网桥内容器通过 docker0 Getway得以访问外网。

不做骚操作,沿用常见的②网桥模式:

第一步:自定义网桥并应用该自定义网桥


docker network create --gateway 172.16.1.1 --subnet 172.16.1.0/24 app_bridge


docker run --network=app_bridge --name ......

# 以下截取自docker-compose.yml文件
......
networks:
default:
name: app_bridge
external: true

为啥不利用默认docker0网桥?

本文开头已讲: docker0 是默认网桥,新建的容器默认都会加入这个网桥,所以我们需要建立一个专属于本程序的网桥app_bridge

第二步:容器内建立 对应于宿主机的别名

为实现在容器内网桥模式访问宿主机localhost:6379 的服务, 必须搭配docker 提供的 –add-host 选项(对应到docker-compose.yml这个配置是extra_host)。


docker run 的--add-host 选项能在 容器 /etc/hosts 文件增加行记录,便于我们使用该名称访问其他网络。

docker run -it --add-host dockerhost:172.16.1.1 ubuntu cat /etc/hosts
172.17.0.22 09d03f76bf2c
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
172.16.1.1 dockerhost

之后在程序的配置文件即可应用 dockerhost:6379 访问宿主机Redis服务。

—————————————— 稍熟悉docker网络模型的朋友应该 都能理解并完成上述操作—————————————————–

一个状况:

我在公司CentOS7机器上使用上述操作, 容器内一直无法连通宿主机(容器间还是能正常访问)。

简化问题测试:新建容器,在容器内尝试ping docker0 网关, 哔了狗了,4台公司机器都ping不通docker0网关,外网还是正常访问。