桥接口
Docker容器通信
容器之间除了使用ip通信外,还可以使用容器名称通信。
docker 1.10开始,内嵌了一个DNS server.
dns解析功能必须在自定义网络中使用。
启动容器时使用 --name 参数指定容器名称。
默认的桥接中不带解析。
容器之间的通信分为单节点上的容器互通和跨节点上的容器互通。
本地之间容器的通过桥接。
不同段的容器在互通的时候是直接走的桥接。数据包从容器内出来以后到达网关docker0,如果发现本机的流量都是同网段的话,还是走的是docker0。
不同网段的容器是隔离的,通过给容器增加一块网卡,进入到另外一个网络当中,使容器间互通。
容器间除了使用ip通信外,还可以使用容器名称通信。ip因为是动态的,所以不靠谱,一般使用docker 内嵌的DNS server来做域名解析。名称在启动docker时,添加–name 参数指定容器名称,施加就可以了,就会创建相应的解析记录。
随着容器的动态ip变更,就会变更dns中的解析记录。
server1
docker run -d --name vm1 --network my_net1 nginx #-d 打入后台
docker run -it --name vm2 --network my_net1 ubuntu
ping vm1
jined容器是一种较为特别的网络模式
在容器创建时使用–network=container:vm1指定。(vm1指定的是运行的容器名)
docker run -it --name vm1 --network my_net1 ubuntu
ip addr
docker ps -a
docker container prune 回收容器。
docker run -d --name nginx # -d打入后台
docker ps #显示当前正在运行的容器
brctl show #查看网桥 br0网桥不带解析
如果希望有解析记录的话,用自定义网络,就是自己创建的。默认的br虽然有桥接驱动,但是不带解析。默认的桥接不带解析。
docker network ls #
docker inspect demo #用于获取容器或镜像的元数据 可以查看ip地址
docker run --rm -it --network container:demo busybox
ip addr
busybox容器和之前打开的demo容器使用的是相同的ip,这两个容器监听的端口不能是重复的。
--link 可以用来连接2个容器
--link 的格式:
--link <name or id>:alias 容器加别名
name和id是源容器的name和id,alias是源容器在Link下的别名。
这个解析不是通过DNS,而是通过host文件。
server1
cat /etc/hosts
docker run --rm -it --link demo:webserver busybox
cat /etc/hosts
ping demo
env 变量
当demo的ip发生变化时,解析也会变,但变量不会变。
重新开一个终端
docker stop demo #停掉之前的demo
docker run -d --name demo2 nginx
docker inspect demo2 #发现这个demo2会把之前的ip地址给占了。
docker start demo
docker inspect demo #又重新分配了一个地址。
接着上一个代码
cat /etc/hosts
env
容器能够出去,是完全依赖宿主机上面的nat,就是snat,创建多少虚拟网络,就会定制多少条策略。
进来是DNAT
server1
ps ax
netstat -antlp
docker ps
docker rm -f demo
docker rm -f demo2
docker ps -a
docker run -d --name demo -p 80:80 nginx #创建一个demo,做一个端口映射,使用-p
iptables -t nat -nL
这里可以看到有个DNAT的策略,当访问本机的80,就会重定向到容器的80.从外部网络,访问本机器的80时,
就会重定向到02的80上。这就是端口重定向机制。这是通过一种双冗余机制,只要一种可用的,网络都是畅通的。
netstat -antlp
一旦开启端口映射,就会生成一个docker-proxy
docker ps
演示双冗余机制。
NAT转换还是依赖于iptables
server1
iptables -t nat -D DOCKER 4 #清除docker这条链
iptable -t nat -nL
其他的主机上
curl 172.25.0.1
netstat -antlp #查看docker-proxy的进行PID
kill -9 5276#
其他的主机上
curl 172.25.0.1 #这时就有问题了
curl 172.25.0.2 #这个可以
恢复之前的
docker stop demo
docker start demo
iptables -t nat -nL
netstat -antlp
但如果先将docker-proxy干掉,则还是可以通的。
数据包出去的规则
进来的规则,是一种双冗余机制。
外网访问容器用到了docker-proxy和iptables DNAT
宿主机访问本机容器使用的是iptables DNAT
外部主机访问容器或容器之间的访问是docker-proxy实现
本地容器之间是通过桥接转发的。
brctl show
route -n
server1
docker ps
docker inspect demo
docker rm -f demo
server2
docker ps
ip addr ip还是从02开始
docker run -d --name demo nginx
docker inspect demo
docker rm -f demo
B、跨主机容器网络
选择大部分都会的技术栈
跨主机网络解决方案
docker原生的overlay和macvlan
第三方的flannel\weave\calico
众多网络方案是如何与docker集成在一起?
libnetwork docker容器网络库
CNM(container network model)这个模型对容器网络进行抽象
CNM分三类组件(开发人员可以多看这个,运维人员现有的可以使用)
sandbox:容器网络栈、包含容器接口、dns、路由表
endpoint:作用是将sandbox接入network(veth pair)
network:包含一组endpoint,同一network的endpoint可以通信。
macvlan网络方案实现
linux kernel提供的一种网卡虚拟化技术
无需 linux bridge,直接使用物理接口,性能极好。
在两台docker主机上各添加一块网卡,打开网卡混杂模式。
server1
ip addr
docker network ls
docker network prune#把不用的网络删除
docker network ls
server2
ip addr
docker network ls
docker network prune#把不用的网络删除
docker network ls
server1和server2上都进行以下操作
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
#-d 指定驱动类型;--subnet子网; -o 指定物理接口;名字
docker network ls
docker network inspect mynet1
docker run -it --name demo1 --network mynet1 --ip 172.25.0.10 busybox #macvlan的ip是自己分配的,和容器没有关系
ip addr
docker ps
ip addr
brctl show
docker attach demo1
解决两个不同容器之间的互通
server2
docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=eth0 mynet1 指定父类
docker inspect mynet1
docker pull busybox
docker run --rm -it --network mynet1 --ip 172.20.0.11 busybox
ip addr
ping 172.20.0.10
server1
docker attach demo1
ping 172.20.0.11
macvlan网络结构分析
没有新建linux bridge
容器的接口直接与主机网卡连接,无需NAT或端口映射。
macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络。
vlan可以将物理二层网络划分为4096个逻辑网络,彼此隔离。
需要创建更多的网络,可以添加网卡,
演示
server1已经添加一块网卡
docker ps
docker network ls
ip addr
ip link set up dev eth1 激活网卡设备
ip addr
ip link set eth1 promisc on
ip addr
docker network create -d macvlan --subnet 172.30.0.0/24 --gateway 172.30.0.1 -o parent=eth1 mynet2
docker network inspect mynet2
docker run --rm -it --network mynet2 busybox
ip addr
docker run --rm -it --network mynet2 --ip 172.30.0.100 busybox
ip addr
因为macvlan需要建立网卡,不合理。因为硬件层面是有限的。
server1
docker ps -a
docker network create -d macvlan --subnet 172.40.0.0/24 --gateway 172.40.0.1 -o parent=eth1.1 mynet3
docker network create -d macvlan --subnet 172.50.0.0/24 --gateway 172.50.0.1 -o parent=eth1.2 mynet4
docker network inspect ls
docker network inspect mynet3
docker network inspect mynet4
ip addr
通过子接口的方式来创建不一样的虚拟网络。
使用的方法,直接用管理员身份直接进行分配即可。
macvlan网络间的隔离和连通
macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。如果希望不同macvlan网络的容器可以通信,添加网卡。
可以在三层上通过网关将macvlan网络连通起来。
docker本身不做任何限制,像vlan网络那样管理即可。
docker network connect
overlay不需要关心那么多底层,需要更多的子网。