Docker网络详解 | 青训营笔记

288 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

网关(Gateway): 某个IP的电脑访问网络时候通过的地方,网关通过读取数据包的目的地址并在网络间转发数据包,网关是在不同网络之间的“翻译者”,帮助数据在不同网络之间传输。

网段(Network segment): 就是指一段连续的IP地址范围

子网掩码(subnet mask): 可以指定IP地址所属的子网段,和网段是一个概率。

1. Docker的三种网络机制

#查看容器网络
docker network ls

#容器建立时产生的桥接口
ip addr show doker0

##安装桥接管理工具
yum install -y bridge-utils-1.5-9.el7.x86_64
 
##桥接命令查看当前桥接接口
brctl show
sysctl -a | grep ip_forward

#指定容器的网络模式
docker run -it --rm --name deamon --network=host busybox

1.1 bridge

该模式下docker中的容器不会产生一个公有IP,只有宿主机可以直接访问容器,此时容器对外部主机是不可见的。但容器可以通过宿主机的NAT规则访问外网。创建网络默认都是bridge。

1.2 host

模式下可以让容器共享宿主机的网络,好处在于可以直接与外部主机进行通信,但此时容器也缺乏隔离性。同时在使用时,对于同一台宿主机而言,相同容器的配置(端口,ip等)会产生冲突。最具代表性的应用就是nginx。

1.3 none

禁用容器的IP地址,此时容器有很好的隔离性,一般用于产生一些特殊的认证等。

作用:密码工具,高安全性的情况

2. 自定义网络

首先先来了解下docker中的IP地址分配规则:docker中分配IP地址是根据一开始创建的docker桥接网卡有关系的,在创建时会产生一个地址段,当新的容器启动时,会根据以有的地址进行自增分配(增量为1),当某一容器关闭时,会自动回收,等待下一次的分配。

三种驱动: Bridge(自带dns解析功能)、overlay(用于跨主机网络,集群访问,应用层通信)、macvlan(用于跨主机网络,集群访问,物理层通信)

2.1 创建自定义网络

#创建自定义网络
docker network create -d bridge mynet1    #-d 指定模式(默认桥接)
 
#查看自定义网络信息
docker inspect mynet1
 
#查看网络
docker network ls
 
#网络删除
docker network rm mynet1
 
#使用自定义网路(打入后台:ctrl+p+q)
docker run -it --rm --name vm1 --network=mynet1 busybox

2.2、自定义网段、网关

【注】在指定IP时,只能使用自定义的网络进行指定。

  1. 创建mynet2,指定网段172.30.0.0/24,网关172.30.0.1。
  2. 使用自定义的网络来启动容器
  3. 指定固定IP来启动容器
#创建自指定网断和网关
docker network create -d bridge --subnet 172.30.0.0/24 --gateway 172.30.0.1 mynet2
 
#查看当前网络
docker network ls
 
#使用自定义网络启动容器
docker run --rm -it --name vm2 --network mynet2 busybox
 
#指定固定IP进行网络容器开启
docker run --rm -it --name vm3 --network mynet2 --ip 172.30.0.30 busybox

3. 容器之间的网络通信

容器网络通信的基础使用的是Linux的网络命名空间

3.1 Linux网络命名空间通信实验

ip netns(network name space)是Linux中用于管理网络命名空间的命令

#创建命名空间: 
ip netns add namespace1
#查看命名空间列表
ip netns list
#进入命名空间
ip netns exec namespace1 bash
#删除命名空间
ip netns delete namespace1
  1. 创建两个网络命名空间

  1. 查看

在"test1"命名空间内启用本地回环接口(lo),使得在该命名空间内可以通过回环接口进行网络通信

本地回环接口(lo) 是一个虚拟的网络接口,启用本地回环接口可以使得应用程序能够在本机上的网络环境中进行通信,而不需要通过网络。因此,本地回环接口通常被用于本地调试和测试

ip netns exec test1 ip link set dev lo up

  1. 创建一对的Veth分别放在test1和test2就可以连接

  1. 创建link: ip link add veth-test1 type veth peer name veth-test2

  1. 分别将veth-test1和veth-test2发送到不同的网络命名空间

  1. 分别给veth-test1veth-test2配置IP地址

并且:

  1. 测试

3.2 原理

不同的container通过不同的veth对连接在docker0上

下图是Linux主机的网卡。两个veth都是和不同的container配对,都是docker0的接口。

模型图

每个容器通过Docker0来进行NAT(网络地址转换)操作,将数据包的ip地址转换为可以联网的ip地址来访问外网。

3.3 Container之间的link

问题: 一开始创建两个Container是不是知道各自的IP地址的,那怎么通信?

容器会创建一个DNS记录。然后通过test1这个名称就可以访问。但是是单向的。

如果用户自建一个bridge网络,容器连接这个网络,都是默认互相link的。

docker network create -d bridge my-bridge

通过--network来指定连接的bridge