骚操作,K8s 集群外的 Endpoint 也能动态变化

语言: CN / TW / HK

在实际使用场景中,两个 K8s 集群之间经常有互相访问的需求,或者 K8s 集群有访问集群外部某些服务的需求,常规的解决方案是手动维护固定的 Services 和 Endpoints,或者直接在业务配置中写死 IP。但这些方案都没有对外部服务的探活功能,无法实现高可用。如果引入外部高可用负载均衡,又会增加复杂度,且很多公司不具备引入外部负载均衡的条件,所以这个方案不是最优解。

众所周知,kube-proxy 的主要功能是维护集群内的 Services 和 Endpoints,并在对应主机上创建对应的 IPVS 规则,因此 Pod 之间可以通过 ClusterIP 相互访问。

受 kube-proxy 启发,新的想法诞生了: 编写一个 Controller,维护一个 CRD 来自动创建需要访问的外部服务所对应的 Service 和 Endpoint,并对创建的 Endpoint 中的外部服务数据(IP:Port 列表)进行探活,探活失败则移除对应的外部服务数据。

于是 endpoints-operator [1] 项目隆重登场!

endpoints-operator 介绍

endpoints-operator 是一个云原生、高可靠性、高性能、面向 K8s 内部服务访问外部服务的具备探活功能的 4 层 LB。

特性

  • 更加贴近云原生

  • 声明式 API:探活的定义方式与 Kubelet 保持一致,还是熟悉的语法、熟悉的味道

  • 高可靠性:原生 Service、Endpoint 资源,拒绝重复造轮子

  • 高性能、高稳定:原生 IPVS 高性能 4 层负载均衡

核心优势

  • 完全使用 K8s 原生的 Service、Endpoint 资源,无自定义 IPVS 策略,依托 K8s 的 Service 能力,高可靠。

  • 通过 controller 管理一个 CRD 资源 ClusterEndpoint(缩写 cep)即可,无需手动管理 Service 和 Endpoint 两个资源

  • 完全兼容已有的自定义 Service、Endpoint 资源,可无缝切换至 endpoints-operator 管理。

  • 原生的 IPVS 4 层负载,未引入 Nginx、HAProxy 等 LB,降低了复杂度,满足高性能和高稳定性的需求

使用场景

主要使用在集群内部的 Pod 需要访问外部服务的场景,比如数据库、中间件等,通过 endpoints-operator 的探活能力,可及时将有问题的后端服务剔除,避免受单个宕机副本影响,并可查看 status 获取后端服务健康状态和探活失败的服务。

使用介绍

安装

$ git clone http://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 数据

$ kubectl get cep wordpress
NAME AGE STATUS
wordpress 108m Healthy

$ kubectl get svc wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress ClusterIP 10.104.2.110 <none> 38082/TCP,38081/TCP 108m

$ kubectl get ep wordpress
NAME ENDPOINTS AGE
wordpress 172.18.191.215:80,172.18.191.215:80 108m

ClusterEndpoint 数据 status 变更

将其中一个端口立即关掉则 cep 的状态已经变为 UnHealthy

$ kubectl get cep wordpress
NAME AGE STATUS
wordpress 115m UnHealthy

$ kubectl get svc wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
wordpress ClusterIP 10.104.2.110 <none> 38083/TCP,38081/TCP 115m

$ kubectl get ep wordpress
NAME ENDPOINTS AGE
wordpress 172.18.191.215:80 115m

总结

endpoint-operator 从开发的角度更优雅地解决了集群内访问外部服务的问题,实现方式更加云原生,对产品无任何侵入。后续将会支持更多的探活协议,比如 UDP/gRPC 等。还会支持监控以及 Webhook 校验等功能。

有兴趣欢迎到 GitHub 贡献代码 : http://github.com/sealyun/endpoints-operator

引用链接

[1]

endpoints-operator: http://github.com/sealyun/endpoints-operator

你可能还喜欢

点击下方图片即可阅读

Kubernetes 集群文件描述符测漏了...

云原生是一种信仰 

关注公众号

后台回复◉k8s◉获取史上最方便快捷的 Kubernetes 高可用部署工具,只需一条命令,连 ssh 都不需要!

点击  "阅读原文"  获取 更好的阅读体验!

发现朋友圈变“安静”了吗?