文章目录
LoadBalance
LoadBalance 通常分成两种类型:Client Side 和 Server side。
通常有如下设置
- Round robin:这种方法持续地循环连接到它的服务列表。当虚拟服务器收到请求时,它会将连接分配给列表中的第一个服务,然后将该服务移动到列表的底部。
- 最少连接:默认方法,当虚拟服务器配置为使用最少连接时,它会选择活动连接最少的服务。
- 最小响应时间:此方法选择活动连接最少、平均响应时间最低的服务。
server side
server side load balance 是在应用服务器前面的代理,LB 将根据路由设置将请求转发到应用服务器。
优点:初始设置很容易。
缺点:当应用服务器是动态的时,即使存在热重新加载,也很难操作。
示例:Nginx,haproxy
访问实现图示:
client side
client side load balance:应用程序服务器首先与客户端应用程序共享列表,应用程序将根据路由设置选择并与应用程序服务器交互。
优点:支持动态应用服务器,因为应用程序在启动时会自动注册。
缺点:初始设置比服务器端 LB 更困难。它需要额外的注册服务器、客户端和功能区客户端。安全问题,因为客户端可以了解所有应用程序(后端)服务器。
示例:kube-proxy,OVN LBtoLogicalSwitch
访问实现图示:
如上图所示,server side lb 是由 lb 代理 clientIP 去进行访问,client side lb 是选择应用程序列表中的 IP,做 dnat 去做访问,也被称为 nat 式 lb。
kubernetes service
kubernetes service 介绍 service
以及 serivce 三种类型的介绍 service type
kubernetes endpoint
在 kubernetes 1.19 后,默认使用 endpointslice 来做 service 的 endpoint。
kube-proxy
kube-proxy 有 iptables 和 ipvs 两种实现方式。默认使用 ipvs (安装 ipvs 情况下)
ipvs vs. iptables
kube-proxy 支持 iptables 和 ipvs 两种模式, 在 kubernetes v1.8 中引入了 ipvs 模式,ipvs 和 iptables 都是基于netfilter的,那么 ipvs 模式和 iptables 模式之间有哪些差异呢?
ipvs 为大型集群提供了更好的可扩展性和性能
ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等等)
ipvs 支持服务器健康检查和连接重试等功能
ipvs 依赖 iptables
ipvs 会使用 iptables 进行包过滤、SNAT、masquared(伪装)。具体来说,ipvs 将使用 ipset 来存储需要 DROP 或 masquared 的流量的源或目标地址,以确保 iptables 规则的数量是恒定的,这样我们就不需要关心我们有多少服务了。
kubernetes iptables 实现
自定义链中数据包的详细流转可以参考:
与 iptables 互动顺序为
流量流转分析
集群内部访问 clusterIP
查看示例 service
Name: service-nginx-public
Namespace: default
Labels: <none>
Annotations: k8s.v1.cni.cncf.io/networks: attachnet
ovn.kubernetes.io/vpc: ovn-cluster
Selector: app=vmirs
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.107.218.177
IPs: 10.107.218.177
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.16.0.119:80,10.16.0.89:80
Session Affinity: None
Events: <none>
iptables 链顺序
PRE-ROUTING -> KUBE-SERVICES -> KUBE-SVC-XXX -> KUBE-SEP-XXX
Chain PREROUTING (policy ACCEPT)
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
Chain KUBE-SERVICES (2 references)
KUBE-SVC-EVALHPSNWHYWZULM tcp -- 0.0.0.0/0 10.107.218.177 /* default/service-nginx-public cluster IP */ tcp dpt:80
Chain KUBE-SVC-EVALHPSNWHYWZULM (1 references)
target prot opt source destination
KUBE-MARK-MASQ tcp -- !10.16.0.0/16 10.107.218.177 /* default/service-nginx-public cluster IP */ tcp dpt:80
KUBE-SEP-IQ42Q3U7IM4YHIW4 all -- 0.0.0.0/0 0.0.0.0/0 /* default/service-nginx-public */ statistic mode random probability 0.50000000000
KUBE-SEP-JGH5UN6XZON73FAC all -- 0.0.0.0/0 0.0.0.0/0 /* default/service-nginx-public */
Chain KUBE-SEP-IQ42Q3U7IM4YHIW4 (1 references)
target prot opt source destination
KUBE-MARK-MASQ all -- 10.16.0.119 0.0.0.0/0 /* default/service-nginx-public */
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/service-nginx-public */ tcp to:10.16.0.119:80
Chain KUBE-SEP-JGH5UN6XZON73FAC (1 references)
target prot opt source destination
KUBE-MARK-MASQ all -- 10.16.0.89 0.0.0.0/0 /* default/service-nginx-public */
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/service-nginx-public */ tcp to:10.16.0.89:80
外部访问 nodePort
在 nodePort 方式下,会用到 KUBE-NODEPORTS 规则链, KUBE-NODEPORTS 位于 KUBE-SERVICE 链的最后一个。
1、非本机访问
PREROUTING --> KUBE-SERVICE --> KUBE-NODEPORTS --> KUBE-SVC-XXX --> KUBE-SEP-XXX
2、本机访问
OUTPUT --> KUBE-SERVICE --> KUBE-NODEPORTS --> KUBE-SVC-XXX --> KUBE-SEP-XXX
KUBE-NODEPORTS
KUBE-SVC-EVALHPSNWHYWZULM tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/service-nginx-public */ tcp dpt:30467
在 KUBE-NODEPORTS 链设置 mark 标记并转发到 KUBE-SVC-5SB6FTEHND4GTL2W,nodeport 与 clusterIP 访问方式最后都是转发到了 KUBE-SVC-xxx 链。
endpointslice
从 1.19 后,使用 endpointslice 同步 service 规则。
在 Kubernetes 中,EndpointSlice 包含对一组网络端点的引用。 指定选择器后控制面会自动为设置了 selector 的 Kubernetes 服务创建 EndpointSlice。 这些 EndpointSlice 将包含对与服务选择算符匹配的所有 Pod 的引用。 EndpointSlice 通过唯一的协议、端口号和服务名称将网络端点组织在一起。
EndpointSlice 将包含不超过 100 个端点。 可以使用 kube-controller-manager 的 --max-endpoints-per-slice 设置
endpointslice.kubernetes.io/managed-by 标明哪个实体在管理某个 EndpointSlice,endpointslice-controller.k8s.io 是根据 service selector,endpointsliceminitoring-controller.k8s.io 从 endpoint 同步(在无 selector service 时使用)
kubernetes.io/service-name 所属 service
控制面不对 Endpoints 资源进行映射的情况有:
- Endpoints 资源上标签 endpointslice.kubernetes.io/skip-mirror 值为 true。
- Endpoints 资源包含标签 control-plane.alpha.kubernetes.io/leader。
- 对应的 Service 资源不存在。
- 对应的 Service 的选择算符不为空。