前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Kubernetes(k8s)-服务(Service)流量走向

Kubernetes(k8s)-服务(Service)流量走向

作者头像
运维小路
发布2025-01-10 10:24:02
发布2025-01-10 10:24:02
8700
代码可运行
举报
文章被收录于专栏:运维小路运维小路
运行总次数:0
代码可运行

作者介绍:简历上没有一个精通的运维工程师。

我们上一章介绍了Docker基本情况,目前在规模较大的容器集群基本都是Kubernetes,但是Kubernetes涉及的东西和概念确实是太多了,而且随着版本迭代功能在还增加,笔者有些功能也确实没用过,所以只能按照我自己的理解来讲解。

我们前面2个小节介绍了svc的几种类型,但是并没有介绍这个流量是如何从svc走到pod去的,下面我将以iptables的方式介绍流量是如何通过svc方式走到pod里面的。

首先需要了解的就是svc是一个虚假的地址,并不真实存在,所以它不可以piing通(实际上svc也只是ip+端口形式的暴露),实际上这个svc地址的访问也只是命中了iptabels规则,通过iptables进行了转发。

我们以下面的这个30008端口来进行讲解,在比较早期的版本这个30008端口还会监听在每个节点的kube-proxy进程上,当前我使用的版本已经不再监听NodePort端口。

首先我们收集了这个规则对应的iptabes规则。

代码语言:javascript
代码运行次数:0
复制
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/my-service" -m tcp --dport 30008 -j KUBE-SVC-FXIYY6OHUSNBITIX
-A KUBE-SVC-FXIYY6OHUSNBITIX -p tcp -m comment --comment "default/my-service" -m tcp --dport 30008 -j KUBE-MARK-MASQ

第一条规则是真正转发规则,我们详细说明。第二条规则只是起标记作用,方便做NAT转发,这里就不介绍,其实我也没完全理解到。

  • -A KUBE-NODEPORTSKUBE-NODEPORTS 链中添加一条规则,这个链也是在nat表里面增加的自定义链,方便统一管理同类型的规则。
  • -p tcp指定该规则适用于 TCP 协议。
  • -m comment --comment "default/my-service"为该规则添加注释,说明这条规则是为名为 “my-service” 的服务在 “default” 命名空间中设置的。
  • -m tcp --dport 30008匹配目标端口为 30008 的 TCP 数据包。
  • -j KUBE-SVC-FXIYY6OHUSNBITIX如果数据包匹配上述条件,则跳转到 KUBE-SVC-FXIYY6OHUSNBITIX 链继续处理。

通俗来说就是当访问当前节点的30008,也就是我们定义的svc的NodePort的时候它会把请求转发到KUBE-SVC-FXIYY6OHUSNBITIX继续处理,当然这里是基于有NodePort的情况,如果是ClusterIP则会有下面这个规则。

代码语言:javascript
代码运行次数:0
复制
-A KUBE-SERVICES -d 10.100.211.232/32 -p tcp -m comment --comment "default/my-service cluster IP" -m tcp --dport 80 -j KUBE-SVC-FXIYY6OHUSNBITIX

这个规则其实和前面那个规则逻辑是一样的,只是这个规则命中的是svc的ip+端口,然后也是往KUBE-SVC-FXIYY6OHUSNBITIX继续处理。

前面2条规则就是对流量进行拦截,只要命中这个svc的信息就接着往后走,下面我们接着看后面的规则。

代码语言:javascript
代码运行次数:0
复制
-A KUBE-SVC-FXIYY6OHUSNBITIX ! -s 10.244.0.0/16 -d 10.100.211.232/32 -p tcp -m comment --comment "default/my-service cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-FXIYY6OHUSNBITIX -p tcp -m comment --comment "default/my-service" -m tcp --dport 30008 -j KUBE-MARK-MASQ

上面这2条规则也是主要起标记作用,下面3条就是真正的核心的转发逻辑,由于这个pod只有3个后端,所以这里就只有3条,这里的数量是由正常可用的pod数量决定的。

代码语言:javascript
代码运行次数:0
复制
-A KUBE-SVC-FXIYY6OHUSNBITIX -m comment --comment "default/my-service" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-2326I2JTW2R4QT2Y
-A KUBE-SVC-FXIYY6OHUSNBITIX -m comment --comment "default/my-service" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-JZUXTWVVYKNJ3L75
-A KUBE-SVC-FXIYY6OHUSNBITIX -m comment --comment "default/my-service" -j KUBE-SEP-XKSMMTNDLCGHRV4S
  • -m statistic --mode random --probability 0.33333333349:使用统计模块(statistic)来随机选择数据包。这里指定了 random 模式,并且设置了一个概率值 0.33333333349(大约等于 1/3)。这意味着大约有三分之一的匹配数据包会被发送到指定的目标。当前这个规则未命中,则继续匹配后面2个规则,所以第二个规则概念提升到了50%,如果前面2个未命中,则第三条规则命中的概率就是100%。通过这个方式svc就实现了类似轮询的方法把请求转发到后端的多个pod里面。
  • -j KUBE-SEP-2326I2JTW2R4QT2Y:如果数据包被随机选择(根据上述概率),则跳转到名为 KUBE-SEP-2326I2JTW2R4QT2Y 的链。这个链通常包含将数据包路由到特定后端 Pod 的规则。KUBE-SEP-* 链的名称是后端 Pod 端点(Endpoint)的哈希值。
代码语言:javascript
代码运行次数:0
复制
-A KUBE-SEP-2326I2JTW2R4QT2Y -p tcp -m comment --comment "default/my-service" -m tcp -j DNAT --to-destination 10.244.1.73:80
-A KUBE-SEP-JZUXTWVVYKNJ3L75 -p tcp -m comment --comment "default/my-service" -m tcp -j DNAT --to-destination 10.244.1.74:80
-A KUBE-SEP-XKSMMTNDLCGHRV4S -p tcp -m comment --comment "default/my-service" -m tcp -j DNAT --to-destination 10.244.1.75:80

这3条规则就是真正DNAT转发到后端pod的规则,由于我们的网络组件提前打通了到任何pod的通信,所以这里只要做了DNAT就可用转发成功。总结下来大概就是下图这样的。

如果出现访问svc不通,就可用通过该方式查询流量的走向,然后来排查问题所在。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维小路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档