目录
一、docker原生网络
1、bridge网络
?2、host 模型
? 3、none网络
?二、docker自定义网络
1、bridge网络
?2、 创建自定义网桥
?三、docker容器间的通信
1、容器通信
?container模式?
link模式
跨主机通信
四、跨主机容器网络?
1、macvlan网络方案实现
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
一、docker原生网络
1、bridge网络
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 ##查看容器的信息
看到容器的网关为172.17.0.1,
#可以看到容器已经被分到一个ip地址【docker0网络端默认地址是172.17】
##注意ip分配是单调递增的
iptables -t nat -nL ?#有一个伪装
【容器通过桥接到达宿主机,宿主机通过l路由功能到达eth0出去,出去做了伪装】
172.17 为所有容器的地址,其他容器地址是以单调递增的方式动态分配的,谁启谁用
2、host 模型
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。
docker run -d --name demo2 --network host nginx ##-d 打入后台 docker ps brctl show?
docker inspect demo2
没有网关和 ip地址
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 ##没有新建网络
可以看到跟宿主机的ip一样
在docker2上直接访问dokcer1
brctl show netstat -antlp systemctl status nginx docker rm -f demo
容器开启占用的80端口
本机没有开nginx?
停掉之后外部不能访问
3、none网络
?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自定义网络
自定义网络模式,docker提供了三种自定义网络驱动: bridge overlay macvlan
bridge驱动类似默认的bridge网络模式,但增加了一些新的功能, overlay和macvlan是用于创建跨主机网络
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址
Docker提供了创建这些网络的默认网络驱动程序,你可以创建一个新的Bridge网络,Overlay或Macvlan网络
1、bridge网络
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?
demo1分配到的ip 是172.17.0.2
两个容器同属于一个网桥,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 动态分配单调递增
重新ping demo1,其ip为172.24.0.4
重新ping demo2,其ip为172.24.0.2
2、 创建自定义网桥
?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
不同容器 桥接不同网络
mynet1和mynet2默认情况下不通,防火墙有控制
不同网段的容器不能互通,要做三层路由
?注意不同的子网之前网络不通,是docker网络隔离作用
?docker ps docker network connect mynet1 75e8f0568e7e? ##把busybox接入到mynet1中
可以看到有两个网卡
--/ # ping demo1
--/ # ping demo2
*两个都能连通
三、docker容器间的通信
容器之间除了使用ip通信外,还可以使用容器名称通信
- docker 1.10开始,内切了一个DNS server
- dns解析功能必须再自定义网络中使用
- 启动容器时使用–name参数指定容器名称。
1、容器通信
【推荐使用自定义网络,因为有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 ps
brctl show docker network ls docker inspect demo
container模式?
在容器创建时使用--network=container:vm1指定。(vm1指定的是运行的容器名)
处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信
?可以看出使用这种模式后网络与demo完全相同。
docker run --rm -it --network container:demo busybox ##busybox和demo使用一个网络栈
link模式
--link 可以用来连接两个容器,通过/etc/hosts文件来做解析
--link 的格式:
--link <name or id>: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
外网可以访问宿主机
本地容器通信使用的是桥接,不同路由走不同接口
?
四、跨主机容器网络?
1、macvlan网络方案实现
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 ##打开混杂模式
同理docker2也打开混杂模式
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指定父级即物理接口为eth0
docker 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 mynet1
docker 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
在docker1主机中添加一块网卡
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网络那样管理即可。
?
?
|