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
原生网络
- [[email protected] ~]# docker pull busybox
- // 下载一个 busybox
- [[email protected] ~]# docker network ls
- // 查看原生网络
1.None: 什么都没有的网络
- [[email protected] ~]# docker run -itd --name none --network none busybox:latest
- // 根据 busybox 创建一个容器, 网卡为 none
- [[email protected] ~]# docker exec -it none /bin/sh
- // 进入刚刚创建的容器
- / # ip a
- // 查看一下 IP
用到 None 网络的容器, 会发现它只有一个 Loop back 回环的地址, 没有 Mac 地址, IP 等信息, 意味着他不能跟外界通信, 是被隔离起来的网络. 需要我们自己为 Docker 容器添加网卡, 配置 IP 等. 这种模式如果不进行特定的配置是无法正常使用的, 但它也给了用户最大的自由度来自定义容器的网络环境.
使用场景:
隔离意味着安全, 所以此网络可以运行一些关于安全方面的验证码, 效验码等服务.
2.Host 网络: 基于宿主机的网络
- [[email protected] ~]# docker run -itd --name host --network host busybox:latest
- // 根据 busybox 创建一个容器, 网卡为 host
- [[email protected] ~]# docker exec -it host /bin/sh
- // 进入刚刚创建的容器
- / # ip a
- // 查看一下 IP
用到 Host 网络的容器, 它的网络跟宿主机的网络一模一样, 那是因为, 在创建这个容器之初, 并没有对它的 Net 网络栈进行隔离, 而是直接使用的宿主机的网络栈.
使用场景:
网络配置与 dockerHost 完全相同, 性能较好, 但不便之处是灵活性不高, 此模式没有网络隔离性, 容器与宿主机出现端口冲突问题.
3.Bridge: 桥接网络
- [[email protected] ~]# brctl show
- // 查看一下桥接网络
docker0: 在我们安装 docker 这个服务的时候, 默认就会生产 - - 张 docker0 的网卡, 一般默认 IP 为 172.17.0.1/16.
- [[email protected] ~]# docker run -itd --name test1 busybox:latest
- // 根据 busybox 创建一个容器
- [[email protected] ~]# docker exec -it test1 /bin/sh
- // 进入刚刚创建的容器
- / # ip a
- // 查看一下 IP
- / # exit
- // 退出容器
- [[email protected] ~]# ip a
- // 查看一下 IP,* 会发现多出一张网卡 (docker0 的网卡 @容器中的 if6)*
- [[email protected] ~]# brctl show
- // 查看一下桥接网络,* 这里也多了一个网卡 *
容器默认使用的网络是 docker0 网络, docker0 此时相当于一个路由器, 基于此网络的容器, 网段都是和 docker0 一致的.
自定义网络
自带了 - 个 ContainerDNSserver 功能 (域名解析)
- 1.bridge
- [[email protected] ~]# docker network create -d bridge my_net
- // 创建一个名称为 my_net 的 bridge 网络
-d: 设置网卡模式
- [[email protected] ~]# ip a
- // 查看 ip, 会发现多了一个网卡
- [[email protected] ~]# brctl show
- // 查看一下桥接网络, 这里也多了一个网卡
- [[email protected] ~]# docker run -itd --name test3 --network my_net busybox:latest
- // 开启一台容器, 网卡为刚刚创建的 my_net
- [[email protected] ~]# docker exec -it test3 /bin/sh
- // 进入刚刚创建的容器
- / # ip a
- // 查看一下 IP
- [[email protected] ~]# ip a
- // 查看 ip, 会发现多了一个网卡
- [[email protected] ~]# brctl show
- // 查看一下桥接网络, 这里也多了一个网卡
- [[email protected] ~]# docker run -itd --name test4 --network my_net busybox:latest
- // 开启一台容器, 网卡为刚刚创建的 my_net
- [[email protected] ~]# docker exec -it test3 /bin/sh
- / # ping test4
- //ping 刚刚创建的容器名称
自定义网络优点, 它可以通过容器的名称通信.
2. 指定容器 IP
- [[email protected] ~]# docker run -itd --name t1 --network my_net --ip 172.18.0.8 busybox:latest
- // 开启一个容器并指定 IP
- [[email protected] ~]# docker network create -d bridge --subnet 172.30.16.0/24 --gateway 172.30.16.1 my_net3
- // 创建一个自定义网络, 并且指定网关和网段
- [[email protected] ~]# docker network ls
- // 查看网络
[[email protected] ~]# ip a
如果想要给容器指定 IP 地址, 那么自定义网络的时候, 必须指定网关 gate 和 subnet 网段选项.
开启两个容器测试一下
- [[email protected] ~]# docker run -itd --name test5 --network my_net3 --ip 172.30.16.5 busybox:latest
- // 开启一个容器 test5 并指定 IP
- [[email protected] ~]# docker exec -it test5 /bin/sh
- / # ip a
- [[email protected] ~]# docker run -itd --name test6 --network my_net3 --ip 172.30.16.6 busybox:latest
- // 开启一个容器 test6 并指定 IP
- [[email protected] ~]# docker exec -it test6 /bin/sh
- / # ip a
/ # ping test5
3. 各网卡互通
- [[email protected] ~]# iptables-save
- // 查看网卡信息的配置规则 (可以看到防火墙的规则当另一个网卡信息来到自己这里时直接丢弃)
- [[email protected] ~]# docker network connect my_net3 test4
- //my_net3 网卡桥接 test4 (网卡名称 容器名称)
- [[email protected] ~]# docker exec -it test5 /bin/sh
- / # ping test4
剩下的以此类推, 然后就可以各个网卡互通了
来源: http://www.bubuko.com/infodetail-3330345.html