一文带你深入理解Kubernetes Service

一文带你深入理解Kubernetes Service

点击关注👉 云原生运维圈 2023-09-26 07:00 发表于上海

图片

为什么需要Service这种资源

在介绍Service之前,我们需要知道在Kubernetes中,Pod是最小的可部署单元。一个Pod可以包含一个或多个容器,并且共享网络命名空间和存储卷。Deployment则定义了如何创建和更新Pod副本的规则。使用Deployment,你可以轻松地管理Pod的生命周期,并确保所有的Pod都处于所需的状态。

但是,仅仅部署Pod还不足以满足大多数应用程序的需求。通常,要将请求路由到一组Pod,需要将它们暴露给外部服务。以及每个Pod都会分配一个单独的Pod IP,然后却存在如下两个问题:

  • Pod IP会随着Pod的重建,导致IP地址经常变化
  • Pod IP仅仅是集群内可见的虚拟IP,外部无法访问

所以我们需要Service资源去解决这些问题,以便于适应更多的实际场景。Kubernetes提供了Service资源,Service会对提供同一个服务的多个Pod进行聚合(Label标签)并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的Pod服务。

什么是Service?

在Kubernetes中,Service是一组Pod的抽象,为它们提供了稳定的DNS名称和IP地址。通过Service,你可以将请求路由到一组具有相同标签的Pod,并通过负载均衡将流量分配到这些Pod之间。这样,即使Pod的IP地址和端口号发生变化,Service也可以确保请求始终能够到达正确的Pod。

Kuberetes Service有三种类型:

  • ClusterIP:将Service暴露给集群内部,只能通过ClusterIP访问。
  • NodePort:将Service暴露给集群外部,可以通过NodeIP和NodePort访问
  • LoadBalancer:将Service暴露给云提供商的负载均衡,可以通过外部IP和端口号访问。

另外,Kubernetes Service还提供了许多其他功能,例如:

  • 健康检查:Service可以定期检查后端Pod的健康状态,并自动将流量路由到健康的Pod上。
  • 多版本管理:通过给不同版本的Pod打上标签,可以轻松地对不同版本的服务进行管理和升级。
  • 网格路由:与Istio等服务网购解决方案集成,可以实现基于请求内容和策略的高级路由功能。

综上所述,Kubernetes Service是构建可伸缩、高可用、弹性和可靠的微服务应用程序的必要组件。通过使用Service,你可以轻松地管理和扩展应用程序的网络层,并确保它们始终处于可用状态。

Service的核心组件Kube-Proxy

在Kubernetes中,Service是一种抽象概念,它为一组Pod提供了一个统一的访问入口,从而实现了对底层Pod的解耦。而Kube-Proxy则是Kubernetes系统中用于实现Service的核心组件之一。

Kube-Proxy是Kubernetes中的一个网络代理组件,它运行在集群的每个节点上,并且Service对象提供了一个单一的入口。它的工作原理是通过监听Kubernetes Api  Server上的Service和Endpoint对象的变化,然后启动地配置Iptables规则或IPVS规则,来将请求负载均衡到对应的Pod上。因此,可以说Kube-Proxy是Service与Pod之间的桥梁,它通过维护网络规则、负载均衡扽方式,实现了Service和后端Pod之间的联系和通信。

此外,Kube-Proxy还支持三种代理模式:UserSpace、Iptables和IPVS。默认情况下,它使用iptables模式,但可以通过命令行参数或Kube-Poryx配置文件来选择其他模式。

UserSpace模式

Kube-Proxy使用的第一代模式,该模式在 Kubernetes v1.0 版本开始支持使用。UserSpace 模式的实现原理图示如下:

图片

Kube-Proxy会为每个Service随时监听一个端口(Proxy Port),并增加一条Iptables规则。所以通过ClusterIP:Port访问Service的报文都 redirect 到 proxy port,kube-proxy 从它监听的 proxy port 收到报文以后,走 round robin(默认) 或是 session affinity(会话亲和力,即同一 client IP 都走同一链路给同一 pod 服务),分发给对应的 pod。

由于 userspace 模式会造成所有报文都走一遍用户态(也就是 Service 请求会先从用户空间进入内核 iptables,然后再回到用户空间,由 kube-proxy 完成后端 Endpoints 的选择和代理工作),需要在内核空间和用户空间转换,流量从用户空间进出内核会带来性能损耗,所以这种模式效率低、性能不高,不推荐使用。

图片

Iptables模式

Kube-Proxy使用的第二代模式,该模式在Kubernetes v1.1版本开始支持,从V1.2版本开始成为Kube-Proxy的默认模式。

Iptables模式的负载均衡模式是通过底层 netfilter/iptables 规则来实现的,通过 Informer 机制 Watch 接口实时跟踪 Service 和 Endpoint 的变更事件,并触发对 iptables 规则的同步更新。

Iptables模式的实现原理图示如下:

图片

通过图示我们可以发现在Iptables模式下,Kube-Proxy只是作为Controller,而不是Server,真正服务的是内核的Netfilter,体现在用户态的是Iptables。所以整体的效率会比UserSpace模式高。

图片

IPVS模式

Kube-Proxy第三代模式,模式在Kubernetes v1.8版本开始引入,在v1.9版本中处于beta阶段,在v1.11版本中正式开始使用。

