Kubernetes 负载均衡

Service

Service 对象

1698237656931

  • Service Selector: 用来选定一组Pod

  • Ports:

    • targetPort: targetPort字段定义了Service将流量转发到后端Pod的容器端口号。当请求进入Service时,Service会根据其定义将请求转发到后端Pod的这个指定端口。通常,后端Pod中的应用程序在指定的容器端口上监听并处理请求。
    • port: port字段定义了Service暴露给集群内部和外部的端口号。当你创建一个Service时,其他应用或服务可以通过该端口与Service进行通信,将请求发送到Service上。这个端口号是Service在Kubernetes集群内部和外部可见的端口。

    clusterip
    在默认的服务类型中,k8s系统给service自动分配虚拟IP,只能在集群内部访问。其主要工作原理是:
    ClusterIP类型的service创建时,k8s会通过etcd从可分配的ip池中分配一个全局唯一、不可修改的ip。所有访问该ip的请求,都会被iptables转发到后端的endpoints中。

EndPoint 对象

  • 在Service创建的时候, 同时会创建Endpoint对象
  • 主要用来描述Service 和 Pods 之间的映射关系

1698238260421

EndpointSlice

1698239246176

不定义Selector 的Service

可以用来连接外部访问, 类似于创建了一个访问集群外部服务的一个负载均衡

1698239878492

Service、Endpoint 和pod 的对应关系

1698241049476

  • 通过ClusterIp 对外提供统一ip入口, 并且对Endpoinds 进行负载均衡

Service的类型

当定义nodePort 类型的Service 会同时有clusterIP配置

当定义了LoadBalancer 类型的Service 会同时配置clusterIP 和 nodePort

1698276487706

1698276854513

Service Topology

1698277054528

1698277144671

kube-proxy

kube-proxy 介绍

1698277191222

kube-proxy 工作原理

1698279841811

iptable

iptable hook 流程

1698281699725

iptable nat表

kube-proxy 核心是通过修改iptable 的dnat 规则, 实现的负载均衡

查看nat表

1
2
3
4
5
6
iptables -L  -t nat
# -L: list
# -t: 规则类型

iptable-save -t nat
# 打印iptable规则, 用来回放

一组实际的iptable 配置

1698280047827

注意 clusterIp 是不能ping通的, 因为clusterIp并没有绑定在某个物理网卡上, 但是是可以访问的

IPVS

ipvs 的hook点

ipvs 和 iptable 的hook 点不一样, 不可以在prerouting处进行路由改写,

所以要起虚拟网卡, 通过绑定clusterIp, 让kernel 可以接受 clusterIp的请求

因为也没有POSROUTING, 所以不能通过pod地址进行数据发送, 所以, 要再发送钱进行ip伪装, 这里依然要借助iptable协助完成

1698281756454

如何切换kube-proxy 为 IPVS 模式

1
2
3
kubectl edit configmap kube-proxy
# 修改 mod为ipvs
# 然后重启kube-proxy 的pod

查看ipvs规则

1
ipvsadm -L

1698282668491

Core DNS

Core DNS 组件介绍

image-20231028135225298

在pod 中, 查看 /etc/resolv.conf 可以看到配置了nameserver的地址, 实际上就是coreDNS组件的ClusterIP

不同类型的DNS 服务

image-20231028140152093

Kugenetes 中的域名解析

image-20231028140451506

关于DNS 的落地实践

image-20231028140748843

kubenetes 中的负载均衡技术

image-20231028141846732

Service 和 Ingress 对比

image-20231028142242670

INgress 组件功能介绍

image-20231028142513616

  • Ingress: 是自kubernetes1.1版本后引入的资源类型,在这个资源中我们可以去配置我们的服务路由规则,但是要真正去实现识别这个 Ingress 并提供代理路由功能,还需要安装一个对应的控制器Ingress controller才能实现。

  • Ingress controller: 是以一种插件的形式提供,有多种实现,例如官方维护的Ingress NGINX。Ingress controller 是部署在Kubernetes之上的Docker容器。它的Docker镜像包含一个像Nginx或HAProxy的负载均衡器和一个控制器守护进程。控制器守护程序从Kubernetes接收所需的Ingress配置。它会生成一个Nginx或HAProxy配置文件,并重新启动负载平衡器进程以使更改生效。换句话说,Ingress controller是由Kubernetes管理的负载均衡器。

    nginx-ingress-controller 的pod 由单一的容器构成, 其内主要有三类进程: IngressController、NginxMaster、NginxWorker。 IC 通过Watch kubenetes api 读取ingress对象的更新, 通过模板文件创建对应的nginx配置文件, 写入/etc/nginx目录, 然后IC 运行 nginx -s reload 命令重载nginx配置, 使负载均衡配置生效。

Ingress Spec

image-20231028144150752

ingress 原理

1、数据流向
ingress为七层负载均衡,理解为nginx。源于官网的数据流向图,客户端访问进入ingress,ingress根据域名进行解析 ,随后找到关联的service服务获取pod信息,直接代理至pod节点

1698883003812

2、ingress 模式 hostnetwork nodeport
hostnetwork模式:

1698883015780

每个节点都创建一个ingress-controller的容器,容器的网络模式设为hostNetwork。访问请求通过80/443端口将直接进入到pod-nginx中。而后nginx根据ingress规则再将流量转发到对应的web应用容器中。

nodeport模式 :

1698883034709

访问流量先通过nodeport进入到node节点,经iptables (svc) 转发至ingress-controller容器,再根据rule转发至后端各业务的容器中。

传统k8s 高可用网络拓扑

高可用架构待解决问题

image-20231029100116888

image-20231029100628179

刘小恺(Kyle) wechat
如有疑问可联系博主