网站首页 > 技术文章 正文
坚持原创,共同进步!请关注我,后续分享更精彩!!!
定义
我们知道,pod是k8s中一个最小的运行单元。Kubernetes Service 定义了一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 --- 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常通过 选择符( selector label)实现。
举个例子,考虑一个图片处理后端,它运行了 3 个副本实例。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端实例。 然而组成这一组后端程序的 Pod 实际上可能发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态。 Service 定义的抽象能够解耦这种关联。
service具有以下功能:
- 自动发现机制,监听service下pod的启动/停止状态;
- 提供单一DNS名称和service下pod集合ip地址映射;
- 负载均衡service下pod集合的网络访问。
通过以上定义我们发现:k8s中的service对象具有微服务的服务治理能力。服务的注册与发现,服务DNS名与服务实例ip的映射,服务的负载均衡流量分发。换句话说:service等同于springcloud体系下的eureka和Robbin组件。
本文将向大家分享service的三种proxy mode(代理模式),并重点演示ipvs的使用,希望对有需要的小伙伴有所帮助和参考。
kube-proxy mode
service的流量分发是通过kube-proxy组件代理工作的。分为三种模式:
- User space proxy mode
- iptables proxy mode
- IPVS proxy mode
User space proxy mode
这种模式,kube-proxy 会监视 Kubernetes 主控节点对 Service 对象和 Endpoints 对象的添加和移除操作。 对每个 Service,它会在本地 Node 上打开一个端口(随机选择)。 任何连接到“代理端口”的请求,都会被代理到 Service 的后端 Pods 中的某个上面。 使用哪个后端 Pod,是 kube-proxy 基于配置策略确定的。
最后,它配置 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP) 和 Port 的请求,并重定向到代理端口,代理端口再代理请求到后端Pod。
默认情况下,用户空间模式下的 kube-proxy 通过轮询算法(round robbin)选择后端。
iptables proxy mode
这种模式,kube-proxy 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会配置 iptables 规则,从而捕获到达该 Service 的 clusterIP 和端口的请求,进而将请求重定向到 Service 的一组后端中的某个 Pod 上面。 对于每个 Endpoints 对象,它也会配置 iptables 规则,这个规则会选择一个后端组合。
默认的策略是,kube-proxy 在 iptables 模式下随机选择一个后端。
使用 iptables 处理流量具有较低的系统开销,因为流量由 Linux netfilter 处理, 而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。
如果 kube-proxy 在 iptables 模式下运行,并且所选的第一个 Pod 没有响应, 则连接失败。 这与用户空间模式不同:在这种情况下,kube-proxy 将检测到与第一个 Pod 的连接已失败, 并会自动使用其他后端 Pod 重试。
IPVS proxy mode
在 ipvs 模式下,kube-proxy监视Kubernetes服务和端点,调用 netlink 接口创建 IPVS 规则, 并定期将 IPVS 规则与 Kubernetes 服务和端点同步。访问服务时,IPVS 将流量定向到后端Pod之一。
IPVS代理模式基于类似于 iptables 模式的 netfilter 挂钩函数, 但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。 与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。
IPVS提供了更多选项来平衡后端Pod的流量。 分别有:
- rr: round-robin
- lc: least connection (smallest number of open connections)
- dh: destination hashing
- sh: source hashing
- sed: shortest expected delay
- nq: never queue
说明:
要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前使 IPVS Linux 在节点上可用。
当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。
ipvs配置
基于以上三种kube-proxy mode介绍,我们知道ipvs方式性能扩展性最好。iptables在集群达到5000+节点时会存在性能瓶颈,而且只有随机一种负载均衡算法,无法灵活设置流量分发策略。
需要说明的是,ipvs代理模式是kubernetes 1.8后才引入的,所以,要使用ipvs模式,请确保k8s版本1.8+。
k8s中kube-proxy默认mode是iptables方式,要使用ipvs模式,需进行相应配置,保证Linux环境下ipvs内核模块可用,否则kube-proxy将自动退回到iptables代理模式运行。
这里以centos系统为例。
集群所有节点,centos开启ipvs
#查看是否加载
lsmod | grep ip_vs
#-----系统中已安装ipvs模块,请忽略以下步骤
#手动加载
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
#配置开机自加载
cat <<EOF>> /etc/rc.local
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod +x /etc/rc.d/rc.local
集群master节点,更改kube-proxy配置
kubectl edit configmap kube-proxy -n kube-system
# 找到如下部分内容并修改mode值
minSyncPeriod: 0s
scheduler: ""
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 127.0.0.1:10249
mode: "ipvs" # 加上这个
nodePortAddresses: null
#其中mode原来是空,默认为iptables模式,改为ipvs
#scheduler默认是空,默认负载均衡算法为轮询
#编辑完,保存退出
master节点,删除所有kube-proxy的pod,使修改生效
kubectl delete pod xxx -n kube-system
master节点,查看kube-proxy的pod日志
kubectl logs kube-proxy-xxx -n kube-system
# 有.....Using ipvs Proxier......即可
验证
如上图,k8s集群中有3个应用实例,其中一个dctl-ms-consumer-deployment消费端服务(一个实例);一个dctl-ms-provider-deployment生产者服务(二个实例),分别对应10.122.5.40、10.122.5.45两个实例ip地址。
消费者服务通过nodeport方式对外暴露3000端口,请求hello/world接口,通过服务名地址访问生产者服务。
浏览器请求消费者服务接口:
第一次请求:
等待几秒,第二次请求:
可以看到,返回结果分别对应不同的ip地址。默认round Robbin负载均衡生效。
注意:第二次请求时,需等待几秒,直接连续访问看不到ip变化。之所以这样,为提高性能,同一ip来源快速访问,会触发kube-proxy ipvs中的连接重用机制。
总结
本文介绍了k8s中service的服务治理能力、kube-proxy的三种代码模式,以及ipvs的设置方式。让我们了解了微服务的注册中心和负载均衡的另一替代方案。
个人能力所限,一些内容可能存在不完备之处,若有疏漏,请不吝指正!谢谢!
猜你喜欢
- 2024-10-12 Kong 优雅实现微服务网关鉴权,登录场景落地实战篇
- 2024-10-12 k8s安装与使用入门(k8s安装步骤)
- 2024-10-12 应用无损上下线(应用无损上下线怎么关闭)
- 2024-10-12 另一个Kubernetes(k8s)指南(kubernetesk8s怎么使用)
- 2024-10-12 Kubernetes 安全专家(CKS)必过心得
- 2024-10-12 深入理解K8S网络原理上(k8s网络解决方案)
- 2024-10-12 一次客户需求引发的K8S网络探究(基于客户需求)
- 2024-10-12 今天讲讲k8s的pod控制器及无状态和有状态
- 2024-10-12 k8s如何滚动升级应用(k8s升级组件方法)
- 2024-10-12 k8s基础知识之service类型(k8s的service类型)
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)