目录
一、docker原生网络
1、bridge网络
2、host 模型
3、none网络
二、docker自定义网络
1、bridge网络
2、 创建自定义网桥
三、docker容器间的通信
1、容器通信
container模式
link模式
跨主机通信
四、跨主机容器网络
1、macvlan网络方案实现
bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的。 容器通过宿主机的NAT规则后可以访问外网。
docker network ls
cd harbor/
ls
docker-compose down ##停止容器
docker network ls ##docker的原生网络有三个
docker安装后会自动创建3种网络:bridge、host、none
ip addr #docker安装后有一个docker0的桥接口
docker run -d --name demo nginx ##开启新容器
docker ps
yum install -y bridge-utils
brctl show ##可以看到容器网络桥接到宿主机docker0上
docker inspect demo ##查看容器的信息
#可以看到容器已经被分到一个ip地址【docker0网络端默认地址是172.17】
##注意ip分配是单调递增的
iptables -t nat -nL #有一个伪装
【容器通过桥接到达宿主机,宿主机通过l路由功能到达eth0出去,出去做了伪装】
172.17 为所有容器的地址,其他容器地址是以单调递增的方式动态分配的,谁启谁用
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。
docker run -d --name demo2 --network host nginx ##-d 打入后台
docker ps
brctl show
docker inspect demo2
docker exec -it demo2 bash ##进入demo2可以看到容器内
docker rm -f demo2
docker run -it --name demo2 --network host busybox ##运行busybox打开终端
docker ps -a
docker rm -f demo
docker rm -f demo2
docker run -d --name demo --network host nginx ##运行demo
ip addr ##没有新建网络
brctl show
netstat -antlp
systemctl status nginx
docker rm -f demo
容器开启占用的80端口
none模式是指禁用网络功能,只有lo接口,在容器创建时使用 --network=none指定
docker run --rm -it --network none busybox #可以看到只有lo接口
docker ps
docker run -d --name demo nginx
docker ps
docker inspect demo | grep Pid
cd /proc/1882/ #进入到进程里面
ls
cd ns
有6种命名空间独立存在 ,相对安全做了隔离,还有一些和宿主机共享的
自定义网络模式,docker提供了三种自定义网络驱动: bridge overlay macvlan
bridge驱动类似默认的bridge网络模式,但增加了一些新的功能, overlay和macvlan是用于创建跨主机网络
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址
Docker提供了创建这些网络的默认网络驱动程序,你可以创建一个新的Bridge网络,Overlay或Macvlan网络
docker network ls
docker rm -f demo
docker network create --help
docker network create mynet1 #创建网络mynet1
docker network ls ##属于桥接模式
docker run -d --name demo1 nginx
docker inspect demo1
docker run -it --rm busybox
两个容器同属于一个网桥,ping 不同demo1 ,可以ping通ip
docker rm -f demo1
docker run -d --name demo1 --network mynet1 nginx ##运行时指定网络可以做DNS解析
brctl show
docker network inspect mynet1 ##网络ip为172.24.0.2,网关为172.24.0.1
ip addr
docker run -it --rm --network mynet1 busybox ##与demo1接入同一个网络,同属于一个vlan
可以ping通域名
停掉demo1,其ip(172.24.0.2)资源自动释放,再开一个demo2 ip(172.24.0.2)会被分配,又重新启动demo1,其ip 动态分配单调递增
mynet1不能手动指定ip
docker network ls
docker ps
docker run -d --name demo3 --network mynet1 --ip 172.24.0.10 nginx #发现不能指定ip
docker ps -a
docker rm -f demo1
docker rm -f demo2
docker rm -f demo3
docker network rm mynet1
ip addr
docker network create --subnet 172.20.0.0/24 --gateway 172.20.0.1 mynet1 #创建网桥指定网段,不能和本机现有网段冲突
docker network inspect mynet1 ##查看mynet1详情
docker run -d --name demo1 --network mynet1 --ip 172.20.0.10 nginx ##指定ip运行容器
curl 172.20.0.10 可以访问到
docker network create --subnet 172.30.0.0/24 --gateway 172.30.0.1 mynet2
docker network ls
docker network inspect mynet2
docker run -d --name demo2 --network mynet2 --ip 172.30.0.10 nginx
brctl show
ip addr #可以看到创建的网桥
iptables -nL
iptables -t nat -nL
cd
docker run -it --rm --network mynet1 busybox
docker run -it --rm --network mynet2 busybox
不同容器 桥接不同网络
注意不同的子网之前网络不通,是docker网络隔离作用
docker ps
docker network connect mynet1 75e8f0568e7e ##把busybox接入到mynet1中
--/ # ping demo1
--/ # ping demo2
*两个都能连通
容器之间除了使用ip通信外,还可以使用容器名称通信
【推荐使用自定义网络,因为有dns】
docker ps -a
docker container prune ##删除所有已经停止的容器
docker ps -a
docker rm -f demo1
docker rm -f demo2
docker ps -a
docker run -d --name demo nginx ##开启nginx容器
docker psbrctl show
docker network ls
docker inspect demo
在容器创建时使用--network=container:vm1指定。(vm1指定的是运行的容器名)
处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信
可以看出使用这种模式后网络与demo完全相同。
docker run --rm -it --network container:demo busybox ##busybox和demo使用一个网络栈
--link
可以用来连接两个容器,通过/etc/hosts文件来做解析
--link
的格式:
--link:alias name和id是源容器的name和id,alias是源容器在link下的别名。
【两个容器之前使用共享的网络栈,通过localhost进行快速通信】
再开一个docker1窗口
docker stop demo ##停掉demo
docker run -d --name demo2 nginx ##运行demo2
docker inspect demo2 ##可以看到demo2获取原先demo的ip
docker start demo ##开启demo
docker inspect demo ##可以看到demo获取的ip是172.17.0.4
返回第一台docker1端口
--/ # env #可以看到变量没有变
--/ # cat /etc/hosts #但是host解析变了
容器访问外网【使用防火墙】
【宿主机访问本机使用的是iptables DNAT
外部主机访问容器或者容器之间的访问是docker-proxy】
iptables -t nat -nL
外网访问容器【定义端口影射】
docker ps
docker rm -f demo2
docker rm -f demo
以上两者都不能访问(没有做端口影射),监听的是本机内部的,
docker run -d --name demo -p 80:80 nginx ##指定端口映射80
iptables -t nat -nL ##可以看到防火墙的DNAT规则,当访问宿主机80时重定向到172.17.0.2的80
netstat -antlp ##可以看到ipv4和ipv6的80端口进程显示:docker-proxy。这是docker的双冗余机制
从外网可以访问宿主机
iptables -t nat -D DOCKER 4 ##删除DOCKER链的第四条
iptables -t nat -nL
curl 172.25.254.1 #可以访问到宿主机
删掉DNAT规则还可以访问到就是因为docker时双冗余机制
netstat -antlp
kill -9 4646 ##删除docker-proxy
netstat -antlp
但是在宿主机内部可以访问 ,因为属于同一vlan,内部数据包走的是网桥
docker stop demo
docker start demo ##重启之后可以恢复这种机制
iptables -t nat -nL ##可以看到DNAT规则重新创建成功
netstat -antlp #docker-proxy重新恢复
kill -9 4817 ##再次删除docker-proxy
Linux kernel提供的一种网卡虚拟化技术。
无需Linux bridge,直接使用物理接口,性能极好。
docker ps
docker inspect demo
在docker2上开一个容器与docker1上相同,因为属于两台主机,具有隔离性,所以分配到相同ip也没有影响
docker ps
docker run -d --name demo nginx
docker inspect demo
docker rm -f demo
docker network ls
docker network prune ##删除创建的网络
docker network ls
ip addr
ip link set eth0 promisc on ##打开混杂模式
docker rm -f demo
docker network ls
ip addr
ip link set eth0 promisc on
ip addr #可以看到已经开启
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=eth0 mynet1 #创建mynet1 -d 指定驱动为macvlan,指定子网和本地网络不冲突,-o指定父级即物理接口为eth0docker network ls
docker network inspect mynet1 #看到已经创建成功
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=eth0 mynet1 ##docker2上也创建网络
docker inspect mynet1docker images
docker pull busybox
docker images
docker ps -a
docker run --rm -it --network mynet1 --ip 172.20.0.11 busybox #可以ping 通docker1中的172.10.0.10
docker attach demo1 ##进入demo1 可以ping 通docker2中的172.20.0.11
ip addr #可以看到多了eth1但是处于down
ip link set up dev eth1 ##激活eth1
ip addr
ip link set eth1 promisc on ##打开eth1的混杂模式
ip addr
docker network create -d macvlan --subnet 172.30.0.0/24 --gateway 172.30.0.1 -o parent=eth1 mynet2 ##创建mynet2
docker network inspect mynet2
docker run --rm -it --network mynet2 busybox ##指定网络运行busybox可以看到会自动分配ip
docker run --rm -it --network mynet2 --ip 172.30.0.100 busybox ##也可以自己指定IP
docker network create -d macvlan --subnet 172.40.0.0/24 --gateway 172.40.0.1 -o parent=eth1.1 mynet3 ##创建mynet3 ,使用子网eth1.1
docker network create -d macvlan --subnet 172.50.0.0/24 --gateway 172.50.0.1 -o parent=eth1.2 mynet4 ##创建mynet4.使用子网eth1.2
docker network ls
docker network inspect mynet3
docker network inspect mynet4
macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
macvlan网络结构分析 :
没有新建linux bridge;容器的接口直接与主机网卡连接,无需NAT或端口映射。
macvlan网络间的隔离和连通 macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。
可以在三层上通过网关将macvlan网络连通起来。
docker本身不做任何限制,像传统vlan网络那样管理即可。