前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于源码深入浅出来理解k8s的services工作原理

基于源码深入浅出来理解k8s的services工作原理

作者头像
机械视角
发布2021-01-06 15:24:11
8910
发布2021-01-06 15:24:11
举报
文章被收录于专栏:TensorbytesTensorbytes

k8s 中的 services 就是一组同label类型 pod 的服务抽象,为服务提供了LB和反向代理的能力,集群中表示一个微服务的概念。kube-proxy 则是 service 具体实现,这里从工作机制(宏观)到源码(微观)解读 services 实现原理。

services 和 endpoints

先对 k8s 中两个基本的网络概念来做个简单的回顾,services 和 endpoints,下面是 services 和 endpoints 资源:

services:

endpoints

可以看出,最简单的 services 结构包含了一个 clusterIP,暴露端口和一个 selector 选择器。 endpoints 对象包含末端目标的ip地址和目标点的pod的信息。

而我们一般创建 serivces 并不需要手动创建 endpoints,集群会尝试根据 selector 找到对应的pod信息,然后基于找到的匹配的pod信息创建 pod 为后端的 endpoints 对象,流程如下图:

当然我们也可以手动创建 endpoints,比如我们为外部服务提供集群内的服务发现可以手动设置 services 和 endpoints:

从 kube-proxy 看 services 工作机制

kube-proxy 是负责 services 和 endpoints 在各节点的具体实现,kube-proxy 和 kubelet 一样会在每个节点都运行一个实例,为 services 提供做简单的 TCP, UDP和 SCTP 流量转发,转发到对应的目标(endpoints)。下面通过 kube-proxy 源码解读可以更好地了解 services 和 endpoints 的运作机制。

这里是基于release-1.17,commit sha:15600ef9855dbdfd6e07f6a76e660b1b6030387e

先从 cmd/kube-proxy/proxy.go 开始:

这是个k8s命令的标准源码,声明命令调用Execute(读过 k8s 命令源码得都知道都是这个讨论~:)

看下 NewProxyCommond方法:

Kubernetes 网络代理在每个节点上运行。网络代理反映了每个节点上 Kubernetes API 中定义的服务,并且可以执行简单的 TCP、UDP 和 SCTP 流转发,或者在一组后端进行循环 TCP、UDP 和 SCTP 转发。当前可通过 Docker-links-compatible 环境变量找到服务集群 IP 和端口,这些环境变量指定了服务代理打开的端口。有一个可选的插件,可以为这些集群 IP 提供集群 DNS。用户必须使用 apiserver API 创建服务才能配置代理。

cobra.Command 是一个标准的 k8s 命令行结构体,直接看 RUN 方法就可以了,RUN 里面有一个段对 kube-proxy 命令的描述:

Kubernetes 网络代理在每个节点上运行。网络代理反映了每个节点上 Kubernetes API 中定义的服务,并且可以执行简单的 TCP、UDP 和 SCTP 流转发,或者在一组后端进行循环 TCP、UDP 和 SCTP 转发。当前可通过 Docker-links-compatible 环境变量找到服务集群 IP 和端口,这些环境变量指定了服务代理打开的端口。有一个可选的插件,可以为这些集群 IP 提供集群 DNS。用户必须使用 apiserver API 创建服务才能配置代理。

这里核心的是 opts.Run() 方法,进去后可以看到一个 NewProxyServer 声明了一个ProxyServer结构体,调用了o.proxyServer.Run()方法,我们先看看 proxyServer 结构体。

ProxyServer 三种运行模式

NewProxyServer 提供了三种运行模式,iptables、IPVS和 userspace,userspace 代理模式算比较旧的一种模式,在 Kubernetes v1.0 中开始使用 user space, v1.2的时候默认模式已经改为 iptables 了,现在大部分集群中都是这种模式。

userspace 模式其实就是直接通过kube-proxy 将数据包转发到后端 Pods,kube-proxy 在这里起到了路由规则下发、包转发规则、负载均衡的功能,由于 kube-proxy 是运行在用户空间的,会存在用户空间和内核空间的频繁切换,这对性能影响很大,所以后面默认就换成 iptables 了。 iptables 基于 netfilter 实现,所有操作都在内核空间相比基于 kube-proxy 直接做转发和负载均衡在性能上得到很大的提升。这里 kube-proxy 只是起到设置 iptables 的规则作用。 另一个是 IPVS, IPVS 在性能上比 iptables 更进一步,底层和 iptables 一样是基于 netfilter ,但IPVS 基于hash tabels来存储网络转发规则相比于 iptables 这种线性 O(n) 的算法要快很多。

但 1.17 版下 iptables 还是 kube-proxy 的默认选项,应该用得人也是最多得,这里就只介绍 iptables 的转发方式。

kube-proxy核心运行逻辑

okay,了解完 ProxyServer 结构,我们继续看看 kube-proxy 核心运行逻辑,也就是 Run()方法:

从这里可以看到, ProxyServer 主要包括几步:

  • 监控检查
  • metrics数据上报
  • 通过 client-go 从apiserver 获取 services 和 endpoints/endpointSlice 配置
  • 创建 services 和 endpoints/endpointSlice
  • 进入循环

kube-proxy在 iptables 实现

在了解 ProxyServer 结构和运行原理之后,我们来看看 kube-proxy 是如何通过 iptables 创建 services 和 endpoints 的。

NewServiceConfig和NewEndpointSliceConfig

ServiceConfig 和 EndpointsConfig 是kube-proxy中用于监听service变化的组件,核心是三个方法AddFuncUpdateFuncDeleteFunc

以 service 为例(endpoints和services类似)三个方法分别对应着OnServiceAddOnServiceUpdateOnServiceDelete,这三个都是接口方法。

这些接口的具体实现我们可以找到对应的实现,这里以 iptables 为例,因为找到 pkg/proxy/iptables/proxier.go 下面 Proxier 对应方法实现:

可以看到这增、删、改三个方法都是 Update实现的

serviceConfig.Run和endpointsConfig.Run

serviceConfig.Run 方法:

这里的 eventHandler 就是一个包含 Proxier 的数组,这里核心是OnServiceSynced方法,找到具体iptables proxier 的这个方法的具体实现:

kube-proxy 在 iptables 规则

到了核心的 syncProxyRules() 方法了,我们先看关键 iptables 的 chain 创建:

可以看到 kube-proxy 的 chain 都是在 filter 表和 nat 表下创建的。

看 nat 表:

对于LB的路由路径:

对于 nodeport 的形式:

这里的 KUBE-SVC-YTWGRZ3E3MPBXGU3KUBE-SEP-EVJ6H5FW5OUSCV2YKUBE-FW-TBZWFMENS353FQVB 这些是通过对 servicePortName 和 协议生成:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-01-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • services 和 endpoints
  • 从 kube-proxy 看 services 工作机制
    • ProxyServer 三种运行模式
      • kube-proxy核心运行逻辑
        • kube-proxy在 iptables 实现
          • NewServiceConfig和NewEndpointSliceConfig
          • serviceConfig.Run和endpointsConfig.Run
        • kube-proxy 在 iptables 规则
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档