在实际使用中,两个K8s集群之间的服务经常有互相访问和访问集群外部某些服务的需求,通常的解决方案为手动维护固定的Services和Endpoints或者直接在业务配置中写死IP,在这时候,是没有对外部服务进行探活的功能的,无法做到高可用。如果需要高可用一般是引入外部高可用LB来解决,但这样增加了复杂度,且好多公司不具备引入条件,不是最优解决方案。
众所周知,Kube-Proxy的主要功能是维护集群内Services和Endpoints并在对应主机上创建对应的IPVS规则。从而达到我们可以在Pod里面通过ClusterIP访问的目的。
由此,新的想法诞生了:
写一个controller,维护一个CRD来自动创建需要访问的外部服务对应的Service和Endpoint,并对创建的Endpoint中的外部服务数据(IP:PORT列表)进行探活,探活失败则移除对应的外部服务数据。
于是 "endpoints-operator"项目隆重登场!
endpoints-operator是一个云原生、高可靠性、高性能、面向K8s内部服务访问外部服务的具备探活功能的4层LB。
主要使用在集群内部的Pod需要访问外部服务的场景,比如数据库、中间件等,通过endpoints-operator的探活能力,可及时将有问题的后端服务剔除,避免受单个宕机副本影响,并可查看status获取后端服务健康状态和探活失败的服务。
git clone https://github.com/sealyun/endpoints-operator.git
cd endpoints-operator
checkout v0.1.0
helm install -n kube-system endpoints-operator config/charts/endpoints-operator
创建一个健康的ClusterEndpoint数据
apiVersion: sealyun.com/v1beta1
kind: ClusterEndpoint
metadata:
name: wordpress
namespace: default
spec:
hosts:
- 172.18.191.215
periodSeconds: 10
ports:
- failureThreshold: 3
name: https
port: 38082
protocol: TCP
successThreshold: 1
targetPort: 80
tcpSocket:
enable: true
timeoutSeconds: 1
- httpGet:
path: /
scheme: http
name: http
port: 38081
protocol: TCP
targetPort: 80
经过controller处理后发现
apiVersion: sealyun.com/v1beta1
kind: ClusterEndpoint
metadata:
creationTimestamp: "2022-01-18T13:44:08Z"
generation: 1
name: wordpress
namespace: default
resourceVersion: "610358"
uid: 41303de7-9706-487a-8204-79a3a358730f
spec:
hosts:
- 172.18.191.215
periodSeconds: 10
ports:
- failureThreshold: 3
name: https
port: 38082
protocol: TCP
successThreshold: 1
targetPort: 80
tcpSocket:
enable: true
timeoutSeconds: 1
- httpGet:
path: /
scheme: http
name: http
port: 38081
protocol: TCP
targetPort: 80
status:
conditions:
- lastHeartbeatTime: "2022-01-18T13:44:08Z"
lastTransitionTime: "2022-01-18T13:44:08Z"
message: cluster endpoints has been initialized
reason: Initialized
status: "True"
type: Initialized
- lastHeartbeatTime: "2022-01-18T13:44:08Z"
lastTransitionTime: "2022-01-18T13:44:08Z"
message: sync service successfully
reason: SyncServiceReady
status: "True"
type: SyncServiceReady
- lastHeartbeatTime: "2022-01-18T13:44:08Z"
lastTransitionTime: "2022-01-18T13:44:08Z"
message: sync endpoint successfully
reason: SyncEndpointReady
status: "True"
type: SyncEndpointReady
- lastHeartbeatTime: "2022-01-18T13:44:08Z"
lastTransitionTime: "2022-01-18T13:44:08Z"
message: ClusterEndpoint is available now
reason: Ready
status: "True"
type: Ready
phase: Healthy
验证Service和Endpoint数据
已经正常处理数据
ClusterEndpoint数据status变更
将其中一个端口立即关掉则cep的状态已经变为UnHealthy
| 总结
"endpoints-operator” 的引入,对产品无侵入以及云原生等特性解决了在集群内部访问外部服务等问题。这个思路将会成为以后开发或者运维的标配,也是一个比较完善的项目,从开发的角度换个思路更优雅的去解决一些问题。新功能将会支持更多的探活协议比如UDP\GRPC等。还支持监控以及webhook校验等功能。
有兴趣欢迎到GitHub贡献代码: https://github.com/sealyun/endpoints-operator