1. 会话亲和性(Session Affinity,即持久化连接)详解
1.1 与IPVS源地址散列(Source Hash,SH)算法的对比
- 源地址散列(SH)算法:基于客户端IP做哈希计算,只要哈希表未被清理,同一客户端会始终被定向到同一台后端真实服务器(Real Server,RS),不考虑集群负载均衡状态,调度逻辑较为呆板
- 持久化连接:在配置的超时时间范围内,将同一客户端的请求定向到同一台后端RS,超时时间到期后绑定记录清除,后续请求会重新按负载调度算法分配,兼顾了会话固定与负载均衡的灵活性
1.2 持久化连接核心机制
IPVS实现持久化连接可通过ipvsadm工具配置,核心参数为-p,用于指定持久化超时时间,单位秒,示例配置命令如下:
# 添加IPVS规则,指定调度算法为轮询(rr),持久化超时时间120秒
ipvsadm -A 192.168.66.1:80 -s rr -p 120
运行逻辑:
- 客户端首次访问时,若IPVS中无该客户端与后端的绑定记录,则按配置的调度算法分配后端RS
- 分配完成后,建立客户端IP+端口与后端RS的映射绑定,绑定附带超时时间
- 超时时间会随时间逐渐衰减,衰减期间同一客户端再次访问会直接命中已有绑定,定向到同一台后端
- 若绑定未过期时客户端再次访问,超时时间会重新计算,实现时间叠加恢复
- 超时时间衰减至0后,绑定记录被清除,客户端后续访问会重新按调度算法分配后端
1.3 适用场景
核心适用于HTTPS负载均衡场景:HTTPS建连需要完成SSL版本协商、加密算法确定、密钥交换等流程,若建连后下一次请求被调度到其他后端,需要重复完成HTTPS握手,造成资源浪费,持久化连接可避免该问题。
持久化连接常见分类包括基于客户端、基于端口、基于防火墙标记三类,K8s Service默认采用基于客户端的实现方式。
1.4 K8s Service中的会话亲和性配置
K8s Service的会话亲和性底层基于IPVS持久化连接实现,配置方式如下:
- 开启配置:在Service的
spec.sessionAffinity字段设置为ClientIP - 超时时间配置:在
spec.sessionAffinityConfig.clientIP.timeoutSeconds字段设置,默认值为10800秒(3小时),取值范围为1~86400秒(1天),必须大于0且小于等于86400
1.5 实验验证效果与操作
- 基础操作:通过
kubectl get pod查看后端Pod状态,确认Pod就绪且标签匹配Service选择器;通过kubectl get svc查看Service信息 - 未开启会话亲和性效果:Service默认调度算法为轮询(rr),多次访问会负载到不同的后端Pod
- 开启会话亲和性操作:通过
kubectl edit service <service-name>修改Service的sessionAffinity字段为ClientIP,保存退出 - 开启后效果:在超时时间内,同一客户端的请求始终被定向到同一台后端Pod,超时后重新按轮询调度
- 底层验证:通过
ipvsadm -L查看IPVS规则,可看到对应规则开启了持久化连接,显示persistent字段,默认超时时间为10800秒 - 注意事项:实验过程中Service类型为Local时仅支持集群内部访问,若需要外部访问需将类型修改为ClusterIP
2. NodePort类型Service详解
2.1 定位与特性
NodePort是ClusterIP类型的升级版,不仅拥有ClusterIP的全部功能(支持集群内部通过ClusterIP负载均衡访问服务),还支持将服务暴露到集群外部,通过节点物理网卡的指定端口提供外部访问。
选型建议:若无需对外提供服务,优先使用ClusterIP类型,避免NodePort带来的额外资源消耗,功能越多资源开销越高。
2.2 配置规则
NodePort Service支持配置多个端口映射,每个端口需要明确以下字段:
name:端口映射的名称,同一Service下多个端口映射的name不能重复port:集群内部访问Service时使用的端口(即ClusterIP对应的端口)targetPort:后端Pod的真实业务端口nodePort:节点物理网卡绑定的对外端口
端口要求:nodePort默认端口范围为30000~32767,官方强烈建议不手动指定该端口,由K8s自动分配,避免端口冲突;也可通过修改IPVS启动参数自定义端口范围- 多个端口映射的
name、port、targetPort、nodePort需一一对应,否则会出现冲突
2.3 工作原理
NodePort底层基于IPVS实现:
- K8s会在集群每个节点的所有可用网卡(包括物理网卡、docker0等虚拟网卡)上,绑定配置的
nodePort端口 - 为每个节点的对应网卡配置IPVS负载均衡规则,将访问节点
nodePort端口的请求,负载到后端匹配的Pod - 外部访问可通过
<节点IP>:<nodePort>实现,同时支持集群内部通过Service DNS(<service-name>.<namespace>.svc.cluster.local)访问
2.4 实验验证要点与操作
- 资源创建:先通过Deployment创建3个副本的Nginx Pod,标签匹配Service选择器;再创建NodePort类型的Service,示例中自动分配的
nodePort为30010 - 集群内部访问验证:通过
curl <cluster-ip>:<port>、curl <service-name>.<namespace>.svc.cluster.local访问,验证负载均衡效果,多次访问会切换到不同后端Pod - 外部访问验证:通过浏览器或
curl <node-ip>:<nodePort>访问任意节点的对应端口,验证服务可正常访问且具备负载均衡效果;任意节点故障时,其他节点的对应端口仍可正常提供服务 - 底层验证:通过
ipvsadm -L查看IPVS规则,确认每个节点的所有可用网卡都绑定了nodePort端口的负载均衡规则 - 生产环境建议:通常会在NodePort外层再配置一层独立负载均衡,将流量调度到所有集群节点,避免单节点故障导致用户访问中断
AI 总结
本次视频主要讲解了K8s Service的两类核心特性:一是会话亲和性(基于IPVS持久化连接实现),对比了其与源地址散列算法的差异,明确了HTTPS场景下的适用性,以及K8s中的配置方法、默认规则与实验效果;二是NodePort类型Service,明确了其作为ClusterIP升级版的定位、配置规范、工作原理与访问逻辑,同时通过实验验证了两种Service的实际运行效果,最后给出了不同类型Service的选型建议。