docker网络(原生网络、自定义网络、容器间通信、外网访问容器、跨主机容器网络)

本文详细介绍了Docker的网络模型,包括原生的bridge、host和none模式,强调了桥接模式下容器的网络访问方式。接着探讨了自定义网络的创建与配置,如指定子网、网关和IP。此外,讲解了容器间的通信机制,如内嵌DNS服务器、使用--link以及joined方式。同时,阐述了如何使外部访问容器,以及跨主机容器网络的解决方案,如overlay、macvlan,并举例说明macvlan在网络层面的实现。

1.docker原生网络

docker在安装好时会有3种网络模型:bridge(默认),host,none
docker network ls
**docker在安装好后会自动新建一个docker0的接口,所有的容器都会自动桥接到docker0 上 **
在这里插入图片描述
在这里插入图片描述


1.1 桥接模式

桥接模式下容器没有公共ip,只有宿主机可以访问,外部主机不可见。
容器要访问外网必须通 过宿主机的NAT规则,所以在物理机上需要打开ip_forward路由转发功能。
容器启动时,默认会生成一个网络对,一头连接容器,一头连接docker0,类似于网线的两端,实现了容器和宿主机的数据互通。

docker run -d --name nginx nginx
brctl show 可以看到桥接到了docker0上
在这里插入图片描述
在这里插入图片描述


1.2 host模式

host模式可以让容器共享宿主机的网络栈,可以让外部直接与容器通信,但是少了容器网络的隔离性。
docker run -it --name vm1 --network host ubuntu在容器内执行ipaddr,看到和宿主机一样的网卡信息
ip addr ##发现确实和容器内看到的一致

在这里插入图片描述

1.3 none模式(禁用网络模式)

有一些应用不需要连接外网,或者存放的数据是重要或秘密数据,可以使用none模式
docker run -it --name vm2 --network none ubuntu在容器内执行ipaddr,可以看到只有一个lo接口
在这里插入图片描述


2.docker自定义网络

三种网络驱动:
1.bridge(自定义的bridge带dns解析功能,可以 直接使用vm1vm2这种名字去访问,不一定要使用ip)
2.overlay
3.macvlan,后面两种用 于跨主机的网络,也就是集群等)

2.1 创建自定义网络

docker network create --help ##可以看到如果不指定驱动,默认使用bridge
docker network create -d bridge my_net1 创建一个名为 my_net1的自定义网络
docker network ls
docker run -it --name vm1 --network my_net1 ubuntu 运行容器, 可以看到分配了一个172.18网段的ip,容器的ip是单调递增,网段也是
docker network inspect my_net1

在这里插入图片描述
在这里插入图片描述


2.2 自定义网段、网关

docker network create -d bridge --subnet 172.22.0.0/24 --gateway 172.22.0.1 my_net2 指定子网和网关
docker network ls
docker run -it --name vm2 --network my_net2 ubuntu 运行容器查看ip addr,看到分配到了一个172.22.0.2的ip

在这里插入图片描述


2.3 自定义ip

docker run -it --name vm3 --network my_net2 --ip172.22.0.100 ubuntu
注意:使用–ip参数时,必须有之前的bridge网络模式的配置–subnet
在这里插入图片描述
在这里插入图片描述

brctl show 看到my_net2上桥接了2块网卡,my_net1 只有一个
iptables-S 查看防火墙规则,来自docker网卡之间的数据包双向都被丢弃

在这里插入图片描述
在这里插入图片描述


2.4 配置容器间的通信

docker network connect my_net2 vm1
docker container attach vm1 可以看到vm1上现在有两个子网的ip,ping容器名也能ping通,自带dns解

在这里插入图片描述
在这里插入图片描述
vm1能ping通vm3的原因是给vm1上又添加了一个网络接口并桥接在my_net2上


3.容器间的通信

3.1 内嵌DNSserver

除了使用–network指定ip访问以外,docker在1.10以后,都会内嵌一个DNSserver
docker run -it --name vm1 --network my_net1 ubuntu
docker run -it --name vm2 --network my_net1 ubuntu
在这里插入图片描述


3.2 joined方式

joined方式类似于默认的host模式,容器之前共享网络

docker run -it --name vm1 ubuntu
docker run -it --name vm2 --network container:vm1 ubuntu 指定共享的容器
这样两个容器之间可以使用localhost(回环接口)进行快速通信,适用于web服务器和应用服务器。

在这里插入图片描述


3.3 使用–link来链接两个容器

docker run -d nginx 先打开一个容器
docker ps获得系统分配的名称
docker run -it --name vm1 --link elastic_cohen:web ubuntu使用–link来链接两个容器,可以ping通
容器里做了下面两件事:
1.容器里添加了解析
2.环境变量里设置了相应的地址和ip

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


