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

共 4486字,需浏览 9分钟

 ·

2022-01-24 07:39


在实际使用场景中,两个 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 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 数据

$ 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           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           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 贡献代码 : https://github.com/sealyun/endpoints-operator

引用链接

[1]

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


你可能还喜欢

点击下方图片即可阅读

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

云原生是一种信仰 🤘

关注公众号

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



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


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

浏览 61
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报