docker网络种类,架构及命令

简介

docker容器网络是为应用程序创造的虚拟环境的一部分,可以让应用内从宿主机操作系统的网络环境中独立出来,默认与宿主机和其他容器相互隔离,形成容器自有的网络设备,IP,端口套接字等与网络相关的模块。

也需要考虑到容器与容器之间/容器与主机之间/容器与外界主机之间的通信,如果不想隔离要怎么实现,所以需要涉及到网络的问题。

架构

CNM

  • sandbox :是容器独立的网络隔离环境,包含容器网络栈的所有配置(例如端口,套接字,IP路由表等等),用于实现容器和宿主机,容器和容器之间的网络隔离,让每个容器拥有完全独立的网络视图,不会互相干扰。
    在Linux中通过namespace实现,一个sandbox可以关联多个endpoint(也就是说一个容器可以同时接入多个网络)。
  • endpoint :是连接sandbox和network的虚拟网络接口,也是容器接入网络的唯一入口,负责将容器接入指定的网络,完成网络连接的配置。
    通常采用虚拟网卡计数实现,一端位于sandbox内,另一端接入network对应的网络设备(例如网桥),一个endpoint只能接入一个network,因此容器需要接入多网络的时候,必须配置多个endpoint。
  • network:是一组可以直接通信的endpoint集合,逻辑上等同于子网/广播域,用于提供容器间的通信域,一个network的endpoint可以直接互通,不同network的endpoint默认隔离。

Libnetwork

Libnetwork是CNM的一个标准实现,采用Go语言编写,docker网络架构的核心代码都在这个库中,Libnetwork实现了CNM中定义的全部三个组件,此外,还实现了本地服务发现,基于Ingress的容器负载均衡,以及网络控制层和管理层等功能。

驱动

Libnetwork是代码层面上的实现,而驱动是Libnetwork的插件化模块,负责把CNM的抽象组件映射到具体的底层网络上。

这样,Libnetwork就不关心底层用的是Linux网桥,VLAN还是别的,实现解耦抽象和实现。

网络管理命令

docker network create

用于创建自定义网络。

bash 复制代码
docker network create [options] network

-d指定网络驱动

--gateway指定网关地址

--subnet用于定义网段的CIDR格式的子网,容器会从这个网段分配IP

--ipv6表示启动ipv6

docker network inspect

用于查看网络详情。

bash 复制代码
docker network inspect [options] network1 [network2...]

-f指定格式

docker network connect

用于将容器连接到网络,可以按名称或者ID连接容器,一旦连接,容器可以与同一网络中的其他容器通信。

bash 复制代码
docker network connect [options] network container

--ip用于指定IP地址

--ip6用于指定ipv6地址

还可以使用docker run --network=< networkname >选项启动容器并立即将其连接到网络

docker network disconnect

用于断开网络。

bash 复制代码
docker network disconnect [options] network container

-f表示强制退出

docker network prune

用于删除不使用的网络。

bash 复制代码
docker network prune [options]

-f表示删除的时候不提示

docker network rm

用于删除一个或者多个网络。

bash 复制代码
docker network rm network1 [network2...]

-f表示强制退出

docker network ls

用于列出网络。

bash 复制代码
docker network ls [options]

-f用于指定过滤条件

--format用于指定格式

--no-trunc表示输出不截断

-q表示仅仅显示id

基本操作

  • 创建网络并指定ip地址段
bash 复制代码
docker network create --subnet=172.19.0.0/16 网络名
  • 查看创建的网络
bash 复制代码
docker network ls
  • 创建一个容器并加入网络
bash 复制代码
docker run -d --name 容器名 --network 网络名 nginx
  • 查看容器的网络信息
bash 复制代码
docker inspect 容器名
  • 创建一个新的nginx容器,但不加入自定义网络
bash 复制代码
docker run -d --name 容器名 nginx
  • 查看容器的网络配置,可以看到采用的是桥
bash 复制代码
docker inspect 容器名
  • 将第二个容器加入自定义网络
bash 复制代码
docker network connect 网络名 容器名
  • 再次查看容器2的网络配置,发现容器2多了一个网络
bash 复制代码
docker inspect 容器名
  • 让容器2断开网络,再次查看容器2的配置,可以看到只剩下一个bridge网络了
bash 复制代码
docker network disconnecct 网络名 容器名
docker inspect 容器名
  • 删除网络,可以看到网络被使用了,无法删除
