本文是自己的学习笔记
- 1、Linux中的namespace
- 1.1、创建namespace
- 1.2、两个namespace互相通信
- 2、Docker中的namespace
- 2.1 容器中的默认Bridge
- 3、容器的三种网络模式
1、Linux中的namespace
Docker
中使用了虚拟网络技术,让各个容器的网络隔离。好像每个容器从网卡到端口都有自己独立的一套网络架构。
namespace
是实现网络虚拟化的重要功能。
它原本是Linux
系统的提供的功能,Docker
借用这些namespace
实现容器间的隔离。比如PID
的namespace
可以实现进程间的隔离;User namespace
实现用户和组的隔离;而NET namespace
实现网络的隔离,这也是本篇文章的重点。
下面是用Linux
的NET namespace
实现网络隔离的示例。
1.1、创建namespace
输入ip a
查看所有网卡。图中显示有四个。注意第一个网卡lo
,接下来我会创建一个网络namespace
。这个namespace
也会有一个同名的网卡,但是这两个网卡是相互隔离的。
现在添加一个namespace
,命名为ns1
。
ip netns add ns1
。
之后进入这个命名空间执行指令,查看这个命名空间的网卡,ip netns exec ns1 ip a
。
里面也有一个lo
网卡,但这个网卡和主机的lo
是完全隔离的。
1.2、两个namespace互相通信
在 Linux
网络中,veth-peer (Virtual Ethernet Peer) 指的是 veth (Virtual Ethernet) 设备对中的另一端。veth
设备是一种特殊的虚拟以太网设备,它总是成对出现,可以把它想象成一根虚拟的网线。
我们在两个namespace
之间创建veth-pair
来实现互相通信。
首先创建两个namespace
,分别命名为ns1
和ns2
。
之后用下面的指令启动他们的lo
网卡。
ip netns exec ns1 ifup lo
ip netns exec ns2 ifup lo
创建一个veth-pair
。
ip link add veth-ns1 type veth peer name veth-ns2
。
之后再查看网络情况,第五和第六就是新建的一对veth
将veth-ns1
设置到ns1
,veth-ns2
设置到ns2
。
ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2
之后需要在ns1
和ns2
中为这对veth
分配地址。
ip netns exec ns1 ip addr add 192.168.0.11/24 dev veth-ns1
ip netns exec ns2 ip addr add 192.168.0.12/24 dev veth-ns2
然后分别到ns1
和ns2
中启动这对veth
。
ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip link set veth-ns2 up
这时候ns1
和ns2
就可以互相ping通。
ns1
和ns2
之间的关系如下图。
2、Docker中的namespace
2.1 容器中的默认Bridge
在Docker
中,每个容器都有自己的一个namespace
,他们之间的网络相对独立。
在默认情况下,这些容器之间也是可以直接相互通信的,不需要特别花心思去建立veth-pair
。
这是因为它们通常连接到同一个虚拟网络,并且Docker为这个虚拟网络提供了必要的网络基础设施和发现机制。
Docker 默认的网络模式就是 桥接网络 (Bridge Network)。当创建一个容器时没有指定特定网络时,容器内除了lo
这个回路网卡,还会有一个类似于veth@if43
名字的网卡。下图是一个tomcat
容器中的网络情况,有一个veth@if24
的网卡。
这个veth@if43
就是Linux
中的虚拟网线veth
,它就会默认连接到这个 docker0
网桥。
当我们启动任意一个容器时,查看宿主机的网络也能看到docker0
会自动创建出来。下图就是启动一个tomcat
容器后,宿主机的网络情况,有个docker0
的网卡。
下面启动两个tomcat
容器,然后互相ping
能看到网络是互通的。
分别命名tomcat01
和tomcat02
两个容器并启动。之后执行下面指令查看两个容器的网络情况。
docker exec -it tomcat01 ip a
docker exec -it tomcat02 ip a
可以看到tomcat01
有一个网卡是eth0@if24
,地址是172.17.0.2/16
;而tomcat02
则是eth2@if26
,地址172.17.0.3/16
。
然后进入tomcat01
去pingtomcat02
的网卡。
docker exec -it tomcat01 ping 172.17.0.3
结果是网络可达。
3、容器的三种网络模式
Dcoker
给容器提供了三种网络模式。
host
:这个模式下容器将与Docker
主机共享一套网络架构。none
:这个模式下容器无法与外界甚至主机进行网络交流。bridge
:容器的默认网络模式。在这个模式下,容器拥有自己一套独立的虚拟网络架构。同时容器中会自动创建一对指向docker0
的veth-pair
。docker0
作为中转站使所有容器网络互通,同时容器也必须通过docker0
才能和外界网络沟通。
我们可以在容器启动时指定网络模式。
docker run -d --name my-tomcat-none --network none tomcat-ip:1.0