Docker 网络基础
Docker启动时, 会自动在主机上创建一个docker0虚拟网桥, 实际上是Linux的一个bridge,可以理解为一个软件交换机, 它会而挂载到它的网口之间进行转发 当创建一个Docker容器的时候, 同理会创建一对veth pair接口(当数据包发送到一个接口时, 另外一个接口也可以收到相同的数据包), 这对接口一端在容器内, 即eth0;另一端在本地并被挂载到docker0网桥, 名称以veth开头。
Docker容器的DNS和主机名
实际上容器中/etc目录下有3个文件是容器启动后被虚拟文件覆盖掉的, 分别是/etc/hostname、 /etc/hosts、 /etc/resolve.conf,通过在容器中运行mount命令可以查看。
Docker容器的5种网络模式
在使用docker run创建docker容器时, 可以用--net选项指定容器的网络模式, Docker有以下5种网络模式:
1. bridge模式
使用docker run --net=bridge指定, bridge模式是Docker默认的网络设置, 此模式会为每一个容器分配Network Namespace、 设置IP等, 并将一个主机上的Docker容器连接到一个虚拟网桥上。 此模式与外界通信使用NAT协议, 增加了通讯的复杂性, 在复杂场景下使用会有诸多
限制。
route -n 查看 IP routing tables;
iptables -t nat -L -n 查看iptables rules.
2. host模式
使用docker run --net=host指定, 这种模式Docker Server将不为Docker容器创建网络协议栈, 即不会创建独立的network namespace,Docker容器中的进程处于宿主机的网络环境中,相当于Docker容器的宿主机共用同一个network namespace,使用宿主机的网卡、 IP、 端口等信息。 此模式没有网络隔离性, 同时会引起网络资源的竞争与冲突。
3. container模式
使用docker run --net=container:othercontainer_name指定, 这种模式与host模式相似, 指定新创建的容器和已经存在的某个容器共享同一个network namespace, 以下两种模式都共享network namespace,区别就在于host模与宿主机共享, 而container模式与某个存在的容器共享。 在container模式下, 两个容器的进程可以通过lo回环网络设备通讯, 增加了容器间通讯的便利性和效率。 container模式的应用场景就在于可以将一个应用的多个组件放在不同的容器趾, 这些 容器配成container模式的网络, 这样它们可以作为一个整体对外提供服务。 同
时, 这种模式也降低了容器间的隔离性。
docker run -it --name helloworld busybox sh docker run -it --name helloword-con --
net=container:helloword busybox sh
4. none模式
使用docker run --net=none指定, 在这种模式下, Docker容器拥有自己的Network
Namespace, 但是, 并不为Docker容器进行任何网络配置。 也就是说, 这个Docker容器没有网卡、 IP、 路由等信息。 需要我们自己为Docker容器添加网卡、 配置IP等。 这种模式如果不进行特定的配置是无法正常使用的, 但它也给了用户最大的自由度来自定义容器的网络环境。
5. overlay模式
overlay网络特点:
跨主机通讯
无需做端口映射
无需担心IP冲突
服务发现与k/v存储: etcd, consul
原生网络
[root@localhost ~]# docker pull busybox
//下载一个busybox
[root@localhost ~]# docker network ls
//查看原生网络
1.None:什么都没有的网络
[root@localhost ~]# docker run -itd --name none --network none busybox:latest
//根据busybox创建一个容器,网卡为none
[root@localhost ~]# docker exec -it none /bin/sh
//进入刚刚创建的容器
/ # ip a
//查看一下IP
用到None网络的容器,会发现它只有一个Loop back回环的地址,没有Mac地址,IP等信息,意味着他不能跟外界通信,是被隔离起来的网络。需要我们自己为Docker容器添加网卡、 配置IP等。 这种模式如果不进行特定的配置是无法正常使用的, 但它也给了用户最大的自由度来自定义容器的网络环境。
使用场景:
隔离意味着安全,所以此网络可以运行一些关于安全方面的验证码、效验码等服务。
2.Host网络:基于宿主机的网络
[root@localhost ~]# docker run -itd --name host --network host busybox:latest
//根据busybox创建一个容器,网卡为host
[root@localhost ~]# docker exec -it host /bin/sh
//进入刚刚创建的容器
/ # ip a
//查看一下IP
用到Host网络的容器,它的网络跟宿主机的网络一模一样,那是因为,在创建这个容器之初、并没有对它的Net网络栈进行隔离,而是直接使用的宿主机的网络栈。
使用场景:
网络配置与dockerHost完全相同,性能较好,但不便之处是灵活性不高,此模式没有网络隔离性,容器与宿主机出现端口冲突问题。
3.Bridge:桥接网络
[root@localhost ~]# brctl show
//查看一下桥接网络
docker0:在我们安装docker这个服务的时候,默认就会生产- -张docker0的网卡,一般默认IP为172.17.0.1/16.
[root@localhost ~]# docker run -itd --name test1 busybox:latest
//根据busybox创建一个容器
[root@localhost ~]# docker exec -it test1 /bin/sh
//进入刚刚创建的容器
/ # ip a
//查看一下IP
/ # exit
//退出容器
[root@localhost ~]# ip a
//查看一下IP,*会发现多出一张网卡(docker0的网卡@容器中的if6)*
[root@localhost ~]# brctl show
//查看一下桥接网络,*这里也多了一个网卡*
容器默认使用的网络是docker0网络,docker0此时相当于一个路由器,基于此网络的容器,网段都是和docker0一致的。
自定义网络
自带了-个ContainerDNSserver功能(域名解析)
1.bridge
[root@localhost ~]# docker network create -d bridge my_net
//创建一个名称为my_net的bridge网络
-d:设置网卡模式
[root@localhost ~]# ip a
//查看ip,会发现多了一个网卡
[root@localhost ~]# brctl show
//查看一下桥接网络,这里也多了一个网卡
[root@localhost ~]# docker run -itd --name test3 --network my_net busybox:latest
//开启一台容器,网卡为刚刚创建的my_net
[root@localhost ~]# docker exec -it test3 /bin/sh
//进入刚刚创建的容器
/ # ip a
//查看一下IP
[root@localhost ~]# ip a
//查看ip,会发现多了一个网卡
[root@localhost ~]# brctl show
//查看一下桥接网络,这里也多了一个网卡
[root@localhost ~]# docker run -itd --name test4 --network my_net busybox:latest
//开启一台容器,网卡为刚刚创建的my_net
[root@localhost ~]# docker exec -it test3 /bin/sh
/ # ping test4
//ping 刚刚创建的容器名称
2.指定容器IP
[root@localhost ~]# docker run -itd --name t1 --network my_net --ip 172.18.0.8 busybox:latest
//开启一个容器并指定IP
[root@localhost ~]# docker network create -d bridge --subnet 172.30.16.0/24 --gateway 172.30.16.1 my_net3
//创建一个自定义网络,并且指定网关和网段
[root@localhost ~]# docker network ls
//查看网络
[root@localhost ~]# ip a
如果想要给容器指定IP地址,那么自定义网络的时候,必须指定网关gate和subnet网段选项。
开启两个容器测试一下
[root@localhost ~]# docker run -itd --name test5 --network my_net3 --ip 172.30.16.5 busybox:latest
//开启一个容器test5并指定IP
[root@localhost ~]# docker exec -it test5 /bin/sh
/ # ip a
[root@localhost ~]# docker run -itd --name test6 --network my_net3 --ip 172.30.16.6 busybox:latest
//开启一个容器test6并指定IP
[root@localhost ~]# docker exec -it test6 /bin/sh
/ # ip a
3.各网卡互通
[root@localhost ~]# iptables-save
//查看网卡信息的配置规则(可以看到防火墙的规则当另一个网卡信息来到自己这里时直接丢弃)
[root@localhost ~]# docker network connect my_net3 test4
//my_net3网卡桥接test4 (网卡名称 容器名称)
[root@localhost ~]# docker exec -it test5 /bin/sh
/ # ping test4