了解Docker的网络模式

了解Docker网络的七种模式

  1. 双网卡
    • 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,这次不用密码 ssh免密
  • 🥱来到正文,开始了解Docker的网络模式

    1. the default Bridge
      sudo apt install docker.io -y
      

      docker0 network Docker服务默认创建一个docker0网桥,在内核层连通了其他的物理或虚拟网卡

      • 默认制定了docker0接口的IP地址为172.17.0.1/16 now
      • 🛼运行三个使用默认的使用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
      

      3个容器使用docker0

      • ✔️验证:bridge link 验证一下 👀查看容器的ip地址
      sudo docker inspect bridge
      

      查看ip

      • 容器互相访问
      sudo docker exec -it milk sh
      

      ping

      • 容器访问外网 访问外网
      • 令coffee暴露80端口,使得物理机可以通过虚拟机的ip直接访问nginx服务
      sudo docker stop coffee
      sudo docker run -itd --rm -p 80:80 --name coffee nginx
      

      暴露80端口 物理机访问

    2. User-defined 自定义桥接网络
      sudo docker network create greatwall
      
      • 产生新的虚拟网桥,网关是172.18.0.1/16 新网桥 greatwall
      • 运行两个使用新网桥的容器
      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
      

      ip

      • 📁隔离性 现在的格局

      • 进入milk容器,你将发现ping不到beijing 隔离性

      • 🤙而且使用了自定义的网桥,容器之间可以通过名字访问(DNS)。如在beijing中ping通shenzhen,这个很实用,docker0则没有这个效果。 通过名字ping

    3. the Host
      sudo docker stop coffee
      sudo docker run -itd --rm --network host --name coffee nginx
      
      • 效果 效果

      • coffee和虚拟机共享端口,在物理机访问虚拟机的双ip地址均出现nginx。 双ip均可访问

      • 👍够简单,代价是失去隔离性

    4. 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网卡 wow
  • ping 网关和外网 great
  • 容器互访,在bread里ping通milk cool
  • 物理机访问tea it works
    • 结构 在这里插入图片描述

    多个Mac地址

    • 这个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口上。不过在虚拟机中不需要额外配置了。
  • 编辑/etc/network/interfaces,配置sub-interface
    • 效果 子网口划分
    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
    

    在milk中ping bread

    • 特点
      • 现在在容器内部只能ping通同个macvlan网络中的其他容器了,不能ping通其他macvlan网络中的容器,也不能ping通外网
      • 解决方案:可以借助三层路由完成通信,留坑(我不会😖)。
    1. 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
    2. 像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

      ping

      • 观察MAC地址,重新ping通后再进行arp查询 都一样
      • 结构 一样的mac
    3. 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 
    4. 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

      wuli

      • 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通外网,好吧,到此为止😭。
    5. 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的时候再来。(🏃‍♂️溜!)
    6. None
      • It's absolutely nothing.
      • 无需设置,它已存在🧘‍♂️ none
      • The driver is null. so cool
      • 如果我创建一个容器, --network none, 它的网卡只有一个lo lo

    🎉