k8s service 负载均衡:proxy mode介绍
定义
我们知道,pod是k8s中一个最小的运行单元。Kubernetes Service 定义了一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 --- 通常称为微服务。这一组 Pod 能够被 Service 访问到,通常通过 选择符( selector label)实现。
举个例子,考虑一个图片处理后端,它运行了 3 个副本实例。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端实例。然而组成这一组后端程序的 Pod 实际上可能发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态。Service 定义的抽象能够解耦这种关联。
service具有以下功能:
自动发现机制,监听service下pod的启动/停止状态;
负载均衡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......即可
验证
浏览器请求消费者服务接口:
第一次请求:
等待几秒,第二次请求:
注意:第二次请求时,需等待几秒,直接连续访问看不到ip变化。之所以这样,为提高性能,同一ip来源快速访问,会触发kube-proxy ipvs中的连接重用机制。
总结
本文介绍了k8s中service的服务治理能力、kube-proxy的三种代码模式,以及ipvs的设置方式。让我们了解了微服务的注册中心和负载均衡的另一替代方案。
柯普瑞企业IT学院
企业使命:
为员工创造价值,为客户创造价值,为社会创造价值,为推动全社会进步而努力!
企业愿景:
成为中国一流的企业IT人才培养解决方案提供商!
南京校区:南京市中山东路300号
长发中心A栋23楼
杭州校区:杭州市下城区东方茂
商业中心2幢6层
学院网址:www.china-esp.com
Welcome to you
扫码点击关注