总结:网络主要是单机网络和多主机通信模式。 下面对每种网络模式进行介绍。 设计的网络模型。 这是为该对定义的元数据。 用户可以通过定义此类元数据来自定义和控制行为。
简介
主要从命名空间、cgroup、协作文件、运行时(runC)和网络方面了解docker。 接下来,我将花时间分别介绍一下他们。
Docker系列--命名空间解读
docker系列--cgroups解读
Docker系列--] unionfs解读
docker系列--runC解读
docker系列--网络模式解读
namesapce主要用于隔离,cgroups主要用于资源限制,联合文件主要用于镜像的分层存储和管理。 runC 是一个遵循 oci 接口的运行时,通常基于 libcontainer。 组网主要是docker独立组网和多主机通信方式。
原生网络模式
使用 docker run 创建 Docker 容器时,可以使用 --net 选项指定容器的网络模式。 Docker有四种网络模式:
主机模式。 指定为 --net=host。
容器模式。 使用 --net=container:NAME_or_ID 指定。
无模式。 使用 --net=none 指定。
桥接模式。 使用 --net=bridge 指定。 默认设置。
下面我们将介绍Docker的各个网络模式。
1) none:不在容器中配置网络功能。
在此模式下,容器必须使用 --net=none 参数启动。
$ docker run --net=none -ti ubuntu:latest ip addr show1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8范围主机lo valid_lft永久preferred_lft永久inet6 ::1/128范围主机valid_lft永久preferred_lft永久
可以看到Docker容器只有一个lo环回接口。 用户使用 --net=none 启动容器后,用户仍然可以手动配置容器的网络。
2)容器:共享网络命名空间,并与另一个正在运行的容器共享相同的网络视图。
例如,首先使用默认网络配置(桥接模式)启动容器,并将主机名设置为 dockerNet,DNS 设置为 8.8.4.4。
$ docker run -h dockerNet --dns 8.8.4.4 -tid ubuntu:最新 bashd25864df1a3bbdd40613552197bd1a965acaf7f3dcb2673d50c875d4a303a67f$ docker exec -ti d 258 64df1a3b bashroot@dockerNet:/# ip地址show1 : lo: mtu 65536 qdisc noqueue 状态 UNKNOWN 组默认链接/环回 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 范围主机 lo valid_lft 永久 Preferred_lft 永久inet6 ::1/128 范围主机 valid_lft 永久 Preferred_lft four1739: eth0: mtu 1500 qdisc noqueue 状态 UP 组默认链接/ether 02:42:ac:11:00:01 brd ff:ff: ff :ff:ff:ff inet 172.17.0.1/16 范围全局 eth0 valid_lft 永久 Preferred_lft 永久 inet6 fe80::42:acff:fe11:1/64 范围链接 valid_lft 永久 Preferred_lft 永久 root@dockerNet:/# cat /etc/resolv 。 confnameserver 8.8.4.4root@dockerNet:/# exitexit
然后 --net=container:d25864df1a3b:
$ docker run -[ k4] 启动另一个容器作为 。 净=Container:d25864df1a3b -ti ubuntu:latest bashroot@dockerNet:/# ip addr show1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00: 00: 00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 作用域主机 lo valid_lft 永久 Preferred_lft 永久 inet6 ::1/128 作用域主机 valid_lft 永久 Preferred_lft 永久 1739: eth0: mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:01 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 range global eth0 valid_lft permanent Preferred_lftforever 您可以使用检查inet6 fe80::42 :acff:fe11:1/64scope 链接 valid_lftforeverpreferred_lftforeverroot@dockerNet:/#cat/etc/resolv.confnameserver8.8.4.4
-。]-net=container:使用 d25864df1a3b 参数启动的容器具有从容器 d25864df1a3b 继承的 IP 地址、DNS 和主机名。 事实上,这两个容器共享相同的网络命名空间,并且具有完全相同的自然网络配置。
3)主机:与主机共享根网络命名空间。 它被认为是不安全的,因为容器拥有操作主机协议栈、路由表、防火墙等的完全权限。
同样,如果要以主机模式启动,则必须指定 --net=host 参数。 示例:
$ docker run -ti --net=host ubuntu:latest bashroot@darcy-HP:/# ip addr show1: lo: mtu 65536 qdisc noqueue 状态未知组默认链接/环回 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 范围主机 lo valid_lft 永远 Preferred_lft 永远 inet6 : :1/128 范围主机 valid_lft 永久 Preferred_lft 永久 2: eth0: mtu 1500 qdisc pfifo_fast 状态 DOWNgroup 默认 qlen 1000 link/ether 2c:41:38:9e: e4: d5brd ff:ff:ff:ff:ff:ff3: eth1: mtu 1500 qdisc pfifo_fast 状态 UPgroup 默认 qlen 1000 链路/以太 00:1b:21:cc:ee:6d brd ff: ff:ff:ff:ff:ff inet 10.110.52.38/22 brd 10.110.55.255范围全局eth1 valid_lft永久preferred_lft永久inet6 fe80::21b:21ff:fecc:ee6d/64范围链接valid_lft永久preferred_lft永久1642:docker0: mtu 1500 qdisc noqueue状态UPgroup默认链接/以太22:f2:f3:18:62:5d brd ff:ff:ff:ff:ff:ff inet 172.17.42.1/16范围全局docker0 valid_lftforeverpreferred_lftforeverinet6 fe80::348e:71ff:fe44:2d41/64范围链接 valid_lftforeverpreferred_lftforever
在主机模式下,容器可以操作主机的网络配置。 这很危险。 除非绝对必要,否则您应该尽可能执行此操作您可以避免使用主机模式。
4)Bridge:Docker设计的NAT网络模型。
当 Docker 守护进程启动时,它会在主机上创建一个 Linux 网桥(默认为 docker0,可以使用 -b 参数手动指定)。 当容器启动时,Docker 会创建一个 vethpair(虚拟网络接口)设备对。 VETH 设备的一个特点是它们成对存在,从一个设备输入的数据同时显示在另一个设备上。 Docker将一端挂载在docker0网桥上,另一端挂载到容器的网络命名空间中,实现容器与主机之间的通信。 下图是桥接模式的网络拓扑图。
在桥接模式下,Docker容器与互联网之间以及不同容器之间的通信由iptables规则控制。
也就是说,Docker网络初始化动作包括创建docker0网桥,为docker0网桥创建新的子网和路由,以及创建相应的iptables规则。
跨主机通信方式
Docker在跨主机通信方面一直比较弱。 目前主要有两种类型:容器网络模型(CNM)和容器网络接口(CNI)。 下面我们将逐一介绍。 当然,我们使用CNI来进行k8s和docker之间的通信。
CNM模式
CNM是Docker提出的一个规范。 目前,Cisco Contiv、Kuryr、开放虚拟网络 (OVN)、Project Calico、VMware 和 Weave 等公司和项目都在使用它。
Libnetwork 是 CNM 的本机实现。 提供 Docker 守护进程和网络驱动程序之间的接口。 网络控制器负责将驱动程序连接到网络。 每个驱动程序负责管理他们拥有的网络以及他们向该网络提供的各种服务,例如 IPAM。 多个驱动程序支持的多个网络可以同时共存。 网络驱动程序可以按提供商分为本机驱动程序驱动程序(内置 libnetwork 或 Docker 支持)或远程驱动程序(第三方插件)。 本机驱动程序包括 None、Bridge、Overlay 和 MACvlan。 根据作用范围,驱动程序还可以分为本地(单主机)和全局(多主机)。
“网络沙箱”——容器内的网络堆栈。
'端点' – 网络接口,通常成对显示。 一端位于网络容器内部,另一端位于网络内部。 端点可以加入网络。 一个容器可以包含多个端点。
“网络”——端点的集合。 该集合中的所有端点都可以互连。
最后,CNM还支持标签。 标签是由键-值对定义的元数据。 用户可以通过定义标签等元数据来自定义 libnetwork 和驱动程序行为。
API使用步骤
接下来,我们看一下libnetwork的一般使用方法。 具体步骤一般如下:
(1)获取NetworkController对象。 用于执行以下操作: 检索对象时指定驱动程序。
(2) 使用 NetworkController 对象的 NewNetwork() 建立网络。 这里最容易理解的是一座桥已经建成了。
(3) 使用网络的CreateEndpoint()在此网络上创建端点。 这里最简单的理解是,每次创建端点时,上面创建的网桥上都会有一个额外的 VIF 端口,用于监听虚拟机或沙箱连接。 假设这里使用veth,veth的一端当前连接到桥上,另一端仍然暴露在外。
(4) 为了调用上面创建的端点的Join方法并提供容器信息,libn网络中的代码创建一个Sandbox对象(通常这里的Sandbox是一个容器命名空间,所以不会重复创建),并将第三步创建的veth的一端连接到Masu。 在命名空间沙箱中。
(5)当沙箱生命周期结束时,调用端点的Leave方法解除与网络的绑定。 简单地说,我们将 veth 从沙箱命名空间中取出并返回到物理机中。
(6) 如果不再需要某个端点,可以通过调用Delete方法将其删除。
(7) 如果不再需要网络,可以通过调用Delete方法将其删除。
CNI模式
CNI(Conteinre Network Interface)是Google和CoreOS开发的容器网络标准。 它可以被理解为一个协议而不是一个实现或代码本身。 该标准是基于rkt网络提案制定的,并考虑了灵活性、可扩展性、IP分配、多网卡等因素。
该协议连接两个组件:容器管理系统和网络插件。 它通过 JSON 格式的文件进行通信,并为容器实现网络功能。 某些事情是通过插件来实现的,比如创建容器网络空间(网络命名空间)、将网络接口(接口)放置在相应的网络空间中、为网络接口分配IP等。
CNI 本身有一些基础插件(https://github.com/containern...、bridge、ipvlan、macvlan、loopback、vlan 等网络接口管理插件)。 dhcp、host-local等IP管理插件,以及主流容器网络解决方案,都有Flannel、Calico、Wea等CNI支持。ve、Contiv、SR-IOV、Amazon ECS CNI 插件等。
Flannel的具体分析可以看我之前的文章(K8s与网络--Flannel解读)。
评论前必须登录!
注册