查看原文
其他

kube-proxy 如何与 iptables 配合使用

我们知道 kube-proxy 是 Kubernetes 中一个运行在每个节点上的守护进程,它基本上反映了集群中定义的服务已经对后端 Pod 负载均衡的规则管理。

服务在后端 Pod 之间对请求进行负载均衡

假设我们有几个 API 微服务的 Pods 运行在我们的集群中,这些 Pods 的副本通过一个 Service 服务暴露,当一个请求到达 Service 的虚拟 IP 时,如何将请求转发到其中一个底层 Pod?其实就是通过 kube-proxy 创建的规则,虽然表面上并没有那么简单,但是我们还是可以进行大致的了解。

kube-proxy 可以在三种不同的模式下运行。

  • iptables
  • IPvs
  • userspace(不再推荐)

虽然 iptables 模式对于许多集群和工作负载来说完全没有问题,但当服务数量很多时(超过1,000个),ipvs 就会很有优势了,由于 iptables 规则是按顺序读取的,如果集群中存在许多服务,那么它的使用会影响路由性能。

Tigera(Calico 的创建者和维护者)在这篇很棒的文章(https://www.tigera.io/blog/comparing-kube-proxy-modes-iptables-or-ipvs/)中详细介绍了 iptables 和 ipvs 模式的区别。

iptables 和 ipvs 模式的主要对比

本文我们将专注于 iptables 模式(下一篇文章将专门介绍 ipvs 模式)来说明 kube-proxy 是如何定义 iptables 规则。

为此,我们将使用我刚刚用 kubeadm 创建的一个双节点集群。

$ kubectl get nodes
NAME    STATUS   ROLES                  AGE   VERSION
k8s-1   Ready    control-plane,master   57s   v1.20.0
k8s-2   Ready    <none>                 41s   v1.20.0

接下来我们将部署一个简单的应用程序,并通过 NodePort 类型的服务将其暴露出来。

示例

首先,我们创建一个基于 ghost 镜像的 Deployment(ghost 是一个免费开源的博客平台)并指定两个副本。

$ kubectl create deploy ghost --image=ghost --replicas=2

然后使用 NodePort 类型的 Service 来暴露 Pods。

$ kubectl expose deploy/ghost \
  --port 80 \
  --target-port 2368 \
  --type NodePort

部署完成后就可以获取这个新创建的 Service 的相关信息了。

$ kubectl describe svc ghost
Name:                     ghost
Namespace:                default
Labels:                   app=ghost
Annotations:              <none>
Selector:                 app=ghost
Type:                     NodePort
IP:                       10.98.141.188
Port:                     <unset>  80/TCP
TargetPort:               2368/TCP
NodePort:                 <unset>  30966/TCP
Endpoints:                10.44.0.3:2368,10.44.0.4:2368
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

这里有几个需要注意的事项:

  • 分配给 Service 的虚拟 IP 地址(VIP)是:10.98.141.188

  • 已分配给该 Service 的 NodePort 端口是 30966。通过这个端口,我们可以从集群的任何节点(本例中使用的集群节点的IP地址为192.168.64.35 和 192.168.64.36)访问 ghost 网页界面

    从集群的任一个节点访问 Ghost
  • Endpoints 属性显示了 Service 所暴露的 Pod 的 IP 地址。换句话说,每个到达 Service 的虚拟 IP (10.98.141.188) 端口 80 的请求都会以随机的方式转发到 2368 端口的底层 Pod 的 IP (10.44.0.3 或 10.44.0.4)。

注意:我们也可以使用标准的 kubectl get 命令来查询 Endpoints 信息。

$ kubectl get endpoints
NAME         ENDPOINTS                       AGE
ghost        10.44.0.3:2368,10.44.0.4:2368   4m
kubernetes   192.168.64.35:6443              6m

接下来,我们将仔细研究一下 kube-proxy 创建的 iptables 规则,以便将请求路由到后端 Pods。

iptables 规则

每次创建/删除 Service 或修改 Endpoints 时(例如,如果由于相关应用的 scale 而导致底层 Pod 数量发生变化),kube-proxy 都会负责更新集群每个节点上的 iptables 规则

让我们看看我们之前定义的 Service是如何完成的。由于有相当多的 iptables 链生成,这里我们只考虑主要涉及到的请求的路由,这些请求在 NodePort 上得到并被转发到其中一个底层 Pods。

首先,KUBE-NODEPORTS 链就是来处理 NodePort 类型的 Service 上的数据包。

KUBE-NODEPORTS 链

因此,每一个来自 30966 端口的数据包都会首先被 KUBE-MARK-MASQ 处理,它会给数据包打上了 0x4000 的标签。

注意:只有当负载均衡使用 IPVS 模式时,才会考虑到这个标记。

KUBE-MARK-MASQ 链

接下来,这个数据包由 KUBE-SVC-4XJR4EADNBDQKTKS 链(在上面的 KUBE-NODEPORTS 链中引用)进行处理。如果我们仔细看一下,可以看到多了两个 iptables 链。

  • KUBE-SEP-7I5NH52DVZSA3QHP
  • KUBE-SEP-PSCUKR75MU2ULAEX
Service iptables 链负载均衡请求

我们可以看到这里随机概率为0.5 的 statistic mode,因此进入 KUBE-SVC-4XJR4EADNBDQKTKS 链的每个数据包都有50%的概率被 KUBE-SEP-7I5NH52DVZSA3QHP 或者 KUBE-SEP-PSCUKR75MU2ULAEX (当它被第一个链忽略时)链进行处理。

如果我们检查这两条链,可以看到它们定义了 ghost 应用的底层 Pod 之一的路由。

路由至 Pod 10.44.0.3
路由至 Pod 10.44.0.4

通过几个 iptables 链,我们就能够了解一个请求从到达节点端口到底层 Pod的历程。

在本文希望我已经澄清了 kube-proxy 在使用 iptables 模式时的工作方式。接下来我们将看到当使用 ipvs 模式进行负载均衡时,路由是如何进行的工作。

原文链接:https://medium.com/better-programming/k8s-a-closer-look-at-kube-proxy-372c4e8b090


后台回复“加群”,带你进入高手如云交流群


推荐阅读:

完美排查入侵者

虚拟路由器冗余协议 VRRP 详解

Kubernetes 万字实战教程 (2021最新版)

Kubernetes 常见问题总结

一文详解负载均衡和反向代理的真实区别

经典!Kubernetes 几个常见对象概述图

带宽、延时、吞吐率、PPS 这些都是啥?

一文读懂你身边的网络

Linux 环境变量配置全攻略

如何定位软中断CPU使用率过高的问题?

10大高性能开发利器

安全容器gVisor详解

TCP协议灵魂 12 问,总会用得到

QUIC也不是万能的

超详干货!Linux环境变量配置全攻略

为什么要选择智能网卡?

60,000毫秒内对Linux进行性能诊断

为什么Linux需要Swapping

Linux系统常用命令速查手册

一文读懂容器网络发展

一文搞懂CDN加速原理

8 个问题彻底搞透 DNS 协议

三张图彻底搞懂iptables和netfilter

故障排查:K8s中Pod无法正常解析域名

网络排错大讲解~

OVS 和 OVS-DPDK 对比

微软出品的最新K8S学习指南3.0下载



喜欢,就给我一个“在看”



10T 技术资源大放送!包括但不限于:云计算、虚拟化、微服务、大数据、网络、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公众号内回复「1024」,即可免费获取!!

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存