2023年6月,我们与一位客户展开合作,帮助客户做容器化转型,客户拥有10多家已经完成容器化改造的 ISV(Independent Software Vendor),客户需要一个PaaS 容器云平台,对供应商软件的资源配额、服务暴露、存储、配置等进行统一管理。
于是我们基于 Kubernetes 1.21.0,交付了一款容器云管理平台的 PaaS 产品,在部署过程中,遇到了一个关于 slb 的问题,并调研了4种解决方案,最终解决。
当检测到是自己发出的请求后,slb 直接把这个包给丢了
官方文档的解释:
由于供应商众多,且对高可用要求很高,所以在整个架构上,再加2台4C8G的机器,部署一套 HaProxy + KeepAlive,这也是 kubernetes 标准部署推荐的负载均衡方案,用以代替原来的 SLB。
但这样的一个缺点是,在一个集群里,用了两种 slb 产品,对一个强迫症患者而言,架构上有东拼西揍的混乱感。
最简单且改动最小的方案,只有master-slb下的3台机器,访问方式从 master-slb-ip,改成 localhost 本地访问,其他 worker 节点,依然保持走 master-slb-ip。
在 default 命名空间下,有一个名为 kubernetes 的 svc,这是kubernetes 自带的master节点的服务暴露方式,describe 其service,可以看到endpoint的值是集群3台master的nodeIP,通过轮询的策略,将流量分发到不同的 master 节点。
使用 kubernetes 内部svc的方式,相比上面 localhost 方案,可用性更高;且通过 svc 访问服务,比直接通过 localhost 访问,在使用规范上,更符合 kubernetes 的设计理念。
[root@172 ~]# k describe svc kubernetes -n default
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 11.3.0.1
IPs: 11.3.0.1
Port: https 443/TCP
TargetPort: 6443/TCP
Endpoints: master1nodeIP:6443,master2nodeIP:6443,master3nodeIP:6443
Session Affinity: None
Events: <none>
在原来的架构里,我们申请的slb端口是 TCP 协议,期间查询到负载均衡协议变更为 HTTPS 后,可以实现slb backend server 访问 slb 本身,于是我们考虑先将 SLB 四层 TCP 协议变更为七层HTTPS协议,这样对我们的架构改动性最小。
但在变更后发现,SLB 变更为 HTTPS 协议后,其后端协议只支持 HTTP,而我们6443的 Apiserver 服务是一个https服务,协议无法兼容,于是出现了下面的报错,这个方案夭折。
slb 下面的机器,访问自己上层的slb,这是一个十分常见且合理的场景,
一些硬件负载均衡设备,如 A5,F10是支持这样访问的,部分云厂商的负载均衡产品也支持;但部分云厂商负载均衡产品不支持这样的场景。
因为无法看到slb产品内部的实现,只能猜测slb产品经理可能是出于性能优化/安全的考虑,从设计上阻止了这类场景,
对于kubernetes集群,面对这样的现状,我们是可以进行改造,集群内部流量走 svc,外部流量走slb,来规避slb的这个缺陷,
但是对于未完成容器化改造,需要ECS 虚拟机部署的ISV,在同样的需求和现状下,他们唯一的方式就是弃用slb了。
这是一个坏设计