首页 > 其他分享 >k8s 网络模型

k8s 网络模型

时间:2023-08-12 10:04:53浏览次数:37  
标签:iptables 容器 Service IP 模型 网络 Pod k8s 数据包

容器网络通信模式

在Host模式中,各容器共享宿主机的根网络名称空间,它们使用同一个接口设备和网络协议栈,因此,用户必须精心管理共享同一网络端口空间容器的应用与宿主机应用,以避免端口冲突。
Bridge模式对host模式进行了一定程度的改进,在该模式中,容器从一个或多个专用网络(地址池)中获取IP地址,并将该IP地址配置在自己的网络名称空间中的网络端口设备上。于是,拥有独立、隔离的网络名称空间的各容器有自己独占的端口空间,而不必再担心各容器及宿主机间的端口冲突。

Bridge

Bridge是指Linux内核支持的虚拟网桥设备,它模拟的是物理网桥设备,工作于数据链路层,根据习得的MAC地址表向设备端口转发数据帧。虚拟以太网接口设备对(veth pair)是连接虚拟网桥和容器的网络媒介:一端插入到容器的网络栈中,表现为通信接口(例如eth0等),另一端则于宿主机上关联虚拟网桥并被降级为当前网桥的“从设备”,失去调用网络协议栈处理数据包的资格,从而表现为桥设备的一个端口

k8s 网络模型_IP

Linux网桥提供的是宿主机内部的网络,同一主机上的各容器可基于网桥和ARP协议完成本地通信。而在宿主机上,网桥表现为一个网络接口并可拥有IP地址,docker0会在docker daemon进程启动后被自动配置172.17.0.1/16的地址。于是,由宿主机发出的网络包可通过此桥接口送往连接至同一个桥上的其他容器,如图的Container-1或Container-2,这些容器通常需要由某种地址分配组件(IPAM)自动配置一个相关网络(例如72.17.0.0/16)中的IP地址。
但此私有网络中的容器却无法直接与宿主机之外的其他主机或容器进行通信,通常作为请求方,这些容器需要由宿主机上的iptables借助SNAT机制实现报文转发,而作为服务方时,它们的服务需要宿主机借助于iptables的DNAT规则进行服务暴露。

配置容器Bridge网络

1) 若不存在,则需要先在宿主机上添加一个虚拟网桥;
2)为每个容器配置一个独占的网络名称空间;
3)生成一对虚拟以太网接口(如veth pair),将一端插入容器网络名称空间,一端关联至宿主机上的网桥;
4)为容器分配IP地址,并按需生成必要的NAT规则。

跨主机bridge网络

尽管Bridge模型下各容器使用独立且隔离的网络名称空间,且彼此间能够互连互通,但跨主机的容器间通信时,请求报文会首先由源宿主机进行一次SNAT(源地址转换)处理,而后由目标宿主机进行一次DNAT(目标地址转换)处理方可送到目标容器,如图所示。这种复杂的NAT机制将会使得网络通信管理的复杂度随容器规模增呈成几何倍数上升,而且基于ipables实现的NAT规则,也限制了解决方案的规模和性能。

k8s 网络模型_NAT_02

Kubernetes 网络模型

集群中每一个 Pod 都会获得自己的、 独一无二的 IP 地址, 这就意味着你不需要显式地在 Pod 之间创建链接,你几乎不需要处理容器端口到主机端口之间的映射。 这将形成一个干净的、向后兼容的模型;在这个模型里,从端口分配、命名、服务发现、 负载均衡、 应用配置和迁移的角度来看,Pod 可以被视作虚拟机或者物理主机。
Kubernetes 强制要求所有网络设施都满足以下基本要求(从而排除了有意隔离网络的策略):
  Pod 能够与所有其他节点上的 Pod 通信, 且不需要网络地址转译(NAT)
  节点上的代理(比如:系统守护进程、kubelet)可以和节点上的所有 Pod 通信
说明:对于支持在主机网络中运行 Pod 的平台(比如:Linux), 当 Pod 挂接到节点的宿主网络上时,它们仍可以不通过 NAT 和所有节点上的 Pod 通信。

这个模型不仅不复杂,而且还和 Kubernetes 的实现从虚拟机向容器平滑迁移的初衷相符, 如果你的任务开始是在虚拟机中运行的,你的虚拟机有一个 IP, 可以和项目中其他虚拟机通信。这里的模型是基本相同的。

