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

545190296e13fa365d826447e4d48eae.gif

在实际使用场景中,两个 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   <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 贡献代码 : https://github.com/sealyun/endpoints-operator

引用链接

[1]

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

90298cbb91af093d7a564c18e16b5a9d.gif

501bff71ae59324dca302f69123662e5.png

你可能还喜欢

点击下方图片即可阅读

c65deacfad3d49a8d37b473c9a296644.png

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

49b4f36cf7b482967790119161798472.gif

云原生是一种信仰 🤘

关注公众号

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

63dbdaff5a8b8b6fa19095f26325883d.gif

9b0084adfbc2563325a4bf4c0c02c8bd.gif

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

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

2810fe23a353ec2224cfc6bab93d1335.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值