1. Network
docker 有四种网络模式:
none :
容器有独立的 Network namespace.
将容器添加到一个容器专门的网络堆栈中,没有对外连接。
只能使用 loopback 网络设备,容器只能使用 127.0.0.1 的本机网络。
host :
此网络驱动直接使用宿主机的网络
将容器添加到主机的网络堆栈中,没有隔离
容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。
bridge :
为每一个容器分配 IP ,并将容器连接到一个 docker0 虚拟网桥
自定义网桥 :
用户自定义网桥,有更多的灵活性、隔离性等。
Network plugins :
可以安装和使用第三方的网络插件
CNI(container network interface) CNCF下的一个项目,由coreOS提出
通过插件的方式统一配置:
flannel : 基于overlay 不支持网络策略
calico : 基于BGP 支持网络策略
canal : 支持网络策略
通过给 Kubelet 传递 CNI 选项:
–network-plugin=cni 命令行选项来选择 CNI 插件。
–cni-conf-dir (默认是 /etc/cni/net.d) 读取文件并使用该文件中的 CNI 配置来设置每个 pod 的网络。
–cni-bin-dir (默认是 /opt/cni/bin)配置引用的任何所需的 CNI 插件都必须存在于该目录下。
各种解决方案对比如下:
特性/方案 | FLANNEL | CALICO | MACVLAN | OPENVSWITCH | 直接路由 |
---|---|---|---|---|---|
方案特性 | 通过虚拟设备 flannel0 实现对 docker0 的管理 | 基于 BGP 协议的纯三层的网络方案 | 基于 Linux Kernel 的 macvlan 技术 | 基于隧道的虚拟路由技术 | 基于 Linux Kernel 的 vRouter 技术 |
对底层网络的要求 | 三层互通 | 三层互通 | 二层互通 | 三层互通 | 二层互通 |
配置难易度 | 简单,基于 etcd | 简单,基于 etcd | 简单,直接使用宿主机网络,需要仔细规划IP地址范围 | 复杂,需要手工配置各个节点的bridge | 简单,使用宿主机 vRoute 功能,需要仔细规划每个node的IP地址范围 |
网络性能 | host-gw > Vxlan > UDP | BGP 模式性能损失小,IPIP模式较小 | 性能损失可忽略 | 效能损失较小 | 性能损失小 |
网络连通性限制 | 无 | 在不支持 BGP 协议的网络环境中无法使用 | 基于 macvlan 的容器无法与宿主机网络通信 | 无 | 在无法实现大二层互通的网络环境下无法使用 |
Flannel 网络原理
Flannel 简介
Flannel 是 CoreOS 团队针对 Kubernetes 设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。
Flannel 实质上是一种覆盖网络(overlaynetwork)。
overlay 覆盖网络:
也就是将 TCP 数据包装在另一种网络包里面进行路由转发和通信
在基础网络的基础上叠加的一种虚拟网络技术模式,该网络的主机通过虚拟链路连接起来。
flannel 网络特点
Flannel 网络特点有:
全集群唯一的虚拟 IP 地址。
建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装。
创建一个新的虚拟网卡 flannel0 接收 docker0 网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)。
etcd
Flannel是 CoreOS 团队针对 Kubernetes 设计的一个覆盖网络(Overlay Network)工具:
目的在于帮助每一个使用 Kuberentes 的 CoreOS 主机拥有一个完整的子网。
功能是让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟IP地址。让所有的容器相当于在同一个直连的网络,底层通过 UDP/VxLAN等进行报文的封装和转发。
其中,Overlay Network:是覆盖网络,在基础网络的基础上叠加的一种虚拟网络技术模式,该网络的主机通过虚拟链路连接起来。
VXLAN:将原数据包包装在 UDP 中,并使用基础网络的 IP/MAC 作为外层报文头进行封装,然后在以太网上传输,到达目的地后由隧道端点解封并将数据发送给目标地址。其中,VXLAN网络结构如下:
Flannel:是 Overlay Network 的一种,也是将原数据包封装在另一种网络包里面进行的路由转发和通信,目前已经支持 UDP、VXLAN、AWS VPC和GCE路由数据转发方式。
具体的通信流程,不同物理节点上的容器通信流程:
node1 节点的 容器 container1 产生数据,根据 容器的路由表,将数据发送给 cni0
Cni0 : 网桥设备,也就是 docker0 网桥,每创建一个 容器 都会创建一对 veth pair。其中一端是 容器 中的 eth0,另一端是 docker0 网桥中的端口(网卡)。容器 中从网卡 eth0 发出的流量都会发送到 docker0 网桥设备的端口(网卡)上。
Cni0 根据节点的路由表,将数据发送到隧道设备 flannel0
Flannel0: overlay 网络的设备,用来进行 vxlan 或其他方式 报文的处理(封包和解包)。不同 node 之间的 pod 数据流量都从 overlay 设备以隧道的形式发送到对端。
Flannel0 查看数据包的目的 ip,从 flanneld 获得对端隧道设备的必要信息,封装数据包。
Flanneld:flannel 在每个主机中运行 flanneld 作为 agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的 IP 地址都将从中分配。同时 Flanneld 监听 etcd 数据库,为 Flannel0 设备提供封装数据时必要的 mac,ip 等网络数据信息。
Flanneld 将数据包通过本机网卡发送到对端设备。对端节点的网卡接收到数据包,发现数据包为 overlay 数据包,解开外层封装,并发送内层封装到flanneld 设备。
Flannel0 设备查看数据包,根据路由表匹配,将数据发送给 Cni0 设备。
Cni0 匹配路由表,发送数据给网桥上对应的端口。
注意:
Flannel 配置第三层 IPv4 Overlay 网络,会创建一个大型内部网络,并且跨越集群中的每个节点
在 Overlay 网络中,每个节点都有个子网 subnet ,用于给容器分配ip地址
同一主机中的 容器可以使用 docker0 直接通信,而不同主机上的容器需要使用 flanneld 进行封装在传输。
其中,一个具体的例子,Flannel 网络结构如下:
上图表示:
数据从源容器 cache1 container 中(IP地址为10.1.15.2)发出后,经由所在主机的 Docker0 虚拟网卡转发到 flannel0 虚拟网卡,这是个 P2P 的虚拟网卡,flanneld 服务监听在网卡的另外一端。
Flannel 通过 Etcd 服务维护了一张节点间的路由。
源主机的 flanneld 服务将原本的数据内容 UDP 封装后根据自己的路由表投递给目的节点的 flanneld 服务,数据到达以后被解包,然后直 接进入目的节点的 flannel0 虚拟网卡,然后被转发到目的主机的 Docker0 虚拟网卡,最后就像本机容器通信一下的有 Docker0 路由到达目标容器 backend1 container (IP地址为10.1.20.3)。
可以直接使用 flannel 的 yaml 文件,在 kubernentes 中一键安装。
5. Calico 网络原理
5.1
calico 是完全利用路由规则实现动态组网,通过 BGP 协议通告路由。
5.2 Calico 原理
Calico 原理:
每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播——小规模部署可以直接互联,大规模下可通过指定的 BGP route reflector 来完成。
保证最终所有的 workload 之间的数据流量都是通过 IP 路由的方式完成互联的。
Calico 节点组网可以直接利用数据中心的网络结构(无论是 L2 或者 L3),不需要额外的 NAT,隧道或者 Overlay Network。
5.3 Calico 组网
组网示意图:
注意:
calico 组网的核心原理就是 IP 路由,每个容器或者虚拟机会分配一个 workload-endpoint(wl)。
endpoint : 接入到 calico 网络中的网卡称为 endpoint
workload-Endpoint : 虚拟机、容器使用的 endpoint
从容器 ConA 中发送给 ConB 的报文被 nodeA 的 wl-A 接收,根据 nodeA 上的路由规则,经过各种 iptables 规则后,转发到nodeB。
如果 nodeA 和 nodeB 在同一个二层网段,下一条地址直接就是 node-B,经过二层交换机即可到达。
如果 nodeA 和 nodeB 在不同的网段,报文被路由到下一跳,经过三层交换或路由器,一步步跳转到 node-B。
5.4 Calico 安装配置
5.4.1 搭建 etcd 集群
安装 etcd
- 两台 etcd 集群,分别装有 docker
yum install -y etcd
启动 etcd 集群
systemctl start etcd
配置 docker 的存储为 etcd , 在两个节点上 修改 docker 启动选项,添加:(配置为自己的etcd节点)
5.4.2 安装配置 calico
在两个节点上修改 calico 的配置
创建 calico 容器,用来进行两个物理节点上容器的互通, 在所有节点上执行
下载安装 calicoctl, 地址:
curl -O -L https://github.com/projectcalico/calicoctl/releases/download/v3.16.3/calicoctl
添加可执行权限:
chmod +x calicoctl
建立 calico node 的容器,容器镜像为:quay.io/calico/node
创建 docker 网络,在任意主机上创建网络(可以同步给远端)
--driver calico
指定使用calico 的 libnetwork CNM driver。--ipam-driver calico-ipam
指定使用 calico 的IPAM driver 管理IP。
在 vms91 上创建一个容器 :
docker run --name c91 --net calnet1 -itd busybox
在 vms92 上创建一个容器 :
docker run --name c92 --net calnet1 -itd busybox
当创建一个busybox 容器后,在容器中 和 在 物理机中都多了一张网卡
在容器中的网卡名称为:6: cali0@if7
在物理机中的网卡名称为:7: calif6391d136be@if6
可以看到:
物理机网卡的序号 7 与 容器网卡的 @if7 对应
物理机网卡的 @if6 与 物理机网卡的 序号6 对应
建立了 veth pair 关系,详细:https://www.cnblogs.com/bakari/p/10613710.html
在容器中的路由表 route -n,可以看到,所有的数据包的默认网关是 cali0 网卡
在物理集中查看路由表 route -n, 可以看到,
凡是去往本机容器中的地址的数据包,默认网卡是 calif6391d136be
凡是去往其他物理机中容器地址的数据包,默认网卡都是 本机的网卡出去
也就是说,在calico的节点上,通过egb协议,相互学习路由
评论