阅读 117

深入理解K8S网络原理下

Service 应用是K8s集群内部可见的
而我们发布的应用需要外网甚至公网可以访问
K8s如何将内部服务暴露出去?复制代码

四层网络只有Node节点网络可以对外通讯
现在问题是第2层的Service网络如何通过第0层Node节点网络暴露出去呢?复制代码

需要再思考一个问题 在k8s服务发现原理图中 哪个组件既知道
service网络的所有信息又可以和pod网络互通互联同时又可以与节点网络打通呢?
那就是Kube-Proxy 对外暴露服务也是通过这个组件实现的

只需要让Kube-Proxy在节点上暴露一个监听端口就可以了 
所以NodePort就闪亮登场了复制代码

NodePort

将service type设置为NodePort 端口范围在30000~32767之间
k8s发布以后 会在每个节点上都会开通NodePort端口 这个端口的背后就是Kube-Proxy

当外部流量想要访问k8s服务的时候
先访问NodePort端口 然后通过Kube-Proxy转发到内部的Service抽象层
然后再转发到目标Pod上去复制代码

LoadBalancer 负载均衡器

如果在阿里云上有一套k8s环境
将service type设置为LoadBalancer
阿里云K8s会自动创建NodePort进行端口转发 同时也会
申请一个SLB 有独立的公网IP 并且也会自动映射K8s集群的NodePort上
以上是生产环境 就可以通过SLB暴露出去的公网IP访问到K8s集群内部的NodePort
但在开发测试环境可以直接通过NodePort访问

这种方式的劣势:

如果暴露一个服务就需要购买一个LB+IP
如果暴露10个服务就需要购买10个LB+IP
所以成本比较高
那有没有办法购买一个LB+IP能不能将更多的服务暴露出去呢?
那么Ingress就闪亮登场了
也就是在K8s内部部署一个独立的反向代理服务 让它做代理转发复制代码

Ingress

Ingress是一个特殊的service 通过节点80/443暴露出去
Ingress可以通过path或者域名转发到Service抽象层然后转发到Pod
只需要设置好转发的路由表即可
本质上和Nginx没有差别
service kind设置为ingress
ingress提供的主要功能是七层反向代理 如果暴露的是四层服务还是需要走LB+IP方式
还可以做安全认证、监控、限流、证书等高级功能
有了Ingress就可以购买一个LB+IP就可以将k8s集群中的多个service暴露出来复制代码

本地环境想要快速的开发调试方法

kubectl proxy

通过kubectl proxy在本机创建一个代理服务 
通过这个代理服务可以访问k8s集群内任意的http服务
通过master上的api server间接的去访问k8s集群内的服务
因为master是知道集群内所有服务的信息
这种方式仅限于七层的http转发复制代码

kubectl Port-Forwarding

在本机上开启一个转发端口间接转发到k8s内部某个pod端口上去
这种方式支持http转发和tcp转发复制代码

kubectl exec

通过该命令直接连接到pod上去执行命令复制代码

小结

深入理解Kube-Proxy

Kube-Proxy主要实现服务发现和负载均衡以及ClusterIP到PodIP的转换

Kube-Proxy通过linux内核提供的2个机制间接实现

"Netfilter"和"iptables"

通过这2个机制的配合来实现IP地址的转换以及流量的路由

Netfilter是linux内核支持的一种钩子方法 允许内核的其他模块注册回调方法

这些回调方法可以截获网络包 可以改变它们的目的地路由

iptables是一组用户空间程序 

通过它可以设置Netfilter中的路由规则 

iptables程序可以检查、转发、修改、重定向或者丢弃ip网络包

iptables是Netfilter用户空间接口 可以间接操作Netfilter中的路由规则复制代码

Kube-Proxy可以通过iptabels程序可以去操作内核空间的Netfilter里面的路由规则
而Netfilter可以截获底层的IP网络包就可以修改它们的路由复制代码

Kube-Proxy的工作模式

  • 用户空间代理模式

大部分的网络功能 包括设置包路由规则、负载均衡都是由运行在用户空间的Kube-Proxy直接完成的
它监听请求 执行路由和负载均衡 将请求转发到目标pod
在该模式下 kube-proxy还需要频繁在用户空间和内核空间切换
因为它需要和iptables交互来实现负载均衡复制代码

1、kube-proxy 监听 master 服务创建、更新、删除事件
   也监听这些服务对应的端点的地址
   如果pod ip发生了变化 kube-proxy也会同步这种变化
   
2、当有一个类型为ClusterIp的新服务被创建 Kube-Proxy会在节点上创建一个随机的端口 比如在10.100.0.2上开启一个随机端口10400
通过这个端口可以将目标请求转发到对应的端点上即pod上面

3、通过iptables设置转发规则 比如请求ip是10.104.14.67:80这个请求转发到10.100.0.2:10400这个地址上去

4、当节点上面有客户端对10.104.14.67:80这个service ip以及对应的podip10.100.0.2:10400发起调用的话  

5、这个请求会被netfilter截获到并且转发到10.100.0.2:10400这个上面 也就是kube-proxy正在监听的端口

6、kube-proxy接受这个请求 通过负载均衡 转发到pod上面

上面1-3步是服务发现阶段

4-6部是运行阶段

将请求转发到10400端口 kube-proxy先切换到内核接受这个请求包

然后切换到用户空间进行负载均衡调用

由于频繁的上下文切换 这种模式的性能并不理想

所以又引入了iptabels模式复制代码

iptables模式

1、kube-proxy会监听master上面的服务创建或者删除
也会监听服务背后所对应的pod ip地址
2、当有一个类型为clusterip的新服务被创建 kube-proxy通过iptables直接设置转发规则 并直接负载均衡转发到目标pod上面

不穿透kube-proxy 性能高
但iptables不支持高级的负载均衡策略也不支持失效自动重试机制
一般需要就绪探针进行配合

这种模式仅适用于中小模式的k8s集群 不适用大规模的k8s集群

假设有5000个节点的集群 集群有2000个服务 每个服务有10个pod 就需要在每个节点同步大约2万条记录 同时在云环境中 后端pod ip可能会随时变化 会给linux内核带来巨大的开销 

为了支持更大规模的k8s集群 引入了IPVS Proxy模式复制代码

IPVS Proxy模式

该模式是linux内核支持的虚拟化构建技术 是建立在netfilter基础之上的 是为了内核传输层高性能的负载均衡设计的技术
也是LVS主要的组成技术 

不仅支持缺省的Round Robbon(加权轮询)还支持最小连接、目标源hash 负载均衡算法 

使用高效的hash算法来存储网络路由规则 可以显著减少iptables的同步开销  大大提升集群的扩展规模 

Kube-Proxy通过调用Netfilter接口来创建和同步IPVS规则的
实际的路由转发和负载均衡由IPVS负责

IPVS效率最高 扩展性最好 配置也是最复杂的复制代码

小结

  • 用户空间代理模式 已淘汰

  • Iptables模式 生产适用 中小规模k8s集群

  • IPVS模式 生产使用 大规模K8s集群 配置复杂


作者:平凡人笔记
链接:https://juejin.cn/post/7018200407935549453


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