Docker 网络详解

简介: Docker 网络详解

前置网络知识

OSI七层网络模型

从下到上依次为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

交换机:处在第二次,也就是数据链路层。作用:通过一个或者多个设备将不同子网连接在一起,相互通信;

路由器:处在网络层,实现信息的传送(简单描述:首先通过IP的网络地址定位到某个网络,期间可能经过多个网络,到达最终的网络后,再通过IP + 子网掩码 得到主机地址,用主机地址和PC的MAC地址映射关系找到最终的机器,再通过port定位到那个程序,对应的程序就能收到数据啦~)。每个路由器都有一张路由表,根据这张表寻找最终地址或者下一个转发的地址。

交换机

交换机工作于OSI参考模型的第二层,即数据链路层。交换机内部的CPU会在每个端口成功连接时,通过将MAC地址和端口对应,形成一张MAC表。在今后的通讯中,发往该MAC地址的数据包将仅送往其对应的端口,而不是所有的端口。

每个物理网卡对应一个唯一的MAC的地址(物理地址),这个地址是网卡在出场的时候就固定了的,保证不会重复。

交换机在同一时刻可进行多个端口对之间的数据传输。每一端口都可视为独立的物理网段(注:非IP网段),连接在其上的网络设备独自享有全部的带宽,无须同其他设备竞争使用。当节点A向节点D发送数据时,节点B可同时向节点C发送数据,而且这两个传输都享有网络的全部带宽,都有着自己的虚拟连接。假使这里使用的是10Mbps的以太网交换机,那么该交换机这时的总流通量就等于2×10Mbps=20Mbps。

总之,交换机是一种基于MAC地址识别,能完成封装转发数据帧功能的网络设备。

NAT(Network Address Translation)

NAT是指网络地址转换,1994年提出的。

当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。这种通过使用少量的全球IP地址(公网IP地址)代表较多的私有IP地址的方式,将有助于减缓可用的IP地址空间的枯竭。

私有网络ip块

A 类:10.0.0.0~10.255.255.255
B 类:172.16.0.0~172.31.255.255
C 类:192.168.0.0~192.168.255.255

一、Docker网络命令

1.1 创建网络
docker network create net_name
1.2 删除网络
docker network rm net_name
1.3 查看网络列表
docker network ls
1.4 查看指定网络信息
docker network inspect net_name
1.5 连接一个容器到执行网络
docker network connect net_name container
1.6 将容器从指定网络断开
docker network disconnect

二、Docker网络连接

Docker默认提供了3种网络模式,生成容器时不指定网络模式下默认使用bridge桥接模式。

使用命令查看当前Docker所有的网络模式。

[root@VM-24-12-centos panda]# docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
1837a1f4b464   bridge       bridge    local
b0363838038c   host         host      local
02040f0017d5   none         null      local
[root@VM-24-12-centos panda]#

2.1 bridge桥接

Docker默认的网络模式就是桥接,如果在启动容器时不使用–network 显式指定网络类型就会使用桥接模式。桥接,也叫网桥,指的是把物理网卡(eth0)当作交换机来用。

当Docker进程启动的时候,会在宿主机上创建一个docker0的虚拟网桥。每个启动的容器都会连接到这个网桥上。具体流程如下:容器在启动的时候,会从docker0子网中分配一个IP给容器(注意:该IP和物理网卡eth0不在同一个网段),同时将docker0的IP设置为容器的网关。接着,Docker会为该容器创建一对虚拟网卡设备veth pair,一个连接宿主机的docker0网桥,另一个连接该容器(veth0xxx)。

docker run -dit --name mynginx nginx
docker inspect mynginx

可以看到容器的IP地址为:172.17.0.3,网关:172.17.0.1(docker0的IP地址)

Linux内核支持两种级别的设备模拟(纯软件):(1)链路层(二层)设备:每个网卡是成对出现的。一端在主机,一端在交换机上,linux原生支持模拟二层网桥设备交换机(工具bridge-utils);(2)网络层(三层)设备,OVS(Open VSwith),软件驱动的软硬件集中到一个软件上,统一调度。

安装 bridge-utils 工具
yum install -y bridge-utils

2.2 NAT 网络地址转换协议

如图,假设同一局域网中的两个容器helloA 和 helloB要通信:helloA的报文会先交给docker0网桥,宿主机判断报文的目标地址不是自己,通过查路由表发现是和机器115的helloB容器通信,就会通过eth0将报文发送到115机器,115再查找自己的路由表找到helloB容器。

但此时110机器是收不到115机器的回复的,为什么呢?因为helloA容器的报文的源IP是172.17.0.2,这个地址是私有的,115机器是看不到的;如果想收到115机器的回复,就需要把报文的源IP地址在出eth0物理网卡时,修改成192.168.10.110。这样115机器的回复报文会找到110机器,再通过查路由表就能知道是helloA容器了。

