《做一个不背锅的运维:简单说说K8S的Service底层》

CodeStriderMaster
• 阅读 883

Service的底层

Kubernetes Service的底层实现可以使用两种网络模式:iptables和ipvs。

在Kubernetes中,Service是一个抽象的逻辑概念,用于公开应用程序的网络服务。它将一组Pod封装在一个虚拟IP地址后面,可以通过该IP地址和相应的端口号访问这些Pod。而底层实现Service的网络模式,可以通过kube-proxy来进行设置。

Kubernetes早期版本中,kube-proxy默认使用iptables实现Service,即通过iptables规则来实现请求的转发和负载均衡。而在Kubernetes 1.11版本之后,新增了对IPVS的支持。IPVS是一种高性能的、基于内核的负载均衡器,可以提供更高的性能和更丰富的负载均衡算法。

相比之下,iptables在规则较多时可能会影响性能,而IPVS的性能更高,且可以支持多种负载均衡算法,例如RR、LC、WRR等。因此,在高并发、高负载的场景下,使用IPVS作为Service的底层实现是更为合适的选择。

优缺点

Kubernetes Service 底层使用 iptables 和 ipvs 作为负载均衡的实现方式,其实两者都是各有优缺点的,下面好好聊聊:

使用 iptables 作为负载均衡器的优点如下:

  1. 简单易用:iptables 是 Linux 中默认的防火墙软件,使用广泛,熟练掌握 iptables 的管理员可以很容易地配置 Service 的负载均衡。
  2. 稳定性高:iptables 在 Linux 中已经经过多年的使用和优化,稳定性得到了很好的保证,可以满足大部分场景下的负载均衡需求。
  3. 配置灵活:iptables 提供了非常灵活的配置方式,可以根据不同的业务场景和需求进行定制化配置,可以轻松地实现多种转发策略。

但是,使用 iptables 作为负载均衡器也存在一些缺点:

  1. 性能不够优秀:iptables 的性能相对较差,当集群规模增大时,会带来一定的性能压力。
  2. 负载均衡粒度较粗:iptables 的负载均衡粒度较粗,只能对 IP 地址进行负载均衡,无法对请求的 Header 信息等进行识别,对于某些需要更精细的负载均衡场景可能无法满足需求。

使用 ipvs 作为负载均衡器的优点如下:

  1. 性能优秀:ipvs 的性能非常优秀,可以支持高并发和大规模的负载均衡。
  2. 负载均衡粒度细:ipvs 的负载均衡粒度比 iptables 更细,可以对请求的 Header 信息等进行识别,可以满足更精细的负载均衡场景。

但是,使用 ipvs 作为负载均衡器也存在一些缺点:

  1. 配置相对复杂:ipvs 的配置比 iptables 更加复杂,需要较高的技术水平和经验。
  2. 稳定性相对较低:ipvs 的稳定性相对较低,需要管理员经常进行监控和维护。
使用 iptables 和 ipvs 作为 Kubernetes Service 的负载均衡器都有其优点和缺点,具体使用哪种方式需要根据实际场景和需求进行权衡。

kube-proxy

kube-proxy 是一个网络代理,它监视 Kubernetes Service 的变化,然后自动更新本地的网络规则,以实现负载均衡和流量转发功能。

当 Kubernetes 中创建了一个 Service 对象时,kube-proxy 会根据 Service 的定义生成相应的虚拟 IP 地址,并为该 IP 地址配置负载均衡规则,以将流量转发到后端 Pod 上。

除了负载均衡和流量转发的功能之外,kube-proxy 还负责维护 Kubernetes 集群中的网络拓扑结构,并为 Pod 分配 IP 地址。因此,kube-proxy 是 Kubernetes 集群中非常重要的组件之一,它确保了网络流量的顺畅和应用程序的可用性。

Kube-proxy默认使用iptables作为Service的实现方式,下面可以看到kube-proxy的启动Log:

