mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 02:03:20 -04:00 
			
		
		
		
	handle clusterIP endpoint queries (#730)
This commit is contained in:
		
				
					committed by
					
						 John Belamaric
						John Belamaric
					
				
			
			
				
	
			
			
			
						parent
						
							930c54ef62
						
					
				
				
					commit
					5c10eba31c
				
			| @@ -366,6 +366,7 @@ func (k *Kubernetes) Records(r recordRequest) ([]msg.Service, error) { | ||||
| 	} | ||||
|  | ||||
| 	records := k.getRecordsForK8sItems(services, pods, r) | ||||
|  | ||||
| 	return records, nil | ||||
| } | ||||
|  | ||||
| @@ -386,8 +387,8 @@ func (k *Kubernetes) getRecordsForK8sItems(services []service, pods []pod, r rec | ||||
| 	zonePath := msg.Path(r.zone, "coredns") | ||||
|  | ||||
| 	for _, svc := range services { | ||||
| 		if svc.addr == api.ClusterIPNone { | ||||
| 			// This is a headless service, create records for each endpoint | ||||
| 		if svc.addr == api.ClusterIPNone || len(svc.endpoints) > 0 { | ||||
| 			// This is a headless service or endpoints are present, create records for each endpoint | ||||
| 			for _, ep := range svc.endpoints { | ||||
| 				s := msg.Service{ | ||||
| 					Host: ep.addr.IP, | ||||
| @@ -522,47 +523,52 @@ func (k *Kubernetes) findServices(r recordRequest) ([]service, error) { | ||||
| 			continue | ||||
| 		} | ||||
| 		s := service{name: svc.Name, namespace: svc.Namespace} | ||||
| 		// External Service | ||||
|  | ||||
| 		// Endpoint query or headless service | ||||
| 		if svc.Spec.ClusterIP == api.ClusterIPNone || r.endpoint != "" { | ||||
| 			s.addr = svc.Spec.ClusterIP | ||||
| 			endpointsList := k.APIConn.EndpointsList() | ||||
| 			for _, ep := range endpointsList.Items { | ||||
| 				if ep.ObjectMeta.Name != svc.Name || ep.ObjectMeta.Namespace != svc.Namespace { | ||||
| 					continue | ||||
| 				} | ||||
| 				for _, eps := range ep.Subsets { | ||||
| 					for _, addr := range eps.Addresses { | ||||
| 						for _, p := range eps.Ports { | ||||
| 							ephostname := endpointHostname(addr) | ||||
| 							if r.endpoint != "" && r.endpoint != ephostname { | ||||
| 								continue | ||||
| 							} | ||||
| 							if !(symbolMatches(r.port, strings.ToLower(p.Name), portWildcard) && symbolMatches(r.protocol, strings.ToLower(string(p.Protocol)), protocolWildcard)) { | ||||
| 								continue | ||||
| 							} | ||||
| 							s.endpoints = append(s.endpoints, endpoint{addr: addr, port: p}) | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if len(s.endpoints) > 0 { | ||||
| 				resultItems = append(resultItems, s) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// External service | ||||
| 		if svc.Spec.ExternalName != "" { | ||||
| 			s.addr = svc.Spec.ExternalName | ||||
| 			resultItems = append(resultItems, s) | ||||
| 			continue | ||||
| 		} | ||||
| 		// ClusterIP service | ||||
| 		if svc.Spec.ClusterIP != api.ClusterIPNone { | ||||
| 			s.addr = svc.Spec.ClusterIP | ||||
| 			for _, p := range svc.Spec.Ports { | ||||
| 				if !(symbolMatches(r.port, strings.ToLower(p.Name), portWildcard) && symbolMatches(r.protocol, strings.ToLower(string(p.Protocol)), protocolWildcard)) { | ||||
| 					continue | ||||
| 				} | ||||
| 				s.ports = append(s.ports, p) | ||||
| 			} | ||||
| 			resultItems = append(resultItems, s) | ||||
| 			continue | ||||
| 		} | ||||
| 		// Headless service | ||||
| 		s.addr = svc.Spec.ClusterIP | ||||
| 		endpointsList := k.APIConn.EndpointsList() | ||||
|  | ||||
| 		for _, ep := range endpointsList.Items { | ||||
| 			if ep.ObjectMeta.Name != svc.Name || ep.ObjectMeta.Namespace != svc.Namespace { | ||||
| 		// ClusterIP service | ||||
| 		s.addr = svc.Spec.ClusterIP | ||||
| 		for _, p := range svc.Spec.Ports { | ||||
| 			if !(symbolMatches(r.port, strings.ToLower(p.Name), portWildcard) && symbolMatches(r.protocol, strings.ToLower(string(p.Protocol)), protocolWildcard)) { | ||||
| 				continue | ||||
| 			} | ||||
| 			for _, eps := range ep.Subsets { | ||||
| 				for _, addr := range eps.Addresses { | ||||
| 					for _, p := range eps.Ports { | ||||
| 						ephostname := endpointHostname(addr) | ||||
| 						if r.endpoint != "" && r.endpoint != ephostname { | ||||
| 							continue | ||||
| 						} | ||||
| 						if !(symbolMatches(r.port, strings.ToLower(p.Name), portWildcard) && symbolMatches(r.protocol, strings.ToLower(string(p.Protocol)), protocolWildcard)) { | ||||
| 							continue | ||||
| 						} | ||||
| 						s.endpoints = append(s.endpoints, endpoint{addr: addr, port: p}) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			s.ports = append(s.ports, p) | ||||
| 		} | ||||
|  | ||||
| 		resultItems = append(resultItems, s) | ||||
| 	} | ||||
| 	return resultItems, nil | ||||
|   | ||||
| @@ -348,7 +348,8 @@ func (APIConnServiceTest) EndpointsList() api.EndpointsList { | ||||
| 					{ | ||||
| 						Addresses: []api.EndpointAddress{ | ||||
| 							{ | ||||
| 								IP: "172.0.0.1", | ||||
| 								IP:       "172.0.0.1", | ||||
| 								Hostname: "ep1a", | ||||
| 							}, | ||||
| 						}, | ||||
| 						Ports: []api.EndpointPort{ | ||||
| @@ -455,6 +456,7 @@ func TestServices(t *testing.T) { | ||||
| 		// Cluster IP Services | ||||
| 		{qname: "svc1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: svcAns{host: "10.0.0.1", key: "/coredns/test/interwebs/svc/testns/svc1"}}, | ||||
| 		{qname: "_http._tcp.svc1.testns.svc.interwebs.test.", qtype: dns.TypeSRV, answer: svcAns{host: "10.0.0.1", key: "/coredns/test/interwebs/svc/testns/svc1"}}, | ||||
| 		{qname: "ep1a.svc1.testns.svc.interwebs.test.", qtype: dns.TypeA, answer: svcAns{host: "172.0.0.1", key: "/coredns/test/interwebs/svc/testns/svc1/ep1a"}}, | ||||
|  | ||||
| 		// External Services | ||||
| 		{qname: "external.testns.svc.interwebs.test.", qtype: dns.TypeCNAME, answer: svcAns{host: "coredns.io", key: "/coredns/test/interwebs/svc/testns/external"}}, | ||||
|   | ||||
| @@ -29,6 +29,16 @@ var dnsTestCases = []test.Case{ | ||||
| 		Rcode:  dns.RcodeNameError, | ||||
| 		Answer: []dns.RR{}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Qname: "bogusendpoint.svc-1-a.test-1.svc.cluster.local.", Qtype: dns.TypeA, | ||||
| 		Rcode:  dns.RcodeNameError, | ||||
| 		Answer: []dns.RR{}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Qname: "bogusendpoint.headless-svc.test-1.svc.cluster.local.", Qtype: dns.TypeA, | ||||
| 		Rcode:  dns.RcodeNameError, | ||||
| 		Answer: []dns.RR{}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Qname: "svc-1-a.*.svc.cluster.local.", Qtype: dns.TypeA, | ||||
| 		Rcode: dns.RcodeSuccess, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user