docker stop elastic_cohen
docker run -d nginx 再打开一个新的nginx(让172.17.0.2被占用)
docker ps
docker inspect
docker start elastic_cohen
docker start vm1
iptables -t nat -S查看火墙策略
docker network ls查看docker网络
docker container attach vm1 ping baidu发现是通的

容器访问外网是通过iptables的SNAT实现的,容器和docker0是桥接的方式,docker0是容器的网关,到达docker0后,通过linux内核的路由功能(ip_forward),然后防火墙会做地址伪装,也就是SNAT,然后通过物理网卡接口到外网
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从防火墙策略和docker网络中也可以看出,每个桥接都做了地址伪装在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


4.外网如何访问容器

docker run -d --name vm1 -p 80:80 nginx做端口映射(冒号 后的是容器内部的端口)
docker port vm1查看容器端口映射情况 80/tcp->0.0.0.0:80
iptables -t nat -S 查看防火墙策略
curl localhost 测试访问
netstat -atnulp每当运行一个容器,就会开启一个docker-proxy进程
docker run -d --name vm2 -p 808:80 nginx看到有2个docker-proxy进程

在这里插入图片描述
外部主机访问时–> 宿主机的eth0(172.25.0.1:80)–>DNAT–>172.17.0.3(容器地址)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
宿主机访问本机容器使用iptables的DNAT,外部主机访问容器或者容器之间访问是docker-proxy实现的。
外部主机 --> 宿主机eth0–>docker-proxy(外部访问容器时通过docker-proxy处理数据 包,不是防火墙)–>docker0(172.17.0.1)–> 容器


5.跨主机容器网络

解决方案:
1)docker原生:overlay和macvlan
2)第三方:flannel、weave、calico

libnetwork(docker容器网络库)和docker集成在一起解决方案。其中CNM (ContainerNetworkModel)是libnetwork的核心,它对容器网络进行了抽象)

CNM由3部分组成:
1.Sandbox:容器的网络栈。包含容器的interface、路由表和DNS等 2.Endpoint:作用是将Sandbox接入Network。(生成vethpair,虚拟网络对,相当于网线的两端)
3.Network:包含一组Endpoint,同一Network的Endpoint可以直接通信

macvlan网络方案实现(使用的是linux内核虚拟化技术,无需桥接,直接使用物理接口, 性能极好)


实验环境:两台虚拟机

1.清理掉之前的容器,删除自定义网络
docker rm-f vm1理掉之前的容器
docker network prune删除自定义网络

在这里插入图片描述


2.给server1和server2各添加一块虚拟网卡
ip link setup ens38激活网卡
ip link set ens38 promisc on 都打开网卡的混杂模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


3.创建macvlan网络模型
在server1
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens38 macvlan1 -oparent一定要加,因为 macvlan模型不走桥接,直接走物理接口,所以需要指定
docker network ls
docker run -it --name vm1 --network macvlan1 --ip 172.20.0.12 ubuntu 运行容器,macvlan模型这里必须手动指定ip地址,如果不指定会自动分配,单调 递增,可能会冲突

在server2
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens38 macvlan1
docker run -it --name vm1 --network macvlan1 --ip 172.20.0.11 ubuntu
ping 172.20.0.11 在server1上ping server2的容器也通
brctl show 容器接口直接与主机网卡相连,无需NAT或端口映射

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


4.可以使用vlan子接口实现多macvlan网络
vlan可以将物理二层网络划分为4094个逻辑 网络,彼此隔离,取值为1~4094

在server1
docker network create -d macvlan --subnet 172.21.0.0/24 --gateway 172.21.0.1 -o parent=ens38.1 macvlan2 创建逻辑网络ens38.1
docker network ls 查看成功创建
ip addr 也可以看到子接口
docker run -it --name vm2 --network macvlan2 --ip 172.21.0.11 ubuntu 看到ip为172.21.0.11 ,ping 172.20.0.11不通

在server2
docker network create -d macvlan --subnet 172.21.0.0/24 --gateway 172.21.0.1 -o parent=ens38.1 macvlan2 创建逻辑网络ens38.1
docker network ls 查看成功创建
docker run -it --name vm2 --network macvlan2 --ip 172.21.0.12 ubuntu 两个容器互相ping对方ip通


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:macvlan网络在二层是隔离的,所以不同macvlan容器不能通信,可以在三层通过网关连接(加路由),docker本身不做任何限制,像传统vlan那样管理即可。网络选型时如果对网络比较熟悉,选macvlan较好,因为只需要把网络设备调整好,docker方面基本不用做什么调整。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值