【云原生 | 从零开始学Kubernetes】二十、Service代理kube-proxy组件详解

本文涉及的产品
公网NAT网关,每月750个小时 15CU
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: kube-proxy组件详解

kube-proxy组件详解


kube-proxy 组件介绍

kube-proxy 三种工作模式

1、Userspace 方式:

2、iptables 方式:

3、ipvs 方式:

kube-proxy 生成的 iptables 规则分析

1、service 的 type 类型是 ClusterIp,iptables 规则分析

2、service 的 type 类型是 nodePort,iptables 规则分析


kube-proxy 组件介绍


Kubernetes service 只是把应用对外提供服务的方式做了抽象,真正的应用跑在 Pod 中的 container 里,我们的请求转到 kubernetes nodes 对应的 nodePort 上,那么 nodePort 上的请求是如何进一步转到提供后台服务的 Pod 的呢? 就是通过 kube-proxy 实现的


kube-proxy 部署在 k8s 的每一个 Node 节点上,是 Kubernetes 的核心组件,我们创建一个 service 的时候,kube-proxy 会在 iptables 中追加一些规则,为我们实现路由与负载均衡的功能。在 k8s1.8 之前,kube-proxy 默认使用的是 iptables 模式,通过各个 node 节点上的 iptables 规则来实现 service 的负载均衡,但是随着 service 数量的增大,iptables 模式由于线性查找匹配、全量更新等特点,其性能 会显著下降。从 k8s 的 1.8 版本开始,kube-proxy 引入了 IPVS 模式,IPVS 模式与 iptables 同样基于 Netfilter,但是采用的 hash 表,因此当 service 数量达到一定规模时,hash 查表的速度优势就会显现出来,从而提高 service 的服务性能。


kubectl get pods -n kube-system -o wide


service 是一组 pod 的服务抽象,相当于一组 pod 的 LB,负责将请求分发给对应的 pod。service 会为这个 LB 提供一个 IP,一般称为 cluster IP。kube-proxy 的作用主要是负责 service 的实现,具体来说,就是实现了内部从 pod 到 service 和外部的从 node port 向 service 的访问。


1、kube-proxy 其实就是管理 service 的访问入口,包括集群内 Pod 到 Service 的访问和集群外访问 service。


2、kube-proxy 管理 sevice 的 Endpoints,该 service 对外暴露一个 Virtual IP,也可以称为是 Cluster IP, 集群内通过访问这个 Cluster IP:Port 就能访问到集群内对应的 serivce 下的 Pod。


kube-proxy 三种工作模式


1、Userspace 方式:


61.png


Client Pod 要访问 Server Pod 时,它先将请求发给内核空间中的 service iptables 规则,由它再将请求转给监听在指定套接字上的 kube-proxy 的端口,kube-proxy 处理完请求,并分发请求到指定Server Pod 后,再将请求转发给内核空间中的 service ip,由 service iptables 将请求转给各个节点中 的 Server Pod。


这个模式有很大的问题,客户端请求先进入内核空间的,又进去用户空间访问 kube-proxy,由 kube-proxy 封装完成后再进去内核空间的 iptables,再根据 iptables 的规则分发给各节点的用户空间的 pod。由于其需要来回在用户空间和内核空间交互通信,因此效率很差。在 Kubernetes 1.1 版本之前,userspace 是默认的代理模型。


2、iptables 方式:


62.png


客户端 IP 请求时,直接请求本地内核 service ip,根据 iptables 的规则直接将请求转发到到各 pod 上,因为使用 iptable NAT 来完成转发,也存在不可忽视的性能损耗。另外,如果集群中存上万的 Service/Endpoint,那么 Node 上的 iptables rules 将会非常庞大,性能还会再打折 iptables 代理模式由 Kubernetes 1.1 版本引入,自 1.2 版本开始成为默认类型。


3、ipvs 方式:


63.png


Kubernetes 自 1.9-alpha 版本引入了 ipvs 代理模式,自 1.11 版本开始成为默认设置。客户端请求时到达内核空间时,根据 ipvs 的规则直接分发到各 pod 上。kube-proxy 会监视 Kubernetes Service 对象和 Endpoints,调用 netlink 接口以相应地创建 ipvs 规则并定期与 Kubernetes Service 对象和 Endpoints 对象同步 ipvs 规则,以确保 ipvs 状态与期望一致。访问服务时,流量将被重定向到其中一个后端 Pod。与 iptables 类似,ipvs 基于 netfilter 的 hook 功能,但使用哈希表作为底层数据结构并在内核空间中工作。这意味着 ipvs 可以更快地重定向流量,并且在同步代理规则时具有更好的性能。此外,ipvs 为负载均衡算法提供了更多选项,例如:


rr:轮询调度  
lc:最小连接数  
dh:目标哈希  
sh:源哈希  
sed:最短期望延迟  
nq:不排队调度 


如果某个服务后端 pod 发生变化,标签选择器适应的 pod 又多一个,适应的信息会立即反映到 apiserver 上,而 kube-proxy 一定可以 watch 到 etc 中的信息变化,而将它立即转为 ipvs 或者 iptables 中的规则,这一切都是动态和实时的,删除一个 pod 也是同样的原理。


64.png


以上不论哪种,kube-proxy 都通过 watch 的方式监控着 apiserver 写入 etcd 中关于 Pod 的最新状态信息,它一旦检查到一个 Pod 资源被删除了或新建了,它将立即将这些变化反应在 iptables 或 ipvs 规则中,以便 iptables 和 ipvs 在调度 Clinet Pod 请求到 Server Pod时不会出现 Server Pod 不存在的情况。自 k8s1.11 以后,service 默认使用 ipvs 规则,若 ipvs 没有被激活,则降级使用 iptables 规则.


kube-proxy 生成的 iptables 规则分析


1、service 的 type 类型是 ClusterIp,iptables 规则分析


在 k8s 创建的 service,虽然有 ip 地址,但是 service 的 ip 是虚拟的,不存在物理机上的,是在 iptables 或者 ipvs 规则里的。


[root@k8smaster service]# kubectl apply -f pod_test.yaml 
[root@k8smaster service]# kubectl apply -f service_test.yaml 
[root@k8smaster node]# kubectl get svc -l run=my-nginx
NAME       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
my-nginx   ClusterIP   10.105.254.244   <none>        80/TCP    15s
[root@k8smaster node]# kubectl get pods -l run=my-nginx -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE  
my-nginx-5898cf8d98-5trvw   1/1     Running   0          40s   10.244.1.5   k8snode2   <none>          
my-nginx-5898cf8d98-phfqr   1/1     Running   0          40s   10.244.1.4   k8snode2   <none>          
[root@k8smaster node]# iptables -t nat -L | grep 10.105.254.244
KUBE-MARK-MASQ  tcp  -- !10.244.0.0/16        10.105.254.244       /* default/my-nginx: cluster IP */ tcp dpt:http
KUBE-SVC-BEPXDJBUHFCSYIC3  tcp  --  anywhere             10.105.254.244       /* default/my-nginx: cluster IP */ tcp dpt:http
[root@k8smaster node]# iptables -t nat -L | grep KUBE-SVC-BEPXDJBUHFCSYIC3
KUBE-SVC-BEPXDJBUHFCSYIC3  tcp  --  anywhere             10.105.254.244       /* default/my-nginx: cluster IP */ tcp dpt:http     #把service关联的pod做了转发
Chain KUBE-SVC-BEPXDJBUHFCSYIC3 (1 references)    
[root@k8smaster node]# iptables -t nat -L | grep 10.244.1.5
KUBE-MARK-MASQ  all  --  10.244.1.5           anywhere             /* default/my-nginx: */
DNAT       tcp  --  anywhere             anywhere             /* default/my-nginx: */ tcp to:10.244.1.5:80
#DNAT转发 kubesvc接收请求,在过滤podip的时候有个mark也会标记ip,然后做了一个dnat转发到10.244.1.5:80这个pod上
#通过上面可以看到之前创建的 service,会通过 kube-proxy 在 iptables 中生成一个规则,来实现流量路由,有一系列目标为 KUBE-SVC-xxx 链的规则,每条规则都会匹配某个目标 ip 与端口。也就是说访问某个 serivce的ip和端口请求会由 KUBE-SVC-xxx 链来通过DNAT转发到对应的podip和端口上。


2、service 的 type 类型是 nodePort,iptables 规则分析


[root@k8smaster node]# kubectl apply -f pod_nodeport.yaml 
deployment.apps/my-nginx-nodeport created
[root@k8smaster node]# kubectl apply -f service_nodeport.yaml 
service/my-nginx-nodeport created
[root@k8smaster node]# kubectl get pods -l run=my-nginx-nodeport -o wide
NAME                                 READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED
my-nginx-nodeport-5fccbb754b-m4csx   1/1     Running   0          34s   10.244.1.7   k8snode2   <none>      
my-nginx-nodeport-5fccbb754b-rg48l   1/1     Running   0          34s   10.244.1.6   k8snode2   <none>
[root@k8smaster node]# kubectl get svc -l run=my-nginx-nodeport 
NAME                TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
my-nginx-nodeport   NodePort   10.105.58.82   <none>        80:30380/TCP   39s
[root@k8smaster node]# iptables -t nat -S | grep 30380 
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp --dport 30380 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp --dport 30380 -j KUBE-SVC-6JXEEPSEELXY3JZG
#一个是mark链一个是svc 在访问物理机ip和端口,访问会先经过这两个链
[root@k8smaster node]# iptables -t nat -S | grep KUBE-SVC-6JXEEPSEELXY3JZG
-N KUBE-SVC-6JXEEPSEELXY3JZG
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp --dport 30380 -j KUBE-SVC-6JXEEPSEELXY3JZG
-A KUBE-SERVICES -d 10.105.58.82/32 -p tcp -m comment --comment "default/my-nginx-nodeport: cluster IP" -m tcp --dport 80 -j KUBE-SVC-6JXEEPSEELXY3JZG
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-36FBCF7ZW3VDH33Q
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -j KUBE-SEP-K2MGI3AJIGBK3IJ5
#会通过iptables的probability机制有0.50的概率进入KUBE-SEP-36FBCF7ZW3VDH33Q这个链,剩下50%还是最后那个GBK3IJ5这个链
[root@k8smaster node]# iptables -t nat -S | grep KUBE-SEP-36FBCF7ZW3VDH33
-N KUBE-SEP-36FBCF7ZW3VDH33Q
-A KUBE-SEP-36FBCF7ZW3VDH33Q -s 10.244.1.6/32 -m comment --comment "default/my-nginx-nodeport:" -j KUBE-MARK-MASQ
-A KUBE-SEP-36FBCF7ZW3VDH33Q -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp -j DNAT --to-destination 10.244.1.6:80
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-36FBCF7ZW3VDH33Q
#-A KUBE-SEP-36FBCF7ZW3VDH33Q -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp -j DNAT --to-destination 10.244.1.6:80 是做了一个dnat把请求给10.244.1.6这个pod的80端口了 下面可以看到ip是相同的
[root@k8smaster node]# kubectl get pods -l run=my-nginx-nodeport -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED
my-nginx-nodeport-5fccbb754b-m4csx   1/1     Running   0          8m24s   10.244.1.7   k8snode2   <none>    
my-nginx-nodeport-5fccbb754b-rg48l   1/1     Running   0          8m24s   10.244.1.6   k8snode2   <none>    
[root@k8smaster node]# iptables -t nat -S | grep KUBE-SEP-K2MGI3AJIGBK3IJ5
-N KUBE-SEP-K2MGI3AJIGBK3IJ5
-A KUBE-SEP-K2MGI3AJIGBK3IJ5 -s 10.244.1.7/32 -m comment --comment "default/my-nginx-nodeport:" -j KUBE-MARK-MASQ
-A KUBE-SEP-K2MGI3AJIGBK3IJ5 -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp -j DNAT --to-destination 10.244.1.7:80
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -j KUBE-SEP-K2MGI3AJIGBK3IJ5
#也是一个dnat,把请求分给另外一个pod,通过这两个链50%的概率来转发到两个pod上
相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
8月前
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
ACK One注册集群已正式支持ACS(容器计算服务)算力,为企业的容器化工作负载提供更多选择和更强大的计算能力。
|
8月前
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
269 10
|
10月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
412 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
8月前
|
运维 分布式计算 Kubernetes
ACK One多集群Service帮助大批量应用跨集群无缝迁移
ACK One多集群Service可以帮助您,在无需关注服务间的依赖,和最小化迁移风险的前提下,完成跨集群无缝迁移大批量应用。
|
11月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
11月前
|
Kubernetes Cloud Native 云计算
云原生入门:Kubernetes 和容器化基础
在这篇文章中,我们将一起揭开云原生技术的神秘面纱。通过简单易懂的语言,我们将探索如何利用Kubernetes和容器化技术简化应用的部署和管理。无论你是初学者还是有一定经验的开发者,本文都将为你提供一条清晰的道路,帮助你理解和运用这些强大的工具。让我们从基础开始,逐步深入了解,最终能够自信地使用这些技术来优化我们的工作流程。
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
198 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
2月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
本文内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
328 15
|
2月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
|
21天前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
249 0

热门文章

最新文章

推荐镜像

更多