slime-io / slime

An intelligent ServiceMesh manager based on Istio
https://slime-io.github.io/
Other
424 stars 78 forks source link

lazyload should support smartdns #385

Open Patrick0308 opened 1 year ago

Patrick0308 commented 1 year ago

问题背景

场景一: 在多集群环境中,当要被调用的服务不在本集群中,如果不开启 smart dns,请求调用时会解析 host 失败。

场景二: istio serviceentries 也是依赖 smart dns 解析的 host

这两种场景开启 lazyload 模式都会导致请求 host 解析失败。

您想要的解决方案

基本方案

在集群中有一个辅助域名服务,能解析所有集群的 svc host 与 service entries, 并添加到默认的 /etc/resolv.conf 中。

原本的 /etc/resolv.conf :

nameserver 172.20.0.10
search core.svc.cluster.local svc.cluster.local cluster.local vpc.internal ap-east-1.compute.internal
options ndots:5

假如辅助域名服务的 cluster ip 是 172.20.0.11, 新的 /etc/resolv.conf :

nameserver 172.20.0.10 
nameserver 172.20.0.11
search core.svc.cluster.local svc.cluster.local cluster.local vpc.internal ap-east-1.compute.internal
options ndots:5

注意辅助域名服务 的 cluster ip 需要静态化指定。

您考虑过的替代方案

可选方案一: Global Sidecar 的 pilot-agent 做为 辅助域名服务 可选方案二: coredns 返回一个 fakeip

额外的上下文

MouceL commented 1 year ago

关于场景二:

解析出来的那个ip是不是真的并不重要,只要能转发到gs,就能流程走通

所以我们修改了内部的pilotagent,if xx then mock ..

这个做法不够普遍..

Patrick0308 commented 1 year ago

@MouceL 两个场景解析出来的 ip 是什么都不太重要,只要 dns 正常就行。

Patrick0308 commented 1 year ago
  1. 当发现 eds 中都不是本集群的节点(通过 ip 段判断?),并且 cds 符合 svc 资源特征 ,然后在 mesh-operator 中创建没有 endpoints 的 serviceentry。

不需要确定 cds 的 host 是 svc 的 host,因为我们也要支持 serviceentries 中自定义的 host。

还有一种方式可以让 lazyload 不需要关心 eds,就是直接使用 cds 的 host 做 dns 解析,如果不成功的 host 放到 serviceentries 中。

Patrick0308 commented 1 year ago

我发现 istio coredns plugin 这个能直接解决我们的问题,只是现在不维护了。

Patrick0308 commented 8 months ago

可选方案二: coredns 返回一个 fakeip

如果 svc 域名或者 service entry 无法解析,使用 template plugin 返回 fake ip 1.1.1.2 ,coredns 配置如下:

    .:53 {
      log . {
        class denial success
      }
      errors
      health {
         lameduck 5s
      }
      ready
      kubernetes cluster.local in-addr.arpa ip6.arpa {
         pods insecure
         fallthrough  in-addr.arpa ip6.arpa cluster.local ## 需要配置 cluster.local 到 fallthrough,默认没有这个配置
         ttl 30
      }
      ## 不能解析的 svc cluster  forward 到 127.0.0.1:153  
      forward cluster.local 127.0.0.1:153 {
        max_concurrent 1000
      }
      ## service.entry 结尾的域名  forward 到 127.0.0.1:153  
      forward service.entry 127.0.0.1:153 {
        max_concurrent 1000
      }
      forward . /etc/resolv.conf {
        max_concurrent 1000
      }
      prometheus :9153
      cache 30
      loop
      reload
      loadbalance
    }
    .:153 {
      errors
      health {
         lameduck 5s
      }
      ready
     ## 返回 1.1.1.2
      template IN A cluster.local service.entry {
          match ^(?P<a>[^.]*)\.(?P<b>[^.]*)\.svc\.cluster\.local\.$
          match service\.entry\.$
          answer "{{ .Name }} 60 IN A 1.1.1.2"
      }
      forward . /etc/resolv.conf {
        max_concurrent 1000
      }
      cache 30
      loadbalance
    }