Kubernetes 的 IP 地址存在于 Pod 范围内 —— 容器共享它们的网络命名空间 —— 包括它们的 IP 地址和 MAC 地址。 这就意味着 Pod 内的容器都可以通过 localhost 到达对方端口。 这也意味着 Pod 内的容器需要相互协调端口的使用,但是这和虚拟机中的进程似乎没有什么不同, 这也被称为“一个 Pod 一个 IP”模型。

Kubernetes 网络解决四方面的问题

Pod内容器间通信

Pod是Kubernetes调度的原子单元,其内部的各容器必须运行在同一节点之上。一个Pod资源内的各容器共享同一网络名称空间,它通常由构建Pod对象的基础架构容器pause所提供。因而,同一个Pod内运行的多个容器通过本地回路(loopback)接口即可在本地内核协议栈上完成交互。

不同Pod间通信

各Pod对象需要运行在同一个平面网络中,每个Pod对象拥有一个虚拟网络接口和集群全局唯一的地址,该IP地址可用于直接与其他Pod进行通信。另外,运行Pod的各节点也会通过桥接设备等持有此平面网络中的一个IP地址,如图中的cni0接口,这意味着Node到Pod间的通信也可直接在此网络进行。因此,Pod间的通信或Pod到Node间的通信类似于同一IP网络中的主机间进行的通信。

k8s 网络模型_IP_03

Kubernetes设计了Pod通信模型,却把相关功能及编排机制的实现通过kubenet或CNI插件API开放给第三方来实现。这些第三方插件要负责为各Pod设置虚拟网络接口、分配IP地址并将其接入到容器网络中等各种任务,以实现Pod间的直接通信。

Service与Pod间的通信

Kubernetes Service 管理一组 Pod,允许你跟踪一组随时间动态变化的 Pod IP 地址,Service 作为对 Pod 的抽象,为一组 Pod 分配一个虚拟的 VIP 地址,任何发往 Service VIP 的流量都会被路由到与其关联的一组 Pod。这就允许与 Service 相关的 Pod 集可以随时变更 - 客户端只需要知道 Service VIP 即可。
创建 Service 时候,会创建一个新的虚拟 IP(也称为 clusterIP),这集群中的任何地方,发往虚拟 IP 的流量都将负载均衡到与 Service 关联的一组 Pod。实际上,Kubernetes 会自动创建并维护一个分布式集群内的负载均衡器,将流量分配到 Service 相关联的健康 Pod 上。

netfilter and iptables

为了在集群中执行负载均衡,Kubernetes 会依赖于 Linux 内置的网络框架 - netfilter。Netfilter 是 Linux 提供的一个框架,它允许以自定义处理程序的形式实现各种与网络相关的操作,Netfilter 为数据包过滤、网络地址转换和端口转换提供了各种功能和操作,它们提供了引导数据包通过网络所需的功能,以及提供禁止数据包到达计算机网络中敏感位置的能力。
iptables 是一个用户空间程序,它提供了一个基于 table 的系统,用于定义使用 netfilter 框架操作和转换数据包的规则。在 Kubernetes 中,iptables 规则由 kube-proxy 控制器配置,该控制器会 watch kube-apiserver 的变更,当对 Service 或 Pod 的变化更新了 Service 的虚拟 IP 地址或 Pod 的 IP 地址时,iptables 规则会被自动更新,以便正确地将指向 Service 的流量路由到支持 Pod。iptables 规则会监听发往 Service VIP 的流量,并且在匹配时,从可用 Pod 集中选择一个随机 Pod IP 地址,并且 iptables 规则将数据包的目标 IP 地址从 Service 的 VIP 更改为所选的 Pod IP。当 Pod 启动或关闭时,iptables 规则集也会更新以反映集群的变化状态。换句话说,iptables 已经在节点上做了负载均衡,以将指向 Service VIP 的流量路由到实际的 Pod 的 IP 上。
在返回路径上,IP 地址来自目标 Pod,在这种情况下,iptables 再次重写 IP 头以将 Pod IP 替换为 Service 的 IP,以便 Pod 认为它一直只与 Service 的 IP 通信。

IPVS