IPVS(IP Virtual Server)实现了传输层负载均衡,也就是4层交换,作为Linux内核的一部分。IPVS运行在主机上,在真实服务器前充当负载均衡器。IPVS可以将基于TCP和UDP的服务请求转发到真实的服务上,并使真实服务器上的服务在单个IP地址上显示为虚拟服务。

IPVS模式的实现原理图示如下:

图片图片

IPVS和Iptables都是基于 netfilter 的,那么 ipvs 模式有哪些更好的性能呢?

  • ipvs为大型集群提供了更好的可拓展性和性能
  • ipvs支持比iptables更复杂的负载均衡算法(包括:最小负载、最少连接、加权等)
  • ipvs 支持服务器健康检查和连接重试等功能
  • 可以动态修改 ipset 的集合,即使 iptables 的规则正在使用这个集合

IPVS依赖于Iptables,IPVS会使用iptables进行包过滤、airpin-masquerade tricks(地址伪装)、SNAT 等功能,但是使用的是 iptables 的扩展 ipset,并不是直接调用 iptables 来生成规则链。通过 ipset 来存储需要 DROP 或 masquerade 的流量的源或目标地址,用于确保 iptables 规则的数量是恒定的,这样我们就不需要关心有多少 Service 或是 Pod 了。

使用 ipset 相较于 iptables 有什么优点呢?

iptables 是线性的数据结构,而 ipset 引入了带索引的数据结构,当规则很多的时候,ipset 依然可以很高效的查找和匹配。我们可以将 ipset 简单理解为一个 IP(段) 的集合,这个集合的内容可以是 IP 地址、IP 网段、端口等,iptables 可以直接添加规则对这个“可变的集合进行操作”,这样就可以大大减少 iptables 规则的数量,从而减少性能损耗。举一个例子,如果我们要禁止成千上万个 IP 访问我们的服务器,如果使用 iptables 就需要一条一条的添加规则,这样会在 iptables 中生成大量的规则;如果用 ipset 就只需要将相关的 IP 地址(网段)加入到 ipset 集合中,然后只需要设置少量的 iptables 规则就可以实现这个目标。下面的表格是 ipvs 模式下维护的 ipset 表集合:

设置名称成员用法
KUBE-CLUSTER-IP 所有服务 IP + 端口 在 masquerade-all=true 或 clusterCIDR 指定的情况下对 Service Cluster IP 地址进行伪装,解决数据包欺骗问题
KUBE-LOOP-BACK 所有服务 IP + 端口 + IP 解决数据包欺骗问题
KUBE-EXTERNAL-IP 服务外部 IP + 端口 将数据包伪装成 Service 的外部 IP 地址
KUBE-LOAD-BALANCER 负载均衡器入口 IP + 端口 将数据包伪装成 Load Balancer 类型的 Service
KUBE-LOAD-BALANCER-LOCAL 负载均衡器入口 IP + 端口 以及externalTrafficPolicy=local 接受数据包到 Load Balancer externalTrafficPolicy=local
KUBE-LOAD-BALANCER-FW 负载均衡器入口 IP + 端口 以及loadBalancerSourceRanges 使用指定的 loadBalancerSourceRanges 丢弃 Load Balancer 类型 Service 的数据包
KUBE-LOAD-BALANCER-SOURCE-CIDR 负载均衡器入口 IP + 端口 + 源 CIDR 接受 Load Balancer 类型 Service 的数据包,并指定 loadBalancerSourceRanges
KUBE-NODE-PORT-TCP NodePort 类型服务 TCP 端口 将数据包伪装成 NodePort(TCP)
KUBE-NODE-PORT-LOCAL-TCP NodePort 类型服务 TCP 端口,带有externalTrafficPolicy=local 接受数据包到 NodePort 服务,使用 externalTrafficPolicy=local
KUBE-NODE-PORT-UDP NodePort 类型服务 UDP 端口 将数据包伪装成 NodePort(UDP)
KUBE-NODE-PORT-LOCAL-UDP NodePort 类型服务 UDP 端口,使用externalTrafficPolicy=local 接受数据包到 NodePort 服务,使用 externalTrafficPolicy=local

Iptables与IPVS对比

  • iptables
    • 表中规则过多时,响应变慢,即规则遍历匹配和更新,呈线性时延
    • 灵活,功能强大(可以在数据包不同阶段对包进行操作)
    • 工作在内核空间
    • 优点
    • 缺点
  • IPVS
    • 内核支持不全,低版本内核不能使用,需要升级到4.0或5.0以上。
    • 转发效率高
    • 调度算法丰富:rr、wrr、lc、wlc、ip hash...
    • 工作在内核空间
    • 优点
    • 缺点
  • 使用iptables与ipvs时机
    • 1.10版本之前使用iptables(1.1版本之前使用UserSpace进行转发)
    • 1.11版本之后同时支持iptables与ipvs,默认使用ipvs,如果ipvs模块没有加载时,会自动降级至iptables来源:https://juejin.cn/post/7223586933866741818

👇

图片

 

云原生运维圈
专注于Docker、Kubernetes、Prometheus、Istio、Terraform、OpenTelemetry等云原生技术分享!
54篇原创内容

图片

收录于合集 #kubernetes
 42
上一篇如何使用Kubernetes Job运行一次性任务下一篇一文带你深入了解Kubernetes Service类型
 
阅读原文
阅读 826
云原生运维圈
 
关注公众号后可以给作者发消息
 
 
 
 
 
 
posted @ 2023-11-23 08:59  技术颜良  阅读(13)  评论(0编辑  收藏  举报