github.com/lingyao2333/mo-zero@v1.4.1/zrpc/resolver/internal/kubebuilder.go (about) 1 package internal 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/lingyao2333/mo-zero/core/logx" 9 "github.com/lingyao2333/mo-zero/core/proc" 10 "github.com/lingyao2333/mo-zero/core/threading" 11 "github.com/lingyao2333/mo-zero/zrpc/resolver/internal/kube" 12 "google.golang.org/grpc/resolver" 13 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 "k8s.io/client-go/informers" 15 "k8s.io/client-go/kubernetes" 16 "k8s.io/client-go/rest" 17 ) 18 19 const ( 20 resyncInterval = 5 * time.Minute 21 nameSelector = "metadata.name=" 22 ) 23 24 type kubeBuilder struct{} 25 26 func (b *kubeBuilder) Build(target resolver.Target, cc resolver.ClientConn, 27 _ resolver.BuildOptions) (resolver.Resolver, error) { 28 svc, err := kube.ParseTarget(target) 29 if err != nil { 30 return nil, err 31 } 32 33 config, err := rest.InClusterConfig() 34 if err != nil { 35 return nil, err 36 } 37 38 cs, err := kubernetes.NewForConfig(config) 39 if err != nil { 40 return nil, err 41 } 42 43 handler := kube.NewEventHandler(func(endpoints []string) { 44 var addrs []resolver.Address 45 for _, val := range subset(endpoints, subsetSize) { 46 addrs = append(addrs, resolver.Address{ 47 Addr: fmt.Sprintf("%s:%d", val, svc.Port), 48 }) 49 } 50 51 if err := cc.UpdateState(resolver.State{ 52 Addresses: addrs, 53 }); err != nil { 54 logx.Error(err) 55 } 56 }) 57 inf := informers.NewSharedInformerFactoryWithOptions(cs, resyncInterval, 58 informers.WithNamespace(svc.Namespace), 59 informers.WithTweakListOptions(func(options *v1.ListOptions) { 60 options.FieldSelector = nameSelector + svc.Name 61 })) 62 in := inf.Core().V1().Endpoints() 63 in.Informer().AddEventHandler(handler) 64 threading.GoSafe(func() { 65 inf.Start(proc.Done()) 66 }) 67 68 endpoints, err := cs.CoreV1().Endpoints(svc.Namespace).Get(context.Background(), svc.Name, v1.GetOptions{}) 69 if err != nil { 70 return nil, err 71 } 72 73 handler.Update(endpoints) 74 75 return &nopResolver{cc: cc}, nil 76 } 77 78 func (b *kubeBuilder) Scheme() string { 79 return KubernetesScheme 80 }