Docker原生网络
docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分。
docker安装后会自动创建3种网络:bridge、host、none
可以使用以下命令查看:
然后我们运行一个容器‘docker run -d --name nginx nginx
上述是通过网桥连接
相当于一个网络段,vethed8ad84桥接到我们的docker0上
我们在宿主机上ping我们的容器
如果我们再打开一个容器
他会在出来一个网络对
docker安装时会创建一个名为docker0的Linux bridge,新建的容器会自动桥接到这个接口。
bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的。
容器通过宿主机的NAT规则后可以访问外网。
linux内部打开了路由功能,允许docker0网卡和eth0网卡进行内部通信
[root@server1~]# sysctl-a |grep ip_forward
net.ipv4.ip_forward=1
首先我们删除原先所有的容器
然后我们运行一个nginx容器,并且对容器的network做说明让他使用host即和宿主机公用一个网络(但是要保证宿主机中的80端口不被占用)
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。
none模式是指禁用网络功能,只有lo接口,在容器创建时使用-network=none指定。
Docker自定义网络
·自定义网络模式,docker提供了三种自定义网络驱动:
·bridge
·overlay
·macvlan
bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,overlay和macvlan是用于创建跨主机网络。
·建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动
DNS解析容器名称到IP地址。
自定义的bridge比原生网络的bridge就多可一个解析其他的都是一样的
进入不同的网络效果是不一样的
[rootaserver1 ~]# docker run -it --name demo busybox
这样ping我们的demo是ping不通 的
[rootaserver1 ~]# docker run -it --name demo --network mynet1busybox
这样就可以
同时
docker run -it --name test --network mynet2 busybox
test和test2在同一个网段就可以ping通但是ping demo就不可以因为demo在mynet1网段
自定义网络存在DNS,他是动态的,当我们创建一个容器是他会自动给我分配地址,如果我们退出容器这个地址会被释放,当我们再次创建新的容器的时候他会将原先释放的地址给我们的新的容器。
我 们可以通过docker network rm来删除我们的网络
我们可以通过一些参数--subnet自己定义我们的网络ip
也可以通过--ip手工指定ip地址(只有使用了--subnet和--getway的网络才可以手工指定ip)使用--ip参数可以指定容器ip地址,但必须是在自定义网桥上,默认的bridge模式不支持,同一网桥上的容器是可以互通的。
桥接到不同网桥上的容器,彼此是不通信的。
docdker在设计上就是要隔离不同network的。
不同网络容器之间的互通(可以将其中一个设置双网卡)
我们先创建一个mynet1指定他的ip
然后我们再创建一个mynet2然后指定ip
docker network creat mynet2
如果我们手工指定ip 的话就会报错
Docker容器通信
容器之间除了使用ip通信外,还可以使用容器名称通信。
·docker 1.10开始,内嵌了一个DNS server。
·dns解析功能必须在自定义网络中使用。
·启动容器时使用--name参数指定容器名称。
Joined容器一种较为特别的网络模式。
在容器创建时使用--network=container:vm1指定。(vm1指定的是运行的容器名)
处于这个模式下的Docker容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信。
-link 可以用来链接2个容器。
--link的格式:
·--link <name or id>:alias
·name和id是源容器的name和id,alias是源容器在link下的别名。
然后我们停掉vm1,然后再创建一个vm3,然后想让vm3把vm1的地址占用了,然后我们再启用vm1,这个时候vm1的ip地址就会变
这就实现了--link的自动更新,但是变量不会同步
使用默认网络,因为没有DNS服务
可以通过docker container查看内部指令
容器如何访问外网是通过iptables的SNAT实现的(如何除去)
外网如何访问容器:(如何进来)
·端口映射
·-p选项指定映射端口
我们先运行一个容器
然后外部访问宿主机上访问
也可以自己访问curl 172.17.0.1
iptables -t nat -NL(利用防火墙的DNAT策略)
外网访问容器用到了docker-proxy和iptables DNAT
·宿主机访问本机容器使用的是iptables DNAT
·外部主机访问容器或容器之间的访问是docker-proxy实现
跨主机容器网络
我们再开一台虚拟机server2
跨主机网络解决方案
·docker原生的overlay和macvlan
·第三方的flannel、weave、calico
众多网络方案是如何与docker集成在一起的
·libnetwork docker容器网络库
·CNM(Container Network Model)这个模型对容器网络进行了抽象
CNM分三类组件
·Sandbox:容器网络栈,包含容器接口、dns、路由表。
(namespace)
·Endpoint:作用是将sandbox接入network(veth pair)·Network:包含一组endpoint,同一network的endpoint可以通信
·macvlan网络方案实现
·Linux kernel提供的一种网卡虚拟化技术。
·无需Linux bridge,直接使用物理接口,性能极好。·在两台docker主机上各添加一块网卡,打开网卡混杂模式:
首先给两个虚拟机各都再添加一个网卡
然后我们先把多余的容器都删除了
然后编辑网卡
B00TPROTO=none
DEVICE=eth1
ONB00T=yes
不给他ip地址并且使之开机激活 ifup eth1
两台主机都要做,然后打开混杂模式
ip link set ethl promisc on
然后在两台docker主机上创建macvlan
然后我们再serer2上也要创建网络,但是必须和server1上的网络处于同网段
macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id
取值为1~4094。
macvlan网络间的隔离和连通
·macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。
·可以在三层上通过网关将macvlan网络连通起来。
·docker本身不做任何限制,像传统vlan网络那样管理即可。
本章节讲解了docker各种网络模型的配置与实现,并从ip管理、
隔离、性能等方面做了对比,希望对大家在实际生产环境中网络选型有所帮助。
docker network子命令
·connect连接容器到指定网络
·create创建网络
·disconhect 断开容器与指定网络的连接
·inspect显示指定网络的详细信息
·ls显示所有网络
·rm删除网络