惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AI
AI
NISL@THU
NISL@THU
AWS News Blog
AWS News Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Privacy & Cybersecurity Law Blog
S
Schneier on Security
PCI Perspectives
PCI Perspectives
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Troy Hunt's Blog
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
Know Your Adversary
Know Your Adversary
F
Fortinet All Blogs
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
Jina AI
Jina AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Vulnerabilities – Threatpost
P
Privacy International News Feed
T
Tor Project blog
S
Security Affairs
S
Securelist
F
Full Disclosure
D
Docker
酷 壳 – CoolShell
酷 壳 – CoolShell
Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
SecWiki News
SecWiki News
P
Palo Alto Networks Blog
Apple Machine Learning Research
Apple Machine Learning Research
N
News and Events Feed by Topic
Recorded Future
Recorded Future
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
Stack Overflow Blog
Stack Overflow Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
I
Intezer
Security Latest
Security Latest
Scott Helme
Scott Helme
U
Unit 42
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念 软件版本语义化
Kubernetes Networking Model & CNI
2024-01-12 · via 蛮荆

2024-01-12 Cloud Native Kubernetes 计算机网络

概述

Kubernetes 提出了一个简单且简洁的网络模型: “IP - per - Pod”, 可以很好地满足集群中跨主机通信和从传统虚拟机向容器云原生平滑迁移的功能需求。 根据 Kubernetes 的网络模型语义设计,每一个 Pod 可以被认为是一个物理机或虚拟机。

模型语义

  • 集群中每个 Pod 都有独立的一个 IP 地址
  • 每个 Pod 中的所有容器共享该 Pod 的 IP 地址,每个容器通过 localhost + 端口 访问其他容器 (所以这也就是为什么 Pod 内部容器端口会冲突的原因)
  • 集群中任意两个 Pod 可以直接通信,而且无需 NAT (网络地址转换)
  • 每个 Node 上的代理(例如: 系统守护进程、kubelet)可以和该 Node 上的所有 Pod 直接通信
  • 集群中的所有 Pod 都处于同一 IP 网段

图片来源: kubernetes.io/docs

模型网络问题

要实现上述的网络模型语义,Kubernetes 要解决 4 个方面的问题:

  1. 每个 Pod 中的所有容器直接通信 (通过每个 Pod 内部的 Pause 容器实现)
  2. Pod 和 Pod 通信 (通过 CNI 接口插件解决,所有 Pod 处于一个没有 NAT 转换的扁平地址空间中,例如 172.16.0.0/24 网段中)
  3. Pod 和 Service 通信,通过为 Service 定义 Cluster IP (虚拟 IP), 然后在每个 Node 运行一个 kube-proxy 进程,该进程会编写对应的流量重定向规则 (例如 iptables, ipvs),将访问流量重定向到正确的 Pod 中
  4. 集群外部到内部的通信,典型的方式是通过集群外部的 LoadBalancer (负载均衡) 来实现的

IP 地址分配

根据 Kubernetes 网络模型的语义,整个集群都处于同一 IP 网段,所以 Kubernetes 还定义了 CIDR(Classless Inter-Domain Routing)网络寻址方案,用于定义和划分 IP 地址范围。 每个集群都有一个 CIDR 地址范围,通过指定一个 IP 地址和子网掩码来定义的,例如 10.0.0.0/16 表示一个 CIDR 范围,其中 10.0.0.0 是起始 IP 地址,/16 表示使用了 16 位的子网掩码。

通过 CIDR 地址范围,Kubernetes 可以管理集群中需要 IP 地址的所有对象资源,具体来说:

  • CNI (容器网络接口) 为 Pod 分配 IP 地址
  • kube-apiserver 为 Service 分配 IP 地址
  • kubelet 或 cloud-controller-manager 为 Node 分配 IP 地址

下面展示一个 CIDR 为 10.50.6.0/24 的 Node 和一个 IP 为 10.50.6.20 的 Pod。

图片来源: kubernetes.io/docs


CNI

如何实现上文中提到的 Kubernetes 网络模型中和 Pod 相关的部分呢?

最常见的方式是 CRI (容器运行时接口) 使用 CNI (容器网络接口) 插件来管理其网络和安全能力, CNI 定义了一系列协议接口,用来管理网络插件,开发者只需实现接口就可以接入 Kubernetes 网络管理能力,实现为 Pod 创建虚拟网卡、为 Pod 分配 IP 地址等网络功能,实现 “IP - per - Pod” 网络模型。

CNI 接口代码定义

根据接口的定义可以看到,CNI 的主要工作是从 CRI 获取容器运行时相关信息,再从容器网络配置文件中获取配置信息,然后将信息传递给对应的插件,由插件执行具体的配置工作并将结果返回到 CRI。

为什么需要 CNI ?

容器和容器网络方案都在不断更新和发展当中,同时还有新的开源方案不断涌现,如果每出现新的容器网络方案时,都需要将其和已有容器兼容适配,那么必然存在大量的重复和无必要工作, 这时候就需要一个标准化的协议接口,用来约束不断发展衍生的容器网络方案,不管后者如何变化,只要其实现并满足 CNI 接口,也就可以兼容已有的所有容器。

