K8S Service底层策略初探和分析

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: K8S Service底层策略初探和分析

创建用于测试的Deployment和Service

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test-goweb
  name: test-goweb
spec:
  replicas: 6
  selector:
    matchLabels:
      app: test-goweb
  template:
    metadata:
      labels:
        app: test-goweb
    spec:
      containers:
      - image: 192.168.11.247/web-demo/goweb-demo:20221229v3
        imagePullPolicy: IfNotPresent
        name: goweb-demo
        ports:
        - containerPort: 8090
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: test-goweb
  name: test-goweb
spec:
  ports:
  - name: 80-8090
    nodePort: 30010
    port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: test-goweb
  type: NodePort

Service底层有哪些iptables链

当在 Kubernetes 中创建 Service 时,将会创建以下几个 iptables 链。这些链都是用于实现 Service 的核心功能,下面列出所涉及到的链:

  1. PREROUTING 链:此链是由 kube-proxy 组件创建的,用于将 Service IP 地址映射到对应的 Pod IP 地址上。当请求进入节点时,该链将被触发,它根据请求的 Service IP 地址来查找对应的 Pod IP 地址,并将请求转发到该 Pod。
  2. KUBE-SERVICES 链:此链包含了一系列规则,用于将 Service IP 地址映射到对应的 Pod IP 地址上。当请求进入节点时,该链将被触发,并根据请求的 Service IP 地址来查找对应的 Pod IP 地址。如果找到了对应的 Pod IP 地址,请求将被转发到该 Pod。
  3. KUBE-SVC-XXX 链:此链包含了一系列规则,其中 XXX 代表 Service 的名称。每个 Service 都有一个对应的 KUBE-SVC-XXX 链。当请求进入节点时,该链将被触发,并根据 Service IP 地址查找对应的 KUBE-SVC-XXX 链。该链中的规则将请求转发到对应的 Pod。
  4. KUBE-SEP-XXX 链:此链包含了一系列规则,其中 XXX 代表 Service 的名称。每个 Service 都有一个对应的 KUBE-SEP-XXX 链。当请求进入节点时,该链将被触发,并根据 Service IP 地址查找对应的 KUBE-SEP-XXX 链。该链中的规则将请求转发到对应的 Pod。
  5. KUBE-FIREWALL 链:此链用于处理来自 Kubernetes 的内部流量。该链包含了一些规则,用于控制访问 Kubernetes 的 API、DNS 和其他一些服务。
  6. KUBE-NODEPORT 链:当 Service 类型为 NodePort 时,此链将被创建。该链包含了一些规则,用于将节点的端口映射到 Service 的端口上。
  7. KUBE-MARK-DROP 链:当请求被拒绝时,会触发此链。该链包含了一些规则,用于标记被拒绝的数据包。

这些 iptables 链是 Kubernetes 中实现 Service 的关键组件。它们使得客户端可以使用 Service 名称来访问运行在 Pod 中的应用程序,而不必了解其具体 IP 地址。

查看和这个service有关的iptables规则

# iptables-save | grep test-goweb
-A KUBE-EXT-XRKWZPWLY5ZGEEBK -m comment --comment "masquerade traffic for default/test-goweb:80-8090 external destinations" -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp --dport 30010 -j KUBE-EXT-XRKWZPWLY5ZGEEBK
-A KUBE-SEP-2KC5TQ77EILRJT77 -s 10.244.240.51/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-2KC5TQ77EILRJT77 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.51:8090
-A KUBE-SEP-5AVQRPMC6RQQAAKG -s 10.244.240.9/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-5AVQRPMC6RQQAAKG -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.9:8090
-A KUBE-SEP-7QBH2WDQDSESRX53 -s 10.244.240.19/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-7QBH2WDQDSESRX53 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.19:8090
-A KUBE-SEP-KGPYN3PAVPO2A2G3 -s 10.244.240.20/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-KGPYN3PAVPO2A2G3 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.20:8090
-A KUBE-SEP-VXCKMNYZWUWZOOOJ -s 10.244.240.38/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-VXCKMNYZWUWZOOOJ -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.38:8090
-A KUBE-SEP-XH5PMCJ3CYSK4B7L -s 10.244.240.56/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-XH5PMCJ3CYSK4B7L -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.56:8090
-A KUBE-SERVICES -d 10.104.238.165/32 -p tcp -m comment --comment "default/test-goweb:80-8090 cluster IP" -m tcp --dport 80 -j KUBE-SVC-XRKWZPWLY5ZGEEBK
-A KUBE-SVC-XRKWZPWLY5ZGEEBK ! -s 10.244.0.0/16 -d 10.104.238.165/32 -p tcp -m comment --comment "default/test-goweb:80-8090 cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.19:8090" -m statistic --mode random --probability 0.16666666651 -j KUBE-SEP-7QBH2WDQDSESRX53
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.20:8090" -m statistic --mode random --probability 0.20000000019 -j KUBE-SEP-KGPYN3PAVPO2A2G3
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.38:8090" -m statistic --mode random --probability 0.25000000000 -j KUBE-SEP-VXCKMNYZWUWZOOOJ
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.51:8090" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-2KC5TQ77EILRJT77
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.56:8090" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-XH5PMCJ3CYSK4B7L
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.9:8090" -j KUBE-SEP-5AVQRPMC6RQQAAKG