bash 复制代码
docker network rm 网络名
  • 删除容器1,再删除网络,可以看到当我们停止了所有容器,就可以正常删除网络了
bash 复制代码
docker stop 容器名
docker rm 容器名
docker network rm 网络名

网络种类

docker bridge网络

概念

docker bridge驱动底层采用的是Linux内核中Linux bridge技术,bridge(网桥)是工作在链路层的设备,负责在不同网络段之间转发流量,在Docker中,通过软件模拟实现了名为docker0的网桥。

这样,同一网桥网络内的容器可相互通信,未接入该网桥的容器则被隔离,实现了容器间的网络隔离与互通。

  • docker container是容器内部的网络接口,对应的设备名为eth0。
  • veth是虚拟以太网对,是连接容器和网桥的虚拟网线,连接eth0和docker0。
  • docker0是默认的软件网桥,是容器网络转发的核心转发节点。
  • host是宿主机,eth0是宿主机的物理网卡,负责与外部进行通信。
  • ipv4 ip_forward是内核IP转发功能,允许网桥将流量转发到物理网卡。

默认情况下,创建的容器在没有使用--network参数指定要加入的docker网络时,默认都是加入docker单机桥接网络,即名字为bridge的网络。

docker默认的bridge网络和Linux内核中的docker0网桥是一一对应的关系,bridge是docker对网络的命名,docker0是内核中网桥的名字。

操作

容器间的网络通信
  • 使用busybox(集成了一百多个常用的Linux命令和工具)镜像创建两台容器,并且保持在后台运行
bash 复制代码
docker run -itd --name test1 busybox
docker run -itd --name test2 busybox
  • 查看容器通信的现象
bash 复制代码
docker exec -it test1 ip a
docker exec -it test2 ip a
docker exec -it test1 ping [test2的IP]


  • 确定两个容器可以通信以后,查看一下bridge网络的信息,此时可以看到,该网络已经连接了2个容器,test1和test2就是通过docker0这个网桥来进行通信的
bash 复制代码
docker network inspect bridge
  • 当我们停止或者删除掉一个容器的时候,会发现该容器会自动和docker0切断连接
bash 复制代码
docker stop test1
docker network inspect bridge
创建自定义bridge

在默认情况下,我们创建的容器都会连接在docker0这个bridge上,我们也可以创建一些自定义的bridge,让运行的容器通过自定义bridge进行通信。

  • 通过create命令来创建新的bridge
bash 复制代码
docker network create -d bridge new-bridge
  • 查看new-bridge的网络信息
bash 复制代码
docker network inspect new-bridge
  • 创建容器,使用--network选项指定要连接的网络,如果不指定,默认连接的是bridge
bash 复制代码
docker run -itd --name test1 --network new-bridge busybox
#过滤网络相关信息
docker inspect test1 | grep "Networks" -A 17
#查看自定义bridge网络详细信息
docker network inspect new-bridge


DNS解析

docker自定义桥接网络是支持通过docker DNS服务进行域名解析的,也就是说我们可以直接使用容器名进行通信,因为DNS服务可以解析容器名到IP地址的映射,但默认的bridge网络是不支持DNS的。

  • 创建四个容器,test1和test2都默认连接bridge网络,test3和test4默认连接new-bridge网络。
bash 复制代码
docker network create -d bridge new-bridge
docker run -itd --name test1 busybox
docker run -itd --name test2 busybox
docker run -itd --name test3 --network new-bridge busybox
docker run -itd --name test4 --network new-bridge busybox
#查看两个网络里面连接的容器
docker network inspect bridge
docker network inspect new-bridge
  • 验证test1和test2能否使用dns解析服务
bash 复制代码
docker exec -it test1 ip a
docker exec -it test2 ip a
#test1容器pingtest2的IP地址是可以ping通的
docker exec -it test1 ping [test2的IP]
#test1容器pingtest2的容器名是找不到IP地址的
docker exec -it test1 ping test2
  • 验证test3和test4能否使用dns解析服务
