@@ -20,115 +20,119 @@ import (
20
20
"net"
21
21
"net/netip"
22
22
"slices"
23
+ "time"
23
24
24
25
clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
25
26
v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
26
27
endpointv3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
27
28
"google.golang.org/protobuf/types/known/wrapperspb"
28
- "k8s.io/client-go/util/workqueue"
29
29
30
30
core_v2 "kmesh.net/kmesh/api/v2/core"
31
31
"kmesh.net/kmesh/pkg/dns"
32
32
)
33
33
34
34
// adsDnsResolver is DNS resolver of Kernel Native
35
- type AdsDnsResolver struct {
36
- Clusters chan []* clusterv3.Cluster
37
- adsCache * AdsCache
38
- dnsResolver * dns.DNSResolver
39
- dnsRefreshQueue workqueue.TypedDelayingInterface [any ]
35
+ type dnsController struct {
36
+ Clusters chan []* clusterv3.Cluster
37
+ cache * AdsCache
38
+ dnsResolver * dns.DNSResolver
40
39
}
41
40
42
- func NewAdsDnsResolver (adsCache * AdsCache ) (* AdsDnsResolver , error ) {
41
+ // pending resolve domain info of Kennel-Native Mode,
42
+ // domain name is used for dns resolution
43
+ // cluster is used for create the apicluster
44
+ type pendingResolveDomain struct {
45
+ DomainName string
46
+ Clusters []* clusterv3.Cluster
47
+ RefreshRate time.Duration
48
+ }
49
+
50
+ func NewDnsResolver (adsCache * AdsCache ) (* dnsController , error ) {
43
51
resolver , err := dns .NewDNSResolver ()
44
52
if err != nil {
45
53
return nil , err
46
54
}
47
- return & AdsDnsResolver {
48
- Clusters : make (chan []* clusterv3.Cluster ),
49
- dnsRefreshQueue : workqueue .NewTypedDelayingQueueWithConfig (workqueue.TypedDelayingQueueConfig [any ]{Name : "dnsRefreshQueue" }),
50
- adsCache : adsCache ,
51
- dnsResolver : resolver ,
55
+ return & dnsController {
56
+ Clusters : make (chan []* clusterv3.Cluster ),
57
+ // dnsRefreshQueue: workqueue.NewTypedDelayingQueueWithConfig(workqueue.TypedDelayingQueueConfig[any]{Name: "dnsRefreshQueue"}),
58
+ cache : adsCache ,
59
+ dnsResolver : resolver ,
52
60
}, nil
53
61
}
54
62
55
- func (adsResolver * AdsDnsResolver ) StartAdsDnsResolver (stopCh <- chan struct {}) {
56
- go adsResolver .startAdsResolver ()
57
- go adsResolver .refreshAdsWorker ()
63
+ func (r * dnsController ) StartKernelNativeDnsController (stopCh <- chan struct {}) {
64
+ go r .startDnsController ()
65
+ // start dns resolver
66
+ go r .dnsResolver .StartDnsResolver (stopCh )
58
67
go func () {
59
68
<- stopCh
60
- adsResolver .dnsRefreshQueue .ShutDown ()
61
- close (adsResolver .Clusters )
69
+ close (r .Clusters )
62
70
}()
63
71
}
64
72
65
- func (adsResolver * AdsDnsResolver ) startAdsResolver () {
73
+ func (r * dnsController ) startDnsController () {
66
74
rateLimiter := make (chan struct {}, dns .MaxConcurrency )
67
- for clusters := range adsResolver .Clusters {
75
+ for clusters := range r .Clusters {
68
76
rateLimiter <- struct {}{}
69
77
go func (clusters []* clusterv3.Cluster ) {
70
78
defer func () {
71
79
<- rateLimiter
72
80
}()
73
- adsResolver .resolveDomains (clusters )
81
+ r .resolveDomains (clusters )
74
82
}(clusters )
75
83
}
76
84
}
77
85
78
- func (adsResolver * AdsDnsResolver ) refreshAdsDns () bool {
79
- element , quit := adsResolver .dnsRefreshQueue .Get ()
80
- if quit {
81
- return false
82
- }
83
- defer adsResolver .dnsRefreshQueue .Done (element )
84
- e := element .(* dns.PendingResolveDomain )
85
-
86
- adsResolver .dnsResolver .RLock ()
87
- _ , exist := adsResolver .dnsResolver .Cache [e .DomainName ]
88
- adsResolver .dnsResolver .RUnlock ()
89
- // if the domain is no longer watched, no need to refresh it
90
- if ! exist {
91
- return true
92
- }
93
- addresses , ttl , err := adsResolver .dnsResolver .Resolve (e .DomainName )
94
- if err != nil {
95
- log .Errorf ("failed to dns resolve: %v" , err )
96
- return false
97
- }
98
- if ttl > e .RefreshRate {
99
- ttl = e .RefreshRate
100
- }
101
- if ttl == 0 {
102
- ttl = dns .DeRefreshInterval
103
- }
104
- adsResolver .dnsRefreshQueue .AddAfter (e , ttl )
86
+ func (r * dnsController ) resolveDomains (cds []* clusterv3.Cluster ) {
87
+ domains := getPendingResolveDomain (cds )
88
+ hostNames := make (map [string ]struct {})
105
89
106
- adsResolver .adsDnsResolve (e , addresses )
107
- adsResolver .adsCache .ClusterCache .Flush ()
108
- return true
109
- }
90
+ for k := range domains {
91
+ hostNames [k ] = struct {}{}
92
+ }
110
93
111
- func (adsResolver * AdsDnsResolver ) resolveDomains (cds []* clusterv3.Cluster ) {
112
- domains := getPendingResolveDomain (cds )
94
+ // delete any scheduled re-resolve for domains we no longer care about
95
+ r .dnsResolver .RemoveUnwatchDomain (hostNames )
96
+ // Directly update the clusters that can find the dns resolution result in the cache
97
+ alreadyResolveDomains := r .dnsResolver .GetAddressesFromCache (hostNames )
98
+ for k , v := range alreadyResolveDomains {
99
+ pendingDomain := domains [k ]
100
+ r .adsDnsResolve (pendingDomain , v .Addresses )
101
+ r .cache .ClusterCache .Flush ()
102
+ delete (domains , k )
103
+ }
113
104
114
- // Stow domain updates, need to remove unwatched domains first
115
- adsResolver .dnsResolver .RemoveUnwatchedDomain (domains )
116
105
for k , v := range domains {
117
- adsResolver .dnsResolver .ResolveDomains (k )
118
- adsResolver .dnsRefreshQueue .AddAfter (v , 0 )
106
+ r .dnsResolver .ResolveDomains (k )
107
+ domainInfo := & dns.DomainInfo {
108
+ Domain : v .DomainName ,
109
+ RefreshRate : v .RefreshRate ,
110
+ }
111
+ r .dnsResolver .RefreshQueue .AddAfter (domainInfo , 0 )
119
112
}
113
+ go r .refreshAdsWorker (domains )
120
114
}
121
115
122
- func (adsResolver * AdsDnsResolver ) refreshAdsWorker () {
123
- for adsResolver .refreshAdsDns () {
116
+ func (r * dnsController ) refreshAdsWorker (domains map [string ]* pendingResolveDomain ) {
117
+ for ! (len (domains ) == 0 ) {
118
+ domain := <- r .dnsResolver .AdsDnsChan
119
+ v , ok := domains [domain ]
120
+ // will this happen?
121
+ if ! ok {
122
+ continue
123
+ }
124
+ addresses , _ := r .dnsResolver .GetOneDomainFromCache (domain )
125
+ r .adsDnsResolve (v , addresses )
126
+ r .cache .ClusterCache .Flush ()
127
+ delete (domains , domain )
124
128
}
125
129
}
126
130
127
- func (adsResolver * AdsDnsResolver ) adsDnsResolve (pendingDomain * dns. PendingResolveDomain , addrs []string ) {
131
+ func (r * dnsController ) adsDnsResolve (pendingDomain * pendingResolveDomain , addrs []string ) {
128
132
for _ , cluster := range pendingDomain .Clusters {
129
133
ready := overwriteDnsCluster (cluster , pendingDomain .DomainName , addrs )
130
134
if ready {
131
- if ! adsResolver . adsCache .UpdateApiClusterIfExists (core_v2 .ApiStatus_UPDATE , cluster ) {
135
+ if ! r . cache .UpdateApiClusterIfExists (core_v2 .ApiStatus_UPDATE , cluster ) {
132
136
log .Debugf ("cluster: %s is deleted" , cluster .Name )
133
137
return
134
138
}
@@ -201,8 +205,8 @@ func overwriteDnsCluster(cluster *clusterv3.Cluster, domain string, addrs []stri
201
205
return ready
202
206
}
203
207
204
- func getPendingResolveDomain (cds []* clusterv3.Cluster ) map [string ]* dns. PendingResolveDomain {
205
- domains := make (map [string ]* dns. PendingResolveDomain )
208
+ func getPendingResolveDomain (cds []* clusterv3.Cluster ) map [string ]* pendingResolveDomain {
209
+ domains := make (map [string ]* pendingResolveDomain )
206
210
207
211
for _ , cluster := range cds {
208
212
if cluster .LoadAssignment == nil {
@@ -224,7 +228,7 @@ func getPendingResolveDomain(cds []*clusterv3.Cluster) map[string]*dns.PendingRe
224
228
if v , ok := domains [address ]; ok {
225
229
v .Clusters = append (v .Clusters , cluster )
226
230
} else {
227
- domainWithRefreshRate := & dns. PendingResolveDomain {
231
+ domainWithRefreshRate := & pendingResolveDomain {
228
232
DomainName : address ,
229
233
Clusters : []* clusterv3.Cluster {cluster },
230
234
RefreshRate : cluster .GetDnsRefreshRate ().AsDuration (),
0 commit comments