文章插图
ipvs 支持三种负载均衡模式:
1、DR模式(Direct Routing);
2、NAT 模式(Network Address Translation);
3、Tunneling(也称 ipip 模式) 。
三种模式中只有 NAT 支持端口映射,所以 ipvs 使用 NAT 模式 。linux 内核原生的 ipvs 只支持 DNAT,当在数据包过滤,SNAT 和支持 NodePort 类型的服务这几个场景中ipvs 还是会使用 iptables 。
ipvs 也支持更多的负载均衡算法:
- rr:round-robin/轮询;
- lc:least connection/最少连接;
- dh:destination hashing/目标哈希;
- sh:source hashing/源哈希;
- sed:shortest expected delay/预计延迟时间最短;
- nq:never queue/从不排队
服务发现service 的 endpoints 解决了容器发现问题,但是不提前知道 service 的 Cluster IP , 就无法知道 service 服务了 。Kubernetes 支持两种基本的服务发现模式 —— 环境变量和 DNS 。
环境变量当一个 pod 创建完成之后,kubelet 会在该 pod 中注册该集群已经创建的所有 service 相关的环境变量,但是需要注意的是,在 service 创建之前的所有 pod 是不会注册该环境变量的 , 所以在平时使用时,建议通过 DNS 的方式进行 service 之间的服务发现 。
举个例子,一个名称为 redis-primary 的 Service 暴露了 TCP 端口 6379,同时给它分配了 Cluster IP 地址 10.0.0.11 , 这个 Service 生成了如下环境变量:
REDIS_PRIMARY_SERVICE_HOST=10.0.0.11REDIS_PRIMARY_SERVICE_PORT=6379REDIS_PRIMARY_PORT=tcp://10.0.0.11:6379REDIS_PRIMARY_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_PRIMARY_PORT_6379_TCP_PROTO=tcpREDIS_PRIMARY_PORT_6379_TCP_PORT=6379REDIS_PRIMARY_PORT_6379_TCP_ADDR=10.0.0.11DNS可以在集群中部署 CoreDNS 服务(旧版本的 kubernetes 群使用的是 kubeDNS) , 来达到集群内部的 pod 通过DNS 的方式进行集群内部各个服务之间的通讯 。
当前 kubernetes 集群默认使用 CoreDNS 作为默认的 DNS 服务,主要原因是 CoreDNS 是基于 Plugin 的方式进行扩展的 , 简单 , 灵活,并且不完全被Kubernetes所捆绑 。
同时 k8s 中也建议使用 DNS 来做服务发现 。
Kubernetes DNS 服务器是唯一的一种能够访问 ExternalName 类型的 Service 的方式 。
总结k8s 中一般使用 Service 为 Pod 对象提供一个固定、统一的访问接口及负载均衡的能力;
k8s 中的负载均衡主要借助于 endpoint 和 kube-proxy 来实现;
endpoint 是 k8s 集群中的一个资源对象 , 存储在 etcd 中,用来记录一个 service 对应的所有 pod 的访问地址 , 当一个 service 关联的 pod 被删除,更新,新增 , 对应的 endpoint 资源都会更新;
kube-proxy 是 Kubernetes 的核心组件,部署在每个 Node 节点上,它是实现 Kubernetes Service 的通信与负载均衡机制的重要组件; kube-proxy 负责为 Pod 创建代理服务,从 apiserver 获取所有 server 信息 , 并根据 server 信息创建代理服务,实现server到Pod的请求路由和转发,从而实现K8s层级的虚拟转发网络;
kube-proxy 的路由转发规则是通过其后端的代理模块实现的,其中 kube-proxy 的代理模块目前有四种实现方案,userspace、iptables、ipvs、kernelspace ;
service 的 endpoints 和 kube-proxy 解决了容器的发现和负载均衡的问题 , 但是 service 服务如何被内部的服务找到呢,Kubernetes 支持两种基本的服务发现模式 —— 环境变量和 DNS;
其中 k8s 中推荐使用 DNS 来做 service 的服务发现 , 当前 kubernetes 集群默认使用 CoreDNS 作为默认的 DNS 服务,主要原因是 CoreDNS 是基于 Plugin 的方式进行扩展的,简单,灵活,并且不完全被Kubernetes所捆绑 。
参考【kubernetes service 原理解析】https://zhuanlan.zhihu.com/p/111244353【service selector】https://blog.csdn.net/luanpeng825485697/article/details/84296765【一文看懂 Kube-proxy】https://zhuanlan.zhihu.com/p/337806843【Kubernetes 【网络组件】kube-proxy使用详解】https://blog.csdn.net/xixihahalelehehe/article/details/115370095【Service】https://jimmysong.io/kubernetes-handbook/concepts/service.html【Service】https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/【k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡】https://boilingfrog.github.io/2022/10/16/k8s中的service如何找到绑定的Pod以及如何实现Pod负载均衡/
推荐阅读
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点
- 时空中的绘旅人司岚生日限定礼包有什么内容
- CentOS 8.2 对k8s基础环境配置
- UML类中的6种关系
- 使用 Kubeadm 部署 K8S安装
- 工厂方法在Spring源码中的运用
- 我的世界信标怎么用,信标功能详细介绍(我的世界中的信标是怎么用的)
- 实时营销引擎在vivo营销自动化中的实践 | 引擎篇04
- 王者荣耀中的露娜,要怎么样玩才能练好招式呢
- .Net Framework中的AppDomain.AssemblyResolve事件的常见用法、问题,以及解决办法