tantianran@test-b-k8s-master:~$ kubectl logs kube-proxy-6bdwl -n kube-system
...
I0320 00:43:35.602674       1 server_others.go:206] "Using iptables Proxier" # 这条log告诉你 使用的是 iptables 的代理模式
...

修改成ipvs模式

kube-proxy 支持两种负载均衡模式,默认是 iptables 模式,使用的模式可以在 kube-proxy 配置中进行指定,下面修改成IPVS:

  1. 每个节点安装ipvs相关依赖
sudo apt-get install -y ipset ipvsadm linux-modules-extra-$(uname -r) # Ubuntu
yum install -y ipset ipvsadm kernel-modules-extra # CentOS

# 确认 IPVS 模块已加载,如果输出结果中包含 ip_vs 和 nf_conntrack_ipv4,则表示 IPVS 模块已加载。
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
确保在每个节点上都安装了这些软件包,并且它们的版本相同,这样才能确保集群中的所有节点都具备 IPVS 的支持。
  1. 修改配置文件
如果k8s使用的是kubeadm搭建的。那么kube-proxy它的配置文件是默认交由ConfigMap进行管理的。在Kubernetes中,ConfigMap是一种用于管理应用程序配置的对象,它将配置信息存储为键值对的形式,可以被挂载到容器中,或者通过环境变量的形式注入到容器中。

kube-proxy使用的配置文件是通过一个名为kube-proxy的ConfigMap来管理的,这个ConfigMap的名称和命名空间默认为kube-system。可以使用以下命令查看kube-proxy的ConfigMap:

kubectl get configmap -n kube-system kube-proxy -o yaml

在编辑器中修改config.conf.mode的值为"ipvs",如果不指定mode,默认的模式就是iptables

kubectl edit configmap kube-proxy -n kube-system

内容如下:

mode: "ipvs"

修改后,保存并退出即可,修改后的配置信息会被自动更新到kube-proxy的配置文件中,查看一下:

kubectl get configmap -n kube-system kube-proxy -o yaml | grep mode
  1. 接着删掉kube-proxy的pod,删完后它会马上自动重建,重建后即能加载配置从而使ipvs生效:
kubectl get pod -n kube-system | grep kube-proxy | awk '{print $1}' | xargs kubectl delete pod -n kube-system
pod "kube-proxy-dh5rv" deleted
pod "kube-proxy-nt8qz" deleted
pod "kube-proxy-pkspb" deleted
  1. 创建一个NodePort类型的Service:
tantianran@test-b-k8s-master:/etc/kubernetes$ kubectl create svc nodeport test-goweb --tcp=80:8090 --node-port=30010
service/test-goweb created
tantianran@test-b-k8s-master:/etc/kubernetes$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        114d
test-goweb   NodePort    10.104.238.165   <none>        80:30010/TCP   8s
tantianran@test-b-k8s-master:/etc/kubernetes$ 
  1. 查看当前正在运行的虚拟服务和真实服务器的信息:
