d4ilys / Carp.Gateway

C#.NET 基于Yarp实现的API网关Gateway,支持Kubernetes、Consul
MIT License
56 stars 15 forks source link

Daily.Carp.Provider.Kubernetes升级0.6.6后报错处理方式 #5

Open d4ilys opened 3 months ago

d4ilys commented 3 months ago

需要增加service读取权限

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: read-endpoints
  namespace: dev
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - pods
  - services    #增加service读取权限
  verbs:
  - get
  - list
  - watch
vxueshan commented 3 months ago

想问个问题,集成K8S最后取的是 kubeService.Spec.ClusterIP,取这个ClusterIP使用和直接使用http://servicename.default.svc.cluster.local有什么区别吗? 关于集成consul的,consul里的service下的IP为podip,更新app应用后,旧podip立马就没有了,这时yarp内存中还使用的旧podip,访问就报错了。3秒或1秒轮询一次,或更短,访问量大时,总会出错,而且有100多consul服务时,短时间内也轮询不完啊。ocelot集成consul时,是每次都根据服务名去查询consul里的服务IP的,效率有点低。所以我感觉在K8S里,就不需要consul了。

d4ilys commented 3 months ago

@vxueshan

Daily.Carp.Provider.Kubernetes这个包是自动获取 Service的Cluster IP,也就是说你只需要写ServiceName,不需要关心ClusterIP或内部DNS解析

该包会自动维护Service的的地址

  "Carp": {
    "Routes": [
      {
        "Descriptions": "日志服务",
        "ServiceName": "LoggerService",
        "PathTemplate": "/api/{**catch-all}",   
        "TransmitPathTemplate": "{**catch-all}"
      }
    ]
  }

如果使用内部DNS服务,或者指定DownstreamHostAndPorts,Daily.Carp.Provider.Kubernetes则会跳过自动获取

  "Carp": {
    "Routes": [
      {
        "Descriptions": "日志服务",
        "ServiceName": "LoggerService",
        "PathTemplate": "/api/{**catch-all}",   
        "TransmitPathTemplate": "{**catch-all}",  
        "DownstreamHostAndPorts": [ "http://servicename.default.svc.cluster.local" ]
      }
    ]
  }

效果基本是一样的,看自己喜欢哪一种方式。

至于Consul应该是无法做到Kuberntes这种滚动更新实现无感升级。

有Kuberntes就不需要Consul,因为Kuberntes Service其实就是服务注册发现

我做这个库的目的其实就是整合Yarp和Kubernetes,并且可以最大程度做到无感知升级

在滚动更新Pod时,可能还会有少量的请求调度到不可用的Pod导致502异常,但是Yarp中没有支持重试机制,这一块在Carp.Gateway未来版本会逐步优化实现真正的无感升级.