BuildNameTable produces a table of hostnames and their associated IPs that can then be used by the agent to resolve DNS. This logic is always active. However, local DNS resolution will only be effective if DNS capture is enabled in the proxy
(cfg Config)
| 40 | // be used by the agent to resolve DNS. This logic is always active. However, local DNS resolution |
| 41 | // will only be effective if DNS capture is enabled in the proxy |
| 42 | func BuildNameTable(cfg Config) *dnsProto.NameTable { |
| 43 | out := &dnsProto.NameTable{ |
| 44 | Table: make(map[string]*dnsProto.NameTable_NameInfo), |
| 45 | } |
| 46 | for _, el := range cfg.Node.SidecarScope.EgressListeners { |
| 47 | for _, svc := range el.Services() { |
| 48 | var addressList []string |
| 49 | hostName := svc.Hostname |
| 50 | headless := false |
| 51 | for _, svcAddress := range svc.GetAllAddressesForProxy(cfg.Node) { |
| 52 | if svcAddress == constants.UnspecifiedIP { |
| 53 | headless = true |
| 54 | break |
| 55 | } |
| 56 | // Filter out things we cannot parse as IP. Generally this means CIDRs, as anything else |
| 57 | // should be caught in validation. |
| 58 | if !netutil.IsValidIPAddress(svcAddress) { |
| 59 | continue |
| 60 | } |
| 61 | addressList = append(addressList, svcAddress) |
| 62 | } |
| 63 | if headless { |
| 64 | // The IP will be unspecified here if its headless service or if the auto |
| 65 | // IP allocation logic for service entry was unable to allocate an IP. |
| 66 | if svc.Resolution == model.Passthrough && len(svc.Ports) > 0 { |
| 67 | localAddresses := make(map[string][]string) |
| 68 | remoteAddresses := make(map[string][]string) |
| 69 | hostMetadata := make(map[string]types.NamespacedName) |
| 70 | for _, instance := range cfg.Push.ServiceEndpointsByPort(svc, svc.Ports[0].Port, nil) { |
| 71 | // addresses may be empty or invalid here |
| 72 | isValidInstance := true |
| 73 | for _, addr := range instance.Addresses { |
| 74 | if !netutil.IsValidIPAddress(addr) { |
| 75 | isValidInstance = false |
| 76 | break |
| 77 | } |
| 78 | } |
| 79 | if len(instance.Addresses) == 0 || !isValidInstance || |
| 80 | (!svc.Attributes.PublishNotReadyAddresses && instance.HealthStatus != model.Healthy) { |
| 81 | continue |
| 82 | } |
| 83 | // TODO(stevenctl): headless across-networks https://github.com/istio/istio/issues/38327 |
| 84 | sameNetwork := cfg.Node.InNetwork(instance.Network) |
| 85 | sameCluster := cfg.Node.InCluster(instance.Locality.ClusterID) |
| 86 | // For all k8s headless services, populate the dns table with the endpoint IPs as k8s does. |
| 87 | // And for each individual pod, populate the dns table with the endpoint IP with a manufactured host name. |
| 88 | if instance.SubDomain != "" && sameNetwork { |
| 89 | // Follow k8s pods dns naming convention of "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>" |
| 90 | // i.e. "mysql-0.mysql.default.svc.cluster.local". |
| 91 | parts := strings.SplitN(hostName.String(), ".", 2) |
| 92 | if len(parts) != 2 { |
| 93 | continue |
| 94 | } |
| 95 | shortName := instance.HostName + "." + instance.SubDomain |
| 96 | host := shortName + "." + parts[1] // Add cluster domain. |
| 97 | hostMetadata[host] = types.NamespacedName{Name: shortName, Namespace: svc.Attributes.Namespace} |
| 98 | if sameCluster { |
| 99 | localAddresses[host] = append(localAddresses[host], instance.Addresses...) |
nothing calls this directly
no test coverage detected
searching dependent graphs…