istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/xds/nds.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package xds 16 17 import ( 18 discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" 19 20 "istio.io/istio/pilot/pkg/model" 21 "istio.io/istio/pilot/pkg/networking/core" 22 "istio.io/istio/pilot/pkg/util/protoconv" 23 "istio.io/istio/pkg/config/schema/kind" 24 "istio.io/istio/pkg/util/sets" 25 ) 26 27 // NdsGenerator generates config for Nds i.e. Name Discovery Service. Istio agents 28 // send NDS requests to istiod and istiod responds with a list of services and their 29 // associated IPs (including service entries). 30 // The agent then updates its internal DNS based on this data. If DNS capture is enabled 31 // in the pod the agent will capture all DNS requests and attempt to resolve locally before 32 // forwarding to upstream dns servers. 33 type NdsGenerator struct { 34 ConfigGenerator core.ConfigGenerator 35 } 36 37 var _ model.XdsResourceGenerator = &NdsGenerator{} 38 39 // Map of all configs that do not impact NDS 40 var skippedNdsConfigs = sets.New( 41 kind.Gateway, 42 kind.VirtualService, 43 kind.DestinationRule, 44 kind.Secret, 45 kind.Telemetry, 46 kind.EnvoyFilter, 47 kind.WorkloadEntry, 48 kind.WorkloadGroup, 49 kind.AuthorizationPolicy, 50 kind.RequestAuthentication, 51 kind.PeerAuthentication, 52 kind.WasmPlugin, 53 kind.ProxyConfig, 54 kind.MeshConfig, 55 56 kind.KubernetesGateway, 57 kind.HTTPRoute, 58 kind.TCPRoute, 59 kind.TLSRoute, 60 kind.GRPCRoute, 61 ) 62 63 func ndsNeedsPush(req *model.PushRequest) bool { 64 if req == nil { 65 return true 66 } 67 if !req.Full { 68 // NDS generally handles full push. We only allow partial pushes, when headless endpoints change. 69 return headlessEndpointsUpdated(req) 70 } 71 // If none set, we will always push 72 if len(req.ConfigsUpdated) == 0 { 73 return true 74 } 75 for config := range req.ConfigsUpdated { 76 if _, f := skippedNdsConfigs[config.Kind]; !f { 77 return true 78 } 79 } 80 return false 81 } 82 83 func headlessEndpointsUpdated(req *model.PushRequest) bool { 84 return req.Reason.Has(model.HeadlessEndpointUpdate) 85 } 86 87 func (n NdsGenerator) Generate(proxy *model.Proxy, _ *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) { 88 if !ndsNeedsPush(req) { 89 return nil, model.DefaultXdsLogDetails, nil 90 } 91 nt := n.ConfigGenerator.BuildNameTable(proxy, req.Push) 92 if nt == nil { 93 return nil, model.DefaultXdsLogDetails, nil 94 } 95 resources := model.Resources{&discovery.Resource{Resource: protoconv.MessageToAny(nt)}} 96 return resources, model.DefaultXdsLogDetails, nil 97 }