tantianran@test-b-k8s-master:/etc/kubernetes$ sudo ipvsadm -Ln | grep 30010
TCP  172.17.0.1:30010 rr
TCP  192.168.11.13:30010 rr
TCP  10.244.82.0:30010 rr
tantianran@test-b-k8s-master:/etc/kubernetes$ sudo ipvsadm -Ln | grep 8090
  -> 10.244.240.3:8090            Masq    1      0          0         
  -> 10.244.240.14:8090           Masq    1      0          0         
  -> 10.244.240.23:8090           Masq    1      0          0         
  -> 10.244.240.34:8090           Masq    1      0          0         
  -> 10.244.240.45:8090           Masq    1      0          0         
  -> 10.244.240.46:8090           Masq    1      0          0         
  -> 10.244.240.3:8090            Masq    1      0          0         
  -> 10.244.240.14:8090           Masq    1      0          0         
  -> 10.244.240.23:8090           Masq    1      0          0         
  -> 10.244.240.34:8090           Masq    1      0          0         
  -> 10.244.240.45:8090           Masq    1      0          0         
  -> 10.244.240.46:8090           Masq    1      0          0         
  -> 10.244.240.3:8090            Masq    1      0          0         
  -> 10.244.240.14:8090           Masq    1      0          0         
  -> 10.244.240.23:8090           Masq    1      0          0         
  -> 10.244.240.34:8090           Masq    1      0          0         
  -> 10.244.240.45:8090           Masq    1      0          0         
  -> 10.244.240.46:8090           Masq    1      0          0         
  -> 10.244.240.3:8090            Masq    1      0          0         
  -> 10.244.240.14:8090           Masq    1      0          0         
  -> 10.244.240.23:8090           Masq    1      0          0         
  -> 10.244.240.34:8090           Masq    1      0          0         
  -> 10.244.240.45:8090           Masq    1      0          0         
  -> 10.244.240.46:8090           Masq    1      0          0         
tantianran@test-b-k8s-master:/etc/kubernetes$ 
  1. 看看能否正常访问:

《做一个不背锅的运维:简单说说K8S的Service底层》

  1. 如果要改回使用iptables的代理模式,只需修改kube-proxy配置中的mode为空字符串,它就会默认使用iptables

内容如下:

mode: ""

最后的总结

Kubernetes中的Service是一个抽象层,用于将一组Pod公开为单个网络端点。在实际部署中,Kubernetes提供了两种不同的Service类型:ClusterIP和NodePort。这两种Service类型的实现方式不同,涉及到两种不同的网络代理技术:iptables和IPVS。

  1. iptables

iptables是一个基于Linux内核的网络数据包过滤工具,用于控制网络数据包的转发。在Kubernetes中,当创建一个ClusterIP Service时,kube-proxy组件会自动为该Service创建一组iptables规则。这些规则将来自Service IP地址和端口的数据包转发到后端Pod的IP地址和端口。

iptables规则的实现方式比较简单,但是当后端Pod数量较多时,iptables规则数量也会随之增加,这可能会对iptables性能产生一定的影响。此外,当Pod数量发生变化时,iptables规则也需要实时更新,这也可能会导致一定的延迟。

  1. IPVS

IPVS是一个高性能的网络代理工具,用于将来自客户端的请求转发到后端的服务。在Kubernetes中,可以使用IPVS来代替iptables作为Service的后端负载均衡器。

与iptables不同,IPVS是基于内核模块的形式实现的。在Kubernetes中,kube-proxy组件会自动加载IPVS内核模块,并使用IPVS来实现Service的后端负载均衡。IPVS的优势在于它可以高效地处理大规模的负载均衡,因此在大规模集群中使用IPVS可以提高集群的性能和稳定性。

需要注意的是,IPVS的配置相对于iptables来说要复杂一些,需要额外的工具来管理。同时,IPVS需要更多的内存和CPU资源,因此在使用IPVS时需要考虑到集群的资源限制。

好了,本篇的分享就到这里。下一篇的话呢,我会继续在k8s中创建一个deployment和service,并分析service底层的iptables和ipvs的每一条策略是怎样的。辛苦大家保持高度关注,感谢!

本文转载于WX公众号不背锅运维:https://mp.weixin.qq.com/s/gqet-QabvxqnWhdxAOO6Cg

