Docker 网络简单说明
docker0 网络模型小结
Docker Daemon 会创建出一个名为 docker0 的虚拟网桥 ,用来连接宿主机与容器,或者连接不同的容器。
veth pair 是用于不同network namespace间进行通信的方式,veth pair 将一个 network namespace 数据发往另一个 network namespace 的 veth。
Docker 利用 veth pair 技术,在宿主机上创建了两个虚拟网络接口 veth0 和 veth1(veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会无条件地传输给另一方)。如下图所示
也可以使用命令: ip addr
具体可以参考:http://blog.daocloud.io/docker-bridge/
docker_gwbridge
他是我们实现多个 host 之间的 container 通信的基础。 docker_gwbridge 网络在初始化或加入 Swarm 时自动创建。大多数情况下,用户不需要自定义配置,但是 Docker 允许自定义。
docker_gwbridge是一种桥接网络,将 overlay 网络(包括 ingress 网络)连接到一个单独的 Docker 守护进程的物理网络。默认情况下,服务正在运行的每个容器都连接到本地 Docker 守护进程主机的 docker_gwbridge 网络。
docker 容器无法通过 IP 访问宿主机问题
在使用 docker 的过程中需要在 docker容器中访问宿主机的80端口,而这个80端口是另外一个容器8080端口映射出去的.当我在容器里通过docker的网桥172.18.0.1访问宿主机时,居然发现:
curl: (7) Failed to connect to 172.18.0.1 port 80: No route to host
找到下面文章
https://forums.docker.com/t/no-route-to-host-network-request-from-container-to-host-ip-port-published-from-other-container/39063
正如 Docker Community Forms 所言,这是一个已知的Bug,宿主机的80端口允许其它计算机访问,但是不允许来自本机的Docker容器访问.必须通过设置firewalld规则允许本机的Docker容器访问.
可以通过在/etc/firewalld/zones/public.xml中添加防火墙规则避免这个问题;
获取 docker0 的ip
ifconfig docker0
添加 firewalld 规则
vi /etc/firewalld/zones/public.xml
# 添加
<rule family="ipv4">
<source address="172.18.0.0/16" />
<accept />
</rule>
# 或使用命令
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="172.18.0.0/16" accept"
# 重启 firewalld
firewall-cmd --reload
或
systemctl restart firewalld
测试
docker run -d -p 81:80 ikubernetes/myapp:v1
docker run -d -p 82:80 ikubernetes/myapp:v2
# 获取宿主机ip
ifconfig eth0
# 这里为 192.168.0.185
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d591c98e850 ikubernetes/myapp:v2 "nginx -g 'daemon of…" 54 seconds ago Up 53 seconds 0.0.0.0:82->80/tcp wonderful_babbage
aa46b87fa261 ikubernetes/myapp:v1 "nginx -g 'daemon of…" 57 seconds ago Up 56 seconds 0.0.0.0:81->80/tcp modest_pare
[root@localhost ~]# docker exec -it 7d591c98e850 /bin/sh
/ # wget -q -O - 192.168.0.185:81
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # wget -q -O - 192.168.0.185:82
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
# 成功访问