上面两个容器时彼此看不到对方的,helloA以为在和192.168.10.115通信,helloB以为在和192.168.10.110通信。这样效率不高,但是方便管理。如果不想和桥接一样暴露在外面,又不想藏在宿主机后面,怎么办呢?叠加网络应用而生。

2.3 host 模型

host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

2.4 none网络

none模式是指禁用网络功能,只有lo接口,在容器创建时使用 --network none指定

2.5 自定义网络类型

自定义网络模式,docker提供了三种自定义网络驱动: bridge overlay macvlan。建议使用自定义的网络来控制哪些容器可以相互通信。

在微服务部署的场景下,注册中心是使用服务名来唯一识别微服务的,而我们上线部署的时候微服务对应的IP地址可能会改动,所以我们需要使用容器名来配置容器间的网络连接。使用自定义网络创建容器后,相同网络下的容器,不管是通过容器IP还是容器名,都可以进行网络通信:

docker network --help
docker network create --help
2.5.1 创建网络并指定子网
docker network create --subnet=172.28.0.0/16 net_test_2

2.5.2 创建网络并指定子网、网关及ip范围
docker network create --subnet=172.38.0.0/16 --gateway=172.38.5.254 --ip-range=172.38.5.0/24 net_test_3

每创建一个网络就会在路由表中添加一条静态路由信息。

route -n 查看路由表

案例1

以nginx为例,我们启动三个容器,都接入 net_test_2 网络

docker run -d --network net_test_2 nginx
docker run -d --network net_test_2 nginx
docker run -d --network net_test_2 nginx
docker network inspect net_test_2 

可以看到,net_test_2 接了三个容器。

将 容器determined_chatelet连接到 net_test_1 网络,在查看determined_chatelet的详细信息,可以看到该容器连接了两个网络。

docker network connect net_test_1 determined_chatelet
docker inspect determined_chatelet

断开网路再次查看

docker network disconnect net_test_1 determined_chatelet
docker network disconnect net_test_2 determined_chatelet

实际案例二

不同网络的容器是无法通信的。需要加入同一个网络才能通信,并且只能访问同一个网络下的那个ip。

可以看到容器 magical_bartik的网络是net_test_1, IP地址是 172.19.0.2

docker inspect magical_bartik

可以看到容器 determined_chatelet 的网络是net_test_2, IP地址是 172.28.0.4

docker inspect determined_chatelet

进入到 determined_chatelet 容器

docker exec -it determined_chatelet bash
curl http://172.28.0.4 
curl http://172.19.0.2 

将上面两个容器同时连接到net_test_3 网络

docker network connect net_test_3 magical_bartik
docker network connect net_test_3 determined_chatelet 
docker inspect magical_bartik

再次进入到 determined_chatelet 容器


推荐一个零声学院免费教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,点击立即学习:

相关文章
|
22天前
|
Docker 容器
docker swarm启动服务并连接到网络
【10月更文挑战第16天】
20 5
|
22天前
|
调度 Docker 容器
docker swarm创建覆盖网络
【10月更文挑战第16天】
14 5
|
23天前
|
负载均衡 网络协议 关系型数据库
docker swarm 使用网络启动服务
【10月更文挑战第15天】
19 4
|
24天前
|
应用服务中间件 nginx Docker
docker swarm创建覆盖网络
【10月更文挑战第14天】
17 3
|
23天前
|
数据安全/隐私保护 Docker 容器
docker swarm创建网络
【10月更文挑战第15天】
10 1
|
24天前
|
Docker 容器
docker swarm 在服务中使用网络
【10月更文挑战第14天】
17 2
|
8天前
|
Docker 容器
【赵渝强老师】Docker的None网络模式
Docker容器在网络方面实现了逻辑隔离,提供了四种网络模式:bridge、container、host和none。其中,none模式下容器具有独立的网络命名空间,但不包含任何网络配置,仅能通过Local Loopback网卡(localhost或127.0.0.1)进行通信。适用于不希望容器接收任何网络流量或运行无需网络连接的特殊服务。
|
8天前
|
Docker 容器
【赵渝强老师】Docker的Host网络模式
Docker容器在网络环境中是隔离的,可通过配置不同网络模式(如bridge、container、host和none)实现容器间或与宿主机的网络通信。其中,host模式使容器与宿主机共享同一网络命名空间,提高性能但牺牲了网络隔离性。
|
8天前
|
Kubernetes Docker 容器
【赵渝强老师】Docker的Container网络模式
Docker容器在网络环境中彼此隔离,但可通过配置不同网络模式实现容器间通信。其中,container模式使容器共享同一网络命名空间,通过localhost或127.0.0.1互相访问,提高传输效率。本文介绍了container模式的特点及具体示例。
|
8天前
|
Linux Docker 容器
【赵渝强老师】Docker的Bridge网络模式
本文介绍了Docker容器的网络隔离机制及其四种网络模式:bridge、container、host和none。重点讲解了默认的bridge模式,通过示例演示了如何创建自定义bridge网络并配置容器的网络信息。文中还附有相关图片和视频讲解,帮助读者更好地理解Docker网络的配置和使用方法。