点赞
收藏
评论区
推荐文章
Prodan Labs Prodan Labs
4年前
Kubernetes Ingress — NGINX
在Kubernetes中,Service是一种抽象的概念,它定义了每一组Pod的逻辑集合和访问方式,并提供一个统一的入口,将请求进行负载分发到后端的各个Pod上。Service默认类型是ClusterIP,集群内部的应用服务可以相互访问,但集群外部的应用服务无法访问。为此Kubernetes提供了NodePorts,LoadBalan
Stella981 Stella981
3年前
Minikube之Win10单机部署
Kubernetes(k8s)是自动化容器操作的开源平台,基于这个平台,你可以进行容器部署,资源调度和集群扩容等操作。如果你曾经用过Docker部署容器,那么可以将Docker看成Kubernetes底层使用的组件,Kubernetes是Docker的上层封装,通过它可以很方便的进行Docker集群的管理。今天我们使用minikube在单机上进行Kubern
Stella981 Stella981
3年前
K8s——Ingress
在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,在Kubernetes中目前提供了以下几种方案:1.NodePort2.LoadBalancer3.IngressNodePort,简单来说,就是通过service这种资源对象,为后端
Stella981 Stella981
3年前
Service IP 原理
ServiceClusterIP是一个虚拟IP,是由Kubernetes节点上的iptables规则管理的。可以通过 iptablessave 命令打印出当前节点的iptables规则,因为输出较多,这里只截取与 httpdsvc ClusterIP 10.99.229.179 相关的信息:!(https:/
Stella981 Stella981
3年前
K8S——Pod无法通过 Service IP 访问自身
问题描述:pod能ping通Service名称,但无法通过nc或者telnet连接对应的端口解决:1、修改svc模式clusterip到loadbalance解决,但阿里云需要创建slb,可以买内网共享型的slb,免费2、修改k8s配置:kubelethairpinmode配置(https://kubernetes.
Stella981 Stella981
3年前
Kubernetes Pod 故障归类与排查方法
Pod概念Pod是kubernetes集群中最小的部署和管理的基本单元,协同寻址,协同调度。Pod是一个或多个容器的集合,是一个或一组服务(进程)的抽象集合。Pod中可以共享网络和存储(可以简单理解为一个逻辑上的虚拟机,但并不是虚拟机)。Pod被创建后用一个UID来唯一标
Stella981 Stella981
3年前
Linux中iptables的正确使用
1.首先介绍一下指令和相关配置文件启动指令:service iptables start重启指令:service iptables restart关闭指令:service iptables stop然后是相关配置:/etc/sysconfig/iptables如何操作该配置呢?vim /etc/sysconfig/iptab
Wesley13 Wesley13
3年前
CDN与智能DNS原理和应用
1.cdn概念,DNS概念CDN:CententDeliveryNetwork(内容分发网络)使用户可以就近取得所需内容,提高用户访问网站相应速度CDN更智能的镜像缓存流量导流;DNS:DomainNameSystem域名系统域名和ip地址相互映射的一个分布式数据库,不用去记住被机器读取的ip地址CDN是内容分发网络,
Stella981 Stella981
3年前
K8s ipvs mode kube
IPVSvs.IPTABLESIPVS模式在Kubernetes1.8中被引入,在1.9中进入beta测试。IPTABLES模式在1.1版本中被添加进来,在1.2开始就变成了默认的操作模式。IPVS和IPTABLES都是基于netfilter实现的。IPVS与IPTABLES有以下几点不同的地方:1
十月飞翔 十月飞翔
3年前
k8s之PV、PVC、StorageClass
PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”,比如Node也是容器应用可以消费的资源。PV由管理员创建和配置,与共享存储的具体实现直接相关。PVC则是用户对存储资源的一个“申请”,就像Pod消费Node资源一样,PVC能够消费PV资源。PVC可以申请特定的存储空间和访问模式。StorageClass,用于标记存储资源的特性和性能,管理员可以将
SPI在Java中的实现与应用 | 京东物流技术团队
1SPI的概念APIAPI在我们日常开发工作中是比较直观可以看到的,比如在Spring项目中,我们通常习惯在写service层代码前,添加一个接口层,对于service的调用一般也都是基于接口操作,通过依赖注入,可以使用接口实现类的实例。简单形容就是这样的
CodeStriderMaster
CodeStriderMaster
Lv1
少妇鬓边犹胜雪,黄昏月下更添香。
文章
4
粉丝
0
获赞
0