一,Docker 网络详解
理解 Docker0
查看ip地址:
# 命令
ip addr
可以看到有3个网络(lo、eth0和docker0),问题:
思考:docker 是如何处理容器网络访问的?
查看容器的内部网络地址:
# 命令
docker exec -it 容器 ip addr
可以发现容器启动时会得到一个 eth0@ 开头的 ip 地址,是 docker 分配的。
思考:linux 能否 ping 同容器内部?
ping 172.17.0.4
可以看到,linux 是可以 ping 同容器内部的。那么,容器和容器间能互相 ping 通吗?
可以看到,容器内去 ping 另一个容器也是可以 ping 通的!
原理
1,只要安装了 docker,就会有一个网卡 docker0 桥接模式,使用的技术是 evth-pair 技术;
evth-pair 技术:就是一对虚拟设备接口,它们是成对出现的,一端连接协议,另一端彼此相连; 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备。
2,我们每启动一个 docker 容器,docker 就会给 docker 容器分配一个 ip,和一对网卡;
3,所有的 docker 容器共用着一个路由器,就是 docker0。所有的容器在不知道网络的情况下,都是 docker0 路由的,docker 会给我们的容器分配一个默认的可以 ip。
小结
- docker 使用的是 linux 的桥接,宿主机中是一个 Docker 容器的网桥 docker0;
- docker 中所有的网络接口都是虚拟的,转发效率高;
- docker 容器一删除,对应的网桥也被删除;
思考:是否可以通过容器名访问容器,避免容器重启后,ip地址改变而导致访问不到。就像微服务中,也可以通过服务名就像访问。
二,自定义网络
我们可以通过 --link 实现通过容器名访问, 但不建议这么干。 --link 的实现原理是在 hosts 配置中添加了容器名访问的映射。这种方式太不方便,所有容器启动时都需要配置 --link 指向需要容器名访问的容器。
我们可以通过自定义网络实现!即容器互联。
实现步骤:
- 创建自定义网络;
- 指定网络启动容器;
好处:
- 功能比 docker0 更完善,也可以通过容器名连接;
- 不同的集群可使用不同的网络,保证集群的安全和健康;
查看所有的docker网络:
# 命令
docker network ls
网络模式:
- bridge:桥接(默认);
- 同一主机的容器实例能够通信,但不能跨主机通信。
- 此时docker引擎会创建一个veth对,一端连接到容器实例并命名为eth0,另一端连接到指定的网桥中(比如docker0),因此同在一个主机的容器实例由于连接在同一个网桥中,它们能够互相通信。容器创建时还会自动创建一条SNAT规则,用于容器与外部通信时。如果用户使用了-p或者-Pe端口端口,还会创建对应的端口映射规则。
- none:不配置网络;
- 不设置网络,相当于容器内没有配置网卡,用户可以手动配置。
- host:主机模式,和宿主机共享网络;
- 此时容器没有使用网络的namespace,宿主机的所有设备,如Dbus会暴露到容器中,因此存在安全隐患。
- container:容器内网络连通,用得少,局限很大;
- 自定义模式:自定义网络;
- 使用自定义网络,可以使用 docker network create 创建,并且默认支持多种网络驱动,用户可以自由创建桥接网络或者overlay网络。
创建自定义网络
# 命令
docker network create
Usage: docker network create [OPTIONS] NETWORK
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
-d, --driver string Driver to manage the Network (default "bridge")
--gateway stringSlice IPv4 or IPv6 Gateway for the master subnet
--help Print usage
--internal Restrict external access to the network
--ip-range stringSlice Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network (default [])
-o, --opt map Set driver specific options (default map[])
--subnet stringSlice Subnet in CIDR format that represents a network segment
# 使用示例
docker network create --subnet 172.18.0.0/16 --gateway 172.18.0.1 mynet
启动容器
我们需要 --net 命令指定网络启动容器,不指定网络启动的话,默认使用 docker0 网络。
# 使用示例
docker run -p 3309:3306 -d --name mysql3309-net --net mynet -e MYSQL_ROOT_PASSWORD=admin mysql-lzh:1.0
docker run -p 3310:3306 -d --name mysql3310-net --net mynet -e MYSQL_ROOT_PASSWORD=admin mysql-lzh:1.0
查看是否能通过容器名连接:
# 命令
docker exec -it mysql3309-net ping mysql3310-net
可以看到能够正常连接。
查看自定义网络元数据:
# 命令
docker network inspect [自定义网络名]
# 使用示例
docker network inspect mynet
可以看到刚指定该网络启动的两个容器。
三,不同网络的容器连通
不同网段的容器正常不能相互连通,这时打通容器与另一个网段的连接,可以使用以下命令:
# 命令
docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias stringSlice Add network-scoped alias for the container
--help Print usage
--ip string IP Address
--ip6 string IPv6 Address
--link list Add link to another container (default [])
--link-local-ip stringSlice Add a link-local address for the container
# 使用示例
# docker0 网络下的 mysql3307 容器与 mynet 网络打通
docker network connect mynet mysql3307
可以看到,打通容器与自定义网络后,不同网络的容器能成功连接上该自定义网络下的容器!
用 docker network inspect mynet 命令查看下自定义网络下的元数据:
可以看到,mysql3307 容器加入到了 自定义网络mynet 下!即mysql3307 容器拥有2个ip地址!类似于阿里云服务器同时拥有公网ip和私网ip。
验证一下,使用 docker inspect mysql3307 命令查看下mysql3307 容器的元数据:
验证成功,mysql3307容器中添加了2个网络!
结论:
假设要跨网络连接容器,就需要使用 docker network connect 连通!
四,Overlay 网络-容器跨主机通信
定义:
Overlay网络是通过网络虚拟化技术,在同一张Underlay网络上构建出的一张或者多张虚拟的逻辑网络。
不同的Overlay网络虽然共享Underlay网络中的设备和线路,但是Overlay网络中的业务与Underlay网络中的物理组网和互联技术相互解耦。
解决什么问题:
overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密,当我们初始化一个swarm或是加入到一个swarm中时,在docker主机上会出现两种网络:
1、称为 ingress 的 overlay 网络,用于传递集群服务的控制或是数据消息,若在创建 swarm 服务时没有指定连接用户自定义的overlay网络,将会加入到默认的ingress网络;
2、名为docker_gwbridge桥接网络会连接swarm中所有独立的docker系统进程
可以使用docker network create创建自定义的overlay网络,容器以及服务可以加入多个网络,只有同一网络中的容器可以相互交换信息;
评论区