了解Docker网络的七种模式
0. 双网卡
-
Host: Linux vm
-
网卡:NAT+Host-only
-
问题:为什么设置双网卡?🤔
NAT模式用于上网。
IP地址的稳定性。
(1)NAT模式,虚拟机的IP地址通过NAT网关翻译成与物理机同个网段的IP地址,虚拟机最终共享这个网段的IP地址,共享意味着要考虑冲突,虚拟机不能霸占已经在使用中的IP地址。为了更有效地利用有限的IP地址资源,物理机管理和维护一个NAT网络的IP地址池,虚拟机关闭时释放IP地址,启动时从NAT网络中的IP地址池重新获取可用的IP地址,这样既避免冲突,又避免浪费。
(2)Host-only模式,有一个隔离的虚拟网络,虚拟机无需和外界共享这个网段,虚拟网络分配给虚拟机一个IP地址,不会说这个IP地址会突然被抢走,也就是说虚拟机可以一直拥有这个IP地址。
配置Host-only模式的原因我是想拥有一个稳定的IP地址,这样物理机还可以为这个IP地址设置别名,方便进行ssh连接。而且虚拟机开放ssh端口有安全隐患,Host-only模式的隔离性也使之得到了安全保证。
开放ssh端口
sudo apt-get install openssh-server安装后自动开启服务
sudo ps -e |grep sshd 验证是否启动
到 /etc/ssh/sshd_config取消port: 22的注释
service ssh restart启动服务
主机ssh连接
5. 为IP地址起别名
(1)本地主机有公钥和密钥
(2)把公钥复制到远程主机上
①虚拟机创建/home/ryon/.ssh目录
②scp id_rsa.pub ohyeah:/home/ryon/.ssh
③进入虚拟机,cat id_rsa.pub > authorized_keys
(3)再次ssh,这次不用密码
🥱来到正文,开始了解Docker的网络模式
1. the default Bridge
sudo apt install docker.io -y
Docker服务默认创建一个docker0网桥,在内核层连通了其他的物理或虚拟网卡
- 默认制定了docker0接口的IP地址为172.17.0.1/16
- 🛼运行三个使用默认的使用docker0网桥的容器
sudo docker run -itd --rm --name milk busybox
sudo docker run -itd --rm --name bread busybox
sudo docker run -itd --rm --name coffee nginx
- ✔️验证:bridge link
👀查看容器的ip地址
sudo docker inspect bridge
- 容器互相访问
sudo docker exec -it milk sh
- 容器访问外网
- 令coffee暴露80端口,使得物理机可以通过虚拟机的ip直接访问nginx服务
sudo docker stop coffee
sudo docker run -itd --rm -p 80:80 --name coffee nginx
2. User-defined 自定义桥接网络
sudo docker network create greatwall
- 产生新的虚拟网桥,网关是
172.18.0.1/16
- 运行两个使用新网桥的容器
sudo docker run -itd --rm --network greatwall --name beijing busybox
sudo docker run -itd --rm --network greatwall --name shenzhen busybox
ip addr show
bridge link
sudo docker inspect greatwall
-
📁隔离性
-
进入milk容器,你将发现ping不到beijing
-
🤙而且使用了自定义的网桥,容器之间可以通过名字访问(DNS)。如在beijing中ping通shenzhen,这个很实用,docker0则没有这个效果。
3. the Host
sudo docker stop coffee
sudo docker run -itd --rm --network host --name coffee nginx
-
效果
-
coffee和虚拟机共享端口,在物理机访问虚拟机的双ip地址均出现nginx。
-
👍够简单,代价是失去隔离性
3. MacVLAN
-
just simpley connect our Docker contaners directly to our physical network
-
本质上是一种网卡虚拟化技术。将一张物理网卡设置多个Mac地址,一变多。性能好,相比其他实现,不需要创建Linux bridge,而是直接通过以太interface连接到物理网络
-
分配独立的ip地址和MAC地址,Host收到数据包后,根据不同的MAC地址把数据包转发给不同的子接口,在外界看来相当于多台主机。
-
macvlan并不创建网络,只创建虚拟网卡。
-
ip route show
查看网关
sudo docker network create -d macvlan
--subnet 192.168.241.0/24
--gateway 192.168.241.2
-o parent=ens33
subway
sudo docker stop milk bread
sudo docker run -itd --rm --network subway
--ip 192.168.241.92
--name milk busybox
sudo docker run -itd --rm --network subway
--ip 192.168.241.95
--name bread busybox
sudo docker run -itd --rm --network subway
--ip 192.168.241.96
--name tea nginx
sudo docker exec -it milk sh
ip address show
eth0@if2
: 是2的子接口,2就是我们主机的ens33网卡
- 结构
- 这个subway网络会独占物理网卡,也就是说一张物理网卡只能创建一个MacVLAN网络。我们想创建多个macvlan网络就得用多张网卡,但主机的物理网卡是有限的,怎么办呢?
- MacVLAN网络支持VLAN子接口,通过将一个网口划分出多个子网口,就可以基于子网口创建MacVLAN网络。
parent interface
父接口可以是一个物理接口(eth0),也可以是一个802.1q的子接口(eth0.10)
3+. the macVLAN(802.1q)
- 在交换机上,如果某个port只能首发单个VLAN的数据,则该端口为
Access模式
;如果支持多VLAN,则为Trunk
模式。 - 实际生产中宿主机的ens33要接在交换机的trunk口上。不过在虚拟机中不需要额外配置了。
- 效果
sudo docker stop milk bread tea
sudo docker network rm subway
sudo docker network create -d macvlan
--subnet 192.168.20.0/24
--gateway 192.168.20.1
-o parent=ens33.20
macvlan20
sudo docker network create -d macvlan
--subnet 192.168.30.0/24
--gateway 192.168.30.1
-o parent=ens33.30
macvlan30
sudo docker run -itd --rm --network macvlan20
--ip 192.168.20.92
--name milk busybox
sudo docker run -itd --rm --network macvlan20
--ip 192.168.20.95
--name bread busybox
sudo docker run -itd --rm --network macvlan30
--ip 192.168.30.96
--name tea nginx
- 特点
- 现在在容器内部只能ping通同个macvlan网络中的其他容器了,不能ping通其他macvlan网络中的容器,也不能ping通外网
- 解决方案:可以借助三层路由完成通信,留坑(我不会😖)。
4. the IPVlan (L2)
- ipvlan和macvlan类似,都是从一个主机接口虚拟出多个虚拟网络接口。
- ipvlan虚拟出的子接口都有相同的mac地址,但可配置不同的ip地址。
- ipvlan有两种不同的工作模式:L2和L3. 一个父接口只能选择其中一种模式
- L2模式与macvlan的bridge模式相似
- 父接口作为
交换机
来转发子接口的数据 - 同一个网络的子接口可以通过父接口来转发数据
- 如果想发送到其他网络,报文通过父接口的路由转发
- 父接口作为
sudo docker network create -d ipvlan
--subnet 192.168.241.0/24
--gateway 192.168.241.2
-o parent=ens33
subway
# 像macvlan一样,L2模式要求分配给子接口的IP地址与父接口在同一子网中
sudo docker run -itd --rm --network subway
--ip 192.168.241.92
--name milk busybox
sudo docker run -itd --rm --network subway
--ip 192.168.241.95
--name bread busybox
- 观察MAC地址,重新ping通后再进行arp查询
- 结构
5. the IPVlan (L3)
- L3,第三层,关注IP地址、路由表。
- No switching , No Mac, No arps,这些都是L2,第二层,现在不关注。
- 现在不把容器接在swtich,接在host,把host当成一台路由器。
- 不同点在于现在没有广播,no broadcast. It's not responding to our request。所以传统gateway对L3模式没有意义。
- 要与外界通信,就需要我们配置路由。
- 体现一个特征:Control
- no one can reach them, but I can control who reaches them.
sudo docker network create -d ipvlan
--subnet 192.168.94.0/24
# L3模式要求容器网络和IP地址所在的子网不同于父接口
-o parent=ens33 -o ipvlan_mode=l3
--subnet 192.168.95.0/24 # 我可以配置多个子网
ipvlanl3
sudo docker run -itd --rm --network ipvlanl3
--ip 192.168.94.7
--name milk busybox
sudo docker run -itd --rm --network ipvlanl3
--ip 192.168.94.8
--name bread busybox
sudo docker run -itd --rm --network ipvlanl3
--ip 192.168.95.7
--name beijing busybox
sudo docker run -itd --rm --network ipvlanl3
--ip 192.168.95.8
--name shenzhen busybox
- milk不能访问外网,because it doesn't have a route out. 但是milk可以ping bread(无需路由), 甚至可以ping通其他子网下的 beijing和shenzhen(走路由)
Unlike ipvlan l2 mode, different subnets can ping one another as long as they share the same parent interface
-
they can talk to each other all day
-
Now , I want them to access everything.
-
So let's add a static route in my network
-
配置静态路由,让物理机可以访问到容器
route add 192.168.94.0 mask 255.255.255.0 192.241.138 -p
ping 192.168.94.7
- 物理机现在是可以访问milk了,但仅仅是单向。
- milk还是无法ping通外网,好吧,到此为止😭。
6. Overlay
- is more for, if you have different hosts
- 现在的环境是单主机docker,用不到
- 但是在实际生产环境中,往往不止一台, 它们往往部署在Docker Swarm
- Docker Swarm类似于Kubernetes. It's just Docker's version of Kubernetes.
- 对于多个docker服务器上的多个容器间网络通信, 需要一种独立于主机的网络配置,也就是Overlay。
- 作为入门,我现在可能还用不上。适合在学习Docker swarm或者Kubernetes的时候再来。(🏃♂️溜!)
7. None
- It's absolutely nothing.
- 无需设置,它已存在🧘♂️
- The driver is null. so cool
- 如果我创建一个容器,
--network none
, 它的网卡只有一个lo
🎉