在 coredns 中 template plugin 默认执行顺序先与 kuberntes plugin , forward plugin 执行顺序后于 kubernetes plugin。所以我们监听一个 153 端口,通过 forward 实现我们的需求。

coredns 版本需要大于 1.9.3 ,不然不支持多个 forward 。

MouceL commented 8 months ago

不太熟悉coredns的配置,我来瞧瞧

如果可以,这个确实可以作为一个社区方案,弥补slime对serviceentry支持的不足

Patrick0308 commented 6 months ago

可选方案二: coredns 返回一个 fakeip

如果 svc 域名或者 service entry 无法解析,使用 template plugin 返回 fake ip 1.1.1.2 ,coredns 配置如下:

    .:53 {
      log . {
        class denial success
      }
      errors
      health {
         lameduck 5s
      }
      ready
      kubernetes cluster.local in-addr.arpa ip6.arpa {
         pods insecure
         fallthrough  in-addr.arpa ip6.arpa cluster.local ## 需要配置 cluster.local 到 fallthrough,默认没有这个配置
         ttl 30
      }
      ## 不能解析的 svc cluster  forward 到 127.0.0.1:153  
      forward cluster.local 127.0.0.1:153 {
        max_concurrent 1000
      }
      ## service.entry 结尾的域名  forward 到 127.0.0.1:153  
      forward service.entry 127.0.0.1:153 {
        max_concurrent 1000
      }
      forward . /etc/resolv.conf {
        max_concurrent 1000
      }
      prometheus :9153
      cache 30
      loop
      reload
      loadbalance
    }
    .:153 {
      errors
      health {
         lameduck 5s
      }
      ready
     ## 返回 1.1.1.2
      template IN A cluster.local service.entry {
          match ^(?P<a>[^.]*)\.(?P<b>[^.]*)\.svc\.cluster\.local\.$
          match service\.entry\.$
          answer "{{ .Name }} 60 IN A 1.1.1.2"
      }
      forward . /etc/resolv.conf {
        max_concurrent 1000
      }
      cache 30
      loadbalance
    }

在 coredns 中 template plugin 默认执行顺序先与 kuberntes plugin , forward plugin 执行顺序后于 kubernetes plugin。所以我们监听一个 153 端口,通过 forward 实现我们的需求。

coredns 版本需要大于 1.9.3 ,不然不支持多个 forward 。

以上配置在开启 smartdns 时存在问题。更新配置如下:

    .:53 {
      log . {
        class denial success
      }
      errors
      health {
         lameduck 5s
      }
      ready
      kubernetes cluster.local in-addr.arpa ip6.arpa {
         pods insecure
         fallthrough  in-addr.arpa ip6.arpa cluster.local
         ttl 30
      }
      forward cluster.local 127.0.0.1:153 {
        max_concurrent 1000
      }
      forward service.entry 127.0.0.1:153 {
        max_concurrent 1000
      }
      forward . /etc/resolv.conf {
        max_concurrent 1000
      }
      prometheus :9153
      cache 30
      loop
      reload
      loadbalance
    }
    .:153 {
      errors
      health {
         lameduck 5s
      }
      ready
      template IN A cluster.local service.entry {
          match ^(?P<a>[^.]*)\.(?P<b>[^.]*)\.svc\.cluster\.local\.$
          match service\.entry.$
          answer "{{ .Name }} 60 IN A 1.1.1.2"
      }
      template IN AAAA cluster.local service.entry {
          match ^(?P<a>[^.]*)\.(?P<b>[^.]*)\.svc\.cluster\.local\.$
      }
      forward . /etc/resolv.conf {
        max_concurrent 1000
      }
      cache 30
      loadbalance
    }