Kubernetes 新版本已经提供了另外一个用于集群负载均衡的选项:IPVS, IPVS 也是构建在 netfilter 之上的,并作为 Linux 内核的一部分实现了传输层的负载均衡。IPVS 被合并到了 LVS(Linux 虚拟服务器)中,它在主机上运行并充当真实服务器集群前面的负载均衡器,IPVS 可以将基于 TCP 和 UDP 的服务请求定向到真实服务器,并使真实服务器的服务作为虚拟服务出现在一个 IP 地址上。这使得 IPVS 非常适合 Kubernetes 服务。
这部署 kube-proxy 时,可以指定使用 iptables 或 IPVS 来实现集群内的负载均衡。IPVS 专为负载均衡而设计,并使用更高效的数据结构(哈希表),与 iptables  相比允许更大的规模。在使用 IPVS 模式的 Service 时,会发生三件事:在 Node 节点上创建一个虚拟 IPVS 接口,将 Service 的 VIP 地址绑定到虚拟 IPVS 接口,并为每个 Service VIP 地址创建 IPVS 服务器。

Pod 到 Service 通信

k8s 网络模型_NAT_04

1. 数据包首先通过 Pod 的 eth0 网卡发出
2. 数据包经过虚拟网卡 veth0 到达网桥 cbr0
3. 网桥上的 APR 协议查找不到该 Service,所以数据包被发送到 root namespace 中的默认路由 - eth0
4. 此时,在数据包被 eth0 接受之前,数据包将通过 iptables 过滤。iptables 使用其规则(由 kube-proxy 根据 Service、Pod 的变化在节点上创建的 iptables 规则)重写数据包的目标地址(从 Service 的 IP 地址修改为某一个具体 Pod 的 IP 地址)
5. 数据包现在的目标地址是 Pod 4,而不是 Service 的虚拟 IP 地址。iptables 使用 Linux 内核的 conntrack 工具包来记录具体选择了哪一个 Pod,以便可以将未来的数据包路由到同一个 Pod。简而言之,iptables 直接在节点上完成了集群内负载均衡的功能。数据包后续如何发送到 Pod 上,

Service 到 Pod 通信

k8s 网络模型_IP_05

1. 接收到此请求的 Pod 将会发送返回数据包,其中标记源 IP 为接收请求 Pod 自己的 IP,目标 IP 为最初发送对应请求的 Pod 的 IP
2. 当数据包进入节点后,数据包将经过 iptables 的过滤,此时记录在 conntrack 中的信息将被用来修改数据包的源地址(从接收请求的 Pod 的 IP 地址修改为 Service 的 IP 地址)
3. 然后,数据包将通过网桥、以及虚拟网卡 veth0
4. 最终到达 Pod 的网卡 eth0

集群外部客户端与Pod对象的通信

出站流量

1. 数据包从 Pod 的 network namespace 发出
2. 通过 veth0 到达虚拟机的 root network namespace
3. 由于网桥上找不到数据包目标地址对应的网段,数据包将被网桥转发到 root network namespace 的网卡 eth0。在数据包到达 eth0 之前,iptables 将过滤该数据包。
4. 在此处,数据包的源地址是一个 Pod,如果仍然使用此源地址,互联网网关将拒绝此数据包,因为其 NAT 只能识别与节点(虚拟机)相连的 IP 地址。因此,需要 iptables 执行源地址转换(source NAT),这样子,对互联网网关来说,该数据包就是从节点(虚拟机)发出的,而不是从 Pod 发出的
5. 数据包从节点(虚拟机)发送到互联网网关
6. 互联网网关再次执行源地址转换(source NAT),将数据包的源地址从节点(虚拟机)的内网地址修改为网关的外网地址,最终数据包被发送到互联网
在回路径上,数据包沿着相同的路径反向传递,源地址转换(source NAT)在对应的层级上被逆向执行。

k8s 网络模型_Pod_06

入站流量

引入集群外部流量到达Pod对象有4种方式,有两种是基于本地节点的端口(nodePort)或根网络名称空间(hostNetwork),另外两种则是基于工作在集群级别的NodePort或LoadBalancer类型的Service对象。不过,即便是四层代理的模式也要经由两级转发才能到达目标Pod资源:请求流量首先到达外部负载均衡器,由其调度至某个工作节点之上,而后再由工作节点的netfilter(kube-proxy)组件上的规则(iptables或ipvs)调度至某个目标Pod对象。

标签:iptables,容器,Service,IP,模型,网络,Pod,k8s,数据包
From: https://blog.51cto.com/wangguishe/7056437

相关文章

  • 网络传输数据的编解码
    网络传输数据的类型(二进制)网络传输是以二进制数据进行传输的,因此在网络传输数据的时候,数据需要先编码转化为二进制(bytes)数据类型数据的编解码 在Python中进行网络数据传输编解码通常涉及到将数据转换为字节流进行传输,并在接收方将字节流转换回原始数据。编码编码是将数据......
  • golang网络编程
    1简介Go语言的网络编程主要使用net包来实现。该包提供了一组基本的网络功能,包括TCP和UDP套接字、IP地址和端口号的处理、以及一些高级特性,如非阻塞I/O和HTTP客户端库。本文简单介绍一下如何使用net包进行TCP通信2TCP通信TCP服务端处理流程:监听端口接收......
  • k8s实战案例之运行dubbo微服务
    1、dubbo微服务架构图通过上述架构可以了解到,生产者通过注册中心,将服务注册至注册中心,消费者通过注册中心找到生产者,从而实现消费者拿到生产者的实际地址,然后直接和生产者通信;管理端通过注册中心发现生产者和消费者,通过svc来管理生产者和消费者;集群外部客户端通过负载均衡器来......
  • R语言中贝叶斯网络(BN)、动态贝叶斯网络、线性模型分析错颌畸形数据|附代码数据
    最近我们被客户要求撰写关于贝叶斯网络的研究报告,包括一些图形和统计输出。贝叶斯网络(BN)是一种基于有向无环图的概率模型,它描述了一组变量及其相互之间的条件依赖性。它是一个图形模型,我们可以很容易地检查变量的条件依赖性和它们在图中的方向在这篇文章中,我将简要地学习如何用R来......
  • 拓端数据tecdat|R语言代写通过WinBUGS对MGARCH和MSV模型进行贝叶斯估计和比较
    多变量广义自回归条件异方差(MGARCH)和多变量随机波动率(MSV)模型与马尔可夫链蒙特卡罗方法的贝叶斯估计和比较可以直接和成功地在WinBUGS包中进行。经济全球化和金融市场的完整性促进了对资产定价,风险管理,投资组合选择等各个领域的多元波动建模的需求。因此,两种类型的模型-多变量广......
  • R语言结构方程模型SEM、路径分析房价和犯罪率数据、预测智力影响因素可视化2案例|附代
    原文链接:http://tecdat.cn/?p=25044原文出处:拓端数据部落公众号最近我们被客户要求撰写关于结构方程模型的研究报告,包括一些图形和统计输出。1简介在本文,我们将考虑观察/显示所有变量的模型,以及具有潜在变量的模型。第一种有时称为“路径分析”,而后者有时称为“测量模型”。......
  • R语言预测人口死亡率:用李·卡特(Lee-Carter)模型、非线性模型进行平滑估计|附代码数据
    全文链接:http://tecdat.cn/?p=13663最近我们被客户要求撰写关于预测人口死亡率的研究报告,包括一些图形和统计输出。今天早上,我和同事一起分析死亡率。我们在研究人口数据集,可以观察到很多波动性我们得到这样的结果:  由于我们缺少一些数据,因此我们想使用一些广义非线性模......
  • 大模型时代的程序员:不会用AIGC编程,未来5年将被淘汰?
    作者|郭炜策划|凌敏前言下面是一段利用Co-Pilot辅助开发的小视频,这是ApacheSeaTunnel开发者日常开发流程中的一小部分。如果你还没有用过Co-Pilot、ChatGPT或者私有化大模型帮助你辅助开发的话,未来的5年,你可能很快就要被行业所淘汰。因为这些善于使用AIGC辅助编......
  • 【Sword系列】第七届全国残疾人职业技能大赛样题-网络安全-被黑了,求密码
    前言摩尔斯电码(Morsecode)也被称作摩斯密码,是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母、数字和标点符号。它发明于1837年,是一种早期的数字化通信形式。不同于现代化的数字通讯,摩尔斯电码只使用零和一两种状态的二进制代码,它的代码包括五种:短促的点信号“・......
  • 一文详解Apipost数据模型功能
    在Apipost数据模型中用户可以预先创建多个数据模型,并在API设计过程中重复利用这些模型来构建API创建数据模型在左侧导航点击「数据模型」-「新建数据模型」在右侧工作台配置数据模型参数引入数据模型在API设计预定义响应期望下点击引用数据模型,并选择需要导入的数据模型即可将创建......