CNI 网络类型

图片来源: https://www.digitaltut.com/vxlan-tutorial

Overlay

构建在另一个真实的计算机网络上面的 “虚拟网络”,在数据包的传输过程中,发送方的底层网络会进行封包操作,接收方的底层网络会进行拆包操作,当然,这些操作对通信双方来说都是透明的。

Overlay 网络的优点在于对网络环境没有特殊要求,利用底层网络组成 “虚拟网络” 有很好的适配性,缺点是封包和拆包会带来额外的开销,所以性能较低。

Route

基于路由的容器网络类型,不会创建任何 “虚拟网络” 或桥接设备,而是直接在底层网络配置容器的路由规则。Route 网络类型利用操作系统的网络命名空间和路由表功能, 为每个容器创建一个独立的网络命名空间,使容器可以直接访问节点上的其他容器,也可以通过路由表转发到其他节点的容器。

Route 优点是不存在封包和拆包会带来额外的开销,性能比 Overlay 模式要高,缺点是是依赖于底层网络。

Underlay

直接使用底层网络技术 (物理网络或虚拟化基础设施的网络) 来实现 CNI, 也就是说 Pod 和宿主机都处于同一个网络中,两者之间是平等的,优点是性能很高,缺点是依赖于底层网络和基础设施。

CNI 功能组件分类

CNI 插件可以分类以下三种类型,每种插件负责完成不同的工作。

IPAM (IP address allocation)

负责为 Pod 分配 IP 地址,支持以下分配方式:

  • DHCP : 发起 DHCP 协议请求为容器申请 IP 地址
  • host-local: 在本地维护已分配的 IP 数据库,使用预先配置的 IP 地址段来进行分配
  • static: 申请静态 IP 地址

Meta: other plugins

由 CNI 社区维护的内置 CNI 插件,不能作为独立的插件使用,需要调用其他插件。

  • tuning: 基于 sysctl 调整网络设备参数的二进制文件
  • portmap: 基于 iptables 配置端口映射的二进制文件,将端口从主机地址空间映射到容器
  • bandwidth: 基于 Token Bucket Filter (TBF) 来进行限流的二进制文件
  • firewall: 防火墙插件,使用 iptables 或 firewalld 添加规则来管理容器的出入流量

Main: interface-creating

负责创建具体网络设备的二进制文件,支持创建如下类型的设备:

  • bridge: 创建一个网桥,向其中添加主机和容器 (例如 Flannel 创建的名称为 cni0, 类似 Docker 创建的 docker0 虚拟网桥)
  • ipvlan: 向容器中添加 ipvlan 接口
  • loopback: 设置本地虚拟环回设备 (通常指 127.0.0.1)
  • macvlan: 创建一个 MAC 地址,将所有流量转发到容器
  • ptp: 创建一对 veth pair
  • vlan: 分配 vlan 设备
  • host-device: 将已有设备移动到容器中
  • dummy: 在容器中创建一个新的虚拟设备

CNI 开源实现

开源社区主流的 CNI 实现包括:Flannel、Calico、Weave、Cilium 等,每个插件都有不同的网络拓扑和特性,选择时需要考虑集群的资源需求和运维限制。

Flannel

Flannel 简单易用,是 Kubernetes 里最流行的 CNI 插件,通过 VXLAN (也可以通过 UDP 替换) 实现了 Overlay 网络模式,通过 Host-Gateway 实现了 Route 网络模式。 Flannel 仅控制流量如何在各个主机之间传输,且性能要低于 Calico 和 Cilium。

图片来源: https://www.tkng.io/cni/flannel/

Calico

Calico 是一个基于 BGP 的纯三层的数据中心网络方案,实现了 Route 网络模式 (不需要 Overlay),支持多种网络策略,kube-proxy 替换、网络安全策略、网络流量可观测性等功能。

实现方式: 通过创建 veth 链接并将该链接的一侧连接到 Pod 的命名空间中,另一侧连接到节点的根命名空间中 (例如 bridge)。这样对于节点的每个 Pod,Calico 都会针对 Pod IP 设置一条指向 veth 链路的路由。

图片来源: https://www.tkng.io/cni/calico/

Cilium

Cilium 是性能最高的 CNI 插件,通过使用 Linux eBPF 直接在内核操作网络数据,可以灵活实现各种功能,同时支持 Overlay 网络模式和 Route 网络模式。

Cilium 可以实现基于各种网络策略的流量过滤、CNI、kube-proxy 替换等功能,相比其他功能,CNI 反而是 Cilium 最不重要的功能。

实现方式: 通过创建 veth 链接并将该链接的一侧连接到 Pod 的命名空间中,另一侧连接到位于节点的根命名空间中 (例如 bridge)。Cilium 将 eBPF 程序附加到这些链路的入口 TC 钩子函数,以拦截所有传入的数据包并进行处理, 大部分网络连接和转发是在 eBPF 程序内执行的。

图片来源: https://www.tkng.io/cni/cilium/

Reference

扩展阅读