bash 复制代码
docker exec -it test3 ip a
docker exec -it test3 ip a
#test1容器pingtest2的IP地址是可以ping通的
docker exec -it test3 ping [test4的IP]
#test1容器pingtest2的容器名是找不到IP地址的
docker exec -it test3 ping test4
端口暴露和转发
  • 端口暴露有两种方式,在启动容器的时候添加端口参数,一种是-P暴露所有端口,将暴露的所有端口映射到主机所有地址的一个动态端口,另外一种是-p暴露指定端口。
  • 端口转发,连接bridge容器的端口映射到宿主机的端口上,那么任何发送到宿主机该端口的流量,都会转发到容器的端口中。
    例如下图,任何发送到8088端口的流量都会被转发到container1的80端口,任何发送到8089端口的流量都会转发到container2的80端口。

docker host网络

概念

docker容器运行默认都会分配network namespace隔离子系统,如果是基于host网络模式,容器将不再获得一个独立的network namespace,而是和宿主机共用同一个network namespace,容器将不再虚拟出自己的网卡,IP等,而是直接使用宿主机的IP端口。

bridge网络在通信的时候需要进行端口转发以及NAT地址转换,肯定会消耗掉一些资源以及性能。直接使用host网络最大的好处就是性能好,如果容器对网络传输有较高的要求,建议选择host网络,但host也有一些不足,比如说要考虑端口冲突的问题。

操作

  • 创建test1容器使用bridge网络,test2容器使用host网络
bash 复制代码
docker run --name test1 -itd busybox
docker run --name test2 -itd --network=host busybox
  • 查看test1容器的网络信息
bash 复制代码
docker exec test1 ip a
  • 查看test2容器的网络信息
bash 复制代码
docker exec test2 ip a

可以看到test1容器是独立的网络配置,test2容器是和宿主机共享网络配置

docker container网络

概念

docker container的other container网络模式是docker中一种比较特别的网络模式,这个模式下的docker container会使用其他容器的网络环境,网络隔离性会处于bridge桥接模式和host模式之间,docker container共享其他容器的网络环境,则至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及其他的容器存在网络隔离。

实现这种模式需要两步

  • 查找other container(即需要被共享网络环境的容器)的网络namespace
  • 让新创建的docker container(需要共享其他网络的容器)的namespace使用other container的namespace

操作

  • 创建一个busybox容器
bash 复制代码
docker run -itd --name test1 busybox
  • 使用test1的网络搭建另外一个容器
bash 复制代码
docker run -itd --name test2 --network container :test1 busybox
  • 查看两个容器的ip信息,会发现两个ip和mac完全一样
bash 复制代码
docker exec -it test1 ip a
docker exec -it test2 ip a
  • 停止test1容器,查看test2容器的网络,会发现eth0网卡消失了,只有一个本地网络了
bash 复制代码
docker stop test1
docker exec -it test2 ip a
  • 再次重启test1容器和test2容器
bash 复制代码
docker restart test1 
docker restart test2
  • 再次查看test2容器,会发现eth0回来了,网络恢复

    这种模式下的docker container可以通过localhost来访问namespace下的其他容器,传输效率较高,但两个容器之间存在依赖,如果依赖的容器重启了,就会导致另外一个服务不可用。

docker none网络

none网络就是指没有网络,挂在这个网络下的容器出来lo(本地环回),没有任何其他网卡。

针对一些对安全性要求比较高且不需要联网的应用,可以使用none网络,比如说生成随机密码,避免生成的密码被第三方获取,一些第三方的应用也可能需要docker创建一个没有网络的容器,网络由第三方自己配置。

相关推荐
qq_297574672 小时前
K8s系列第十五篇(终篇):K8s 集群优化实战:性能、稳定性与安全性优化
docker·容器·kubernetes
const_qiu2 小时前
测试左移实践:在开发阶段构建质量防线
架构·可用性测试
小陈工2 小时前
Python测试实战:单元测试、集成测试与性能测试全解析
大数据·网络·数据库·人工智能·python·单元测试·集成测试
wefg12 小时前
【计算机网络】套接字编程(套接字API/UDP和TCP服务器)
服务器·网络·计算机网络
有毒的教程2 小时前
Ubuntu 安装完成后网络配置教程
linux·网络·ubuntu
CIAS2 小时前
openclaw 扩展企业微信模块
docker·openclaw
二等饼干~za8986682 小时前
豆包geo优化系统,源码开发搭建解析
大数据·网络·数据库·人工智能·django
小杨啥都学2 小时前
通过ipsec服务端给客户端分配ip
服务器·网络·tcp/ip·ipsec
不一样的故事1262 小时前
线号管并非必须和端子端面绝对齐平
网络·安全