上面看到的这一堆规则,就是由 kube-proxy 组件自动创建和维护 iptables 规则,继续往下看,抽几条规则做个简单的分析。

简单分析

  1. 先看整体看看这1条规则
-A KUBE-EXT-XRKWZPWLY5ZGEEBK -m comment --comment "masquerade traffic for default/test-goweb:80-8090 external destinations" -j KUBE-MARK-MASQ

这是上面第一条iptables规则,它用于Kubernetes集群中的网络转发和流量伪装。具体来说,这个规则将来自Kubernetes服务“default/test-goweb”的流量伪装为外部目标,以便它们可以通过集群外部访问。

规则中的参数解释如下:

  • -A:将规则添加到链的末尾
  • KUBE-EXT-XRKWZPWLY5ZGEEBK:链的名称
  • -m comment --comment "masquerade traffic for default/test-goweb:80-8090 external destinations":添加一条注释,说明此规则是用于伪装“default/test-goweb”的流量,并指定了流量端口范围和目标类型
  • -j KUBE-MARK-MASQ:将流量标记为需要进行伪装的流量,以便其能够离开集群并在目标处正确路由

请注意,KUBE-EXT-XRKWZPWLY5ZGEEBK、KUBE-MARK-MASQ是自定义的链名称,它在Kubernetes集群中的不同部分可能会有所不同。在实际使用时,链的名称可能会因不同的部署而有所变化,但规则的作用通常是相似的。

  1. 大概看看第2条
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp --dport 30010 -j KUBE-EXT-XRKWZPWLY5ZGEEBK

它的作用是将从 NodePort 类型的 Service 访问到的流量(目标端口为 30010/tcp)转发到名为 KUBE-EXT-XRKWZPWLY5ZGEEBK 的链上进行进一步处理。

  1. 大概看看第3条
-A KUBE-SEP-2KC5TQ77EILRJT77 -s 10.244.240.51/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ

它的作用是将来自 IP 地址为 10.244.240.51 的源地址流量进行 SNAT 转换,以便将源 IP 地址更改为 Node 的 IP 地址,从而使流量能够返回到客户端。该规则使用名为 KUBE-MARK-MASQ 的链进行转换。

  1. 再看看第4条
-A KUBE-SEP-2KC5TQ77EILRJT77 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.51:8090

它的作用是将从集群内某个节点上的 Pod 访问 Service 的流量进行 DNAT 转换,以便将流量重定向到特定 Pod 的 IP 地址和端口上。

k8s的iptables规则是由k8s自身自动维护的,它使用 kube-proxy 组件来自动创建和维护 iptables 规则,当创建一个 Service 时,kube-proxy 会自动为该 Service 创建一组 iptables 规则,当 Pod 被添加或删除时,kube-proxy 会相应地更新这些规则。所以,不需要人为手动管理这些规则,简直是香到不行。

将Service底层的代理模式改为IPVS后

tantianran@test-b-k8s-master:~$ kubectl get svc test-goweb
NAME         TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
test-goweb   NodePort   10.104.238.165   <none>        80:30010/TCP   25h

在其中一台节点上看虚拟服务器信息

tantianran@test-b-k8s-node01:~$ sudo ipvsadm-save
-A -t test-b-k8s-node01:30001 -s rr
-a -t test-b-k8s-node01:30001 -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:30010 -s rr
-a -t test-b-k8s-node01:30010 -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.63:8090 -m -w 1
-A -t test-b-k8s-node01:30001 -s rr
-a -t test-b-k8s-node01:30001 -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:30010 -s rr
-a -t test-b-k8s-node01:30010 -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.63:8090 -m -w 1
-A -t test-b-k8s-node01:https -s rr
-a -t test-b-k8s-node01:https -r test-b-k8s-master:6443 -m -w 1
-A -t test-b-k8s-node01:domain -s rr
-a -t test-b-k8s-node01:domain -r 10.244.82.19:domain -m -w 1
-a -t test-b-k8s-node01:domain -r 10.244.240.60:domain -m -w 1
-A -t test-b-k8s-node01:9153 -s rr
-a -t test-b-k8s-node01:9153 -r 10.244.82.19:9153 -m -w 1
-a -t test-b-k8s-node01:9153 -r 10.244.240.60:9153 -m -w 1
-A -t test-b-k8s-node01:https -s rr
-a -t test-b-k8s-node01:https -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:8000 -s rr
-a -t test-b-k8s-node01:8000 -r 10.244.240.16:8000 -m -w 1
-A -t test-b-k8s-node01:http -s rr
-a -t test-b-k8s-node01:http -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.63:8090 -m -w 1
-A -t test-b-k8s-node01:https -s rr
-a -t test-b-k8s-node01:https -r 10.244.240.15:4443 -m -w 1
-A -t test-b-k8s-node01:30001 -s rr
-a -t test-b-k8s-node01:30001 -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:30010 -s rr
-a -t test-b-k8s-node01:30010 -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.63:8090 -m -w 1
-A -u test-b-k8s-node01:domain -s rr
-a -u test-b-k8s-node01:domain -r 10.244.82.19:domain -m -w 1
-a -u test-b-k8s-node01:domain -r 10.244.240.60:domain -m -w 1

要注意了,在上面的虚拟服务器信息中可以看到,有的是-a,有的是-A,这两个选项都可以用于向IPVS中添加一个新的服务(virtual server)。它们的区别不仅仅在于是大小写的区别,更大的区别在于添加服务的方式和语义上略有不同:

  • -a选项将添加一个新的服务,并将其附加到一个现有的调度器上。如果调度器不存在,则会创建一个新的调度器。
  • -A选项将添加一个新的服务,并将其附加到一个现有的调度器上。如果调度器不存在,则不会创建新的调度器。如果调度器已经存在,则服务将被添加到现有的调度器中。

拿这条策略来看看

-a -t test-b-k8s-node01:http -r 10.244.240.24:8090 -m -w 1

以下是每个选项的含义:

  • -a: 添加虚拟服务
  • -t test-b-k8s-node01:http: 虚拟服务的名称和协议。
  • -r 10.244.240.24:8090: 后端真实服务器的IP地址和端口号,也就是POD的。
  • -m: 使用IPVS的NAT模式。
  • -w 1: 将权重设置为1,即将1个请求发送给该服务器。

总而言之它的作用是:它将添加一个名为test-b-k8s-node01的HTTP虚拟服务,并将客户端的请求源IP地址改为工作节点的IP地址,并将请求发送到后端服务器10.244.240.24:8090,其中只有一个后端服务器,它的服务能力是1。

最后的总结

k8s中的Service底层不管是iptables还是ipvs,它们的策略规则都是k8s自身自动维护的。具体来说,当创建一个Service时,Kubernetes会在底层为该Service创建一个虚拟IP(VIP),并自动配置iptables或者ipvs规则,使得这个VIP可以将流量转发到Service中的多个Pod实例。

当使用iptables时,Kubernetes会在每个节点上创建iptables规则,通过iptables NAT功能实现负载均衡和服务发现。而当使用ipvs时,Kubernetes会在每个节点上创建ipvs规则,并使用ipvs的负载均衡算法实现服务发现和流量转发。

无论是使用iptables还是ipvs,Kubernetes都会自动维护这些规则,保证Service的负载均衡和高可用性。当Service中的Pod实例发生变化时,Kubernetes会自动更新iptables或ipvs规则,以确保流量能够正确地转发到新的Pod实例上。Kubernetes通过自动化的方式,简化了Service的配置和维护。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
24天前
|
Kubernetes Linux 调度
k8s环境设置-pod下载及重启策略
k8s环境设置-pod下载及重启策略
32 1
|
6天前
|
Kubernetes 负载均衡 应用服务中间件
Kubernetes(K8S) Service 介绍
Kubernetes(K8S) Service 介绍
9 0
|
6天前
|
Kubernetes 容器
Kubernetes(K8S) 镜像拉取策略 imagePullPolicy
Kubernetes(K8S) 镜像拉取策略 imagePullPolicy
13 0
|
1月前
|
存储 Kubernetes 监控
Kubernetes 集群的持续性能优化策略
【5月更文挑战第70天】 随着容器化技术的普及,Kubernetes 已成为管理微服务架构的首选平台。然而,在大规模部署和长期运行过程中,集群往往会遭遇性能瓶颈,影响服务的响应速度和稳定性。本文将探讨针对 Kubernetes 集群的性能优化策略,包括资源调度优化、网络延迟降低、存储效率提升及监控与日志分析等方面,旨在为运维工程师提供一套系统化的持续优化方法,确保集群性能的长期稳定。
67 10
|
2月前
|
容器 Perl Kubernetes
深入 Kubernetes 网络:实战K8s网络故障排查与诊断策略
本文介绍了Kubernetes网络的基础知识和故障排查经验,重点讨论了私有化环境中Kubernetes网络的挑战。首先,文章阐述了Kubernetes网络模型的三大核心要素:Pod网络、Service网络和CNI,并强调了其在容器通信和服务发现中的作用。接着,通过三个具体的故障案例,展示了网络冲突、主节点DNS配置更改导致的服务中断以及容器网络抖动问题的解决过程,强调了网络规划、配置管理和人员培训的重要性。最后,提到了KubeSkoop exporter工具在监控和定位网络抖动问题中的应用。通过这些案例,读者可以深入了解Kubernetes网络的复杂性,并学习到实用的故障排查方法。
146853 19
|
3月前
|
存储 Kubernetes 调度
Kubernetes 集群的持续性能优化策略
【5月更文挑战第25天】 随着容器化技术的普及,越来越多的企业采用 Kubernetes 作为其服务部署和运维的标准平台。然而,随着集群规模的增长和应用复杂性的上升,性能问题逐渐浮现,成为系统管理员关注的焦点。本文将探讨在 Kubernetes 环境中进行持续性能优化的实践方法,旨在为读者提供一系列实用的调优技巧,帮助其提升集群的稳定性与效率。通过深入分析资源分配、调度优化、网络效率以及存储管理等方面的调优手段,我们将展示如何构建一个高效、可扩展的 Kubernetes 集群。
|
3月前
|
存储 运维 监控
Kubernetes 集群的监控与维护策略
【5月更文挑战第23天】在微服务架构日益普及的当下,容器化技术与编排工具如Kubernetes已成为部署和管理应用程序的重要手段。然而,随着集群规模的扩大和复杂性的增加,确保系统的稳定性和高效性成为了一项挑战。本文将深入探讨针对Kubernetes集群的监控和维护策略,旨在为运维人员提供一套系统的方案,以实现对集群状态的实时监控、性能优化和故障快速响应。
|
3月前
|
存储 Kubernetes 监控
Kubernetes 集群的持续性能优化策略
【5月更文挑战第22天】 在微服务架构日益普及的背景下,容器编排成为关键性技术之一。其中,Kubernetes 凭借其强大的功能、灵活的扩展性和便捷的管理特性,成为业界广泛采用的解决方案。然而,随着集群规模的扩大和业务复杂度的增加,性能问题逐渐凸显,影响系统稳定性和响应效率。本文聚焦于 Kubernetes 集群的性能优化,提出一系列持续优化的策略,旨在帮助运维人员系统性地分析和解决性能瓶颈,提升集群运行效率。通过实际案例分析与经验总结,为读者呈现一套实用的性能调优方法论。
|
3月前
|
运维 Kubernetes Linux
Kubernetes详解(七)——Service对象部署和应用
Kubernetes详解(七)——Service对象部署和应用
60 3
|
3月前
|
运维 Prometheus 监控
Kubernetes 集群的监控与维护策略
【5月更文挑战第30天】 在微服务架构日益普及的背景下,容器编排工具如Kubernetes成为确保服务高效运行的关键。本文聚焦于Kubernetes集群的监控和维护,首先探讨了监控系统的重要性及其对集群健康的影响,随后详细介绍了一套综合监控策略,包括节点性能监控、应用服务质量跟踪以及日志管理等方面。此外,文章还提出了一系列实用的集群维护技巧和最佳实践,旨在帮助运维人员预防故障发生,快速定位问题,并确保集群长期稳定运行。