Change:
return supported } <ins> func omitDuplicates(kl *Kubelet, pod *v1.Pod, combinedSearch []string) []string { uniqueDomains := map[string]bool{} for _, dnsDomain := range combinedSearch { if _, exists := uniqueDomains[dnsDomain]; !exists { combinedSearch[len(uniqueDomains)] = dnsDomain uniqueDomains[dnsDomain] = true } else { log := fmt.Sprintf("Found and omitted duplicated dns domain in host search line: '%s' during merging with cluster dns domains", dnsDomain) kl.recorder.Event(pod, v1.EventTypeWarning, "DNSSearchForming", log) glog.Error(log) } } return combinedSearch[:len(uniqueDomains)] } func formDNSSearchFitsLimits(kl *Kubelet, pod *v1.Pod, composedSearch []string) []string { // resolver file Search line current limitations resolvSearchLineDNSDomainsLimit := 6 resolvSearchLineLenLimit := 255 limitsExceeded := false if len(composedSearch) > resolvSearchLineDNSDomainsLimit { composedSearch = composedSearch[:resolvSearchLineDNSDomainsLimit] limitsExceeded = true } if resolvSearchhLineStrLen := len(strings.Join(composedSearch, " ")); resolvSearchhLineStrLen > resolvSearchLineLenLimit { cutDomainsNum := 0 cutDoaminsLen := 0 for i := len(composedSearch) - 1; i >= 0; i-- { cutDoaminsLen += len(composedSearch[i]) + 1 cutDomainsNum++ if (resolvSearchhLineStrLen - cutDoaminsLen) <= resolvSearchLineLenLimit { break } } composedSearch = composedSearch[:(len(composedSearch) - cutDomainsNum)] limitsExceeded = true } if limitsExceeded { log := fmt.Sprintf("Search Line limits were exceeded, some dns names have been omitted, the applied search line is: %s", strings.Join(composedSearch, " ")) kl.recorder.Event(pod, v1.EventTypeWarning, "DNSSearchForming", log) glog.Error(log) } return composedSearch } func (kl *Kubelet) formDNSSearchForDNSDefault(hostSearch []string, pod *v1.Pod) []string { return formDNSSearchFitsLimits(kl, pod, hostSearch) } func (kl *Kubelet) formDNSSearch(hostSearch []string, pod *v1.Pod) []string { if kl.clusterDomain == "" { formDNSSearchFitsLimits(kl, pod, hostSearch) return hostSearch } nsSvcDomain := fmt.Sprintf("%s.svc.%s", pod.Namespace, kl.clusterDomain) svcDomain := fmt.Sprintf("svc.%s", kl.clusterDomain) dnsSearch := []string{nsSvcDomain, svcDomain, kl.clusterDomain} combinedSearch := append(dnsSearch, hostSearch...) combinedSearch = omitDuplicates(kl, pod, combinedSearch) return formDNSSearchFitsLimits(kl, pod, combinedSearch) } func (kl *Kubelet) checkLimitsForResolvConf() { // resolver file Search line current limitations resolvSearchLineDNSDomainsLimit := 6 resolvSearchLineLenLimit := 255 f, err := os.Open(kl.resolverConfig) if err != nil { kl.recorder.Event(kl.nodeRef, v1.EventTypeWarning, "checkLimitsForResolvConf", err.Error()) glog.Error("checkLimitsForResolvConf: " + err.Error()) return } defer f.Close() _, hostSearch, err := kl.parseResolvConf(f) if err != nil { kl.recorder.Event(kl.nodeRef, v1.EventTypeWarning, "checkLimitsForResolvConf", err.Error()) glog.Error("checkLimitsForResolvConf: " + err.Error()) return } domainCntLimit := resolvSearchLineDNSDomainsLimit if kl.clusterDomain != "" { domainCntLimit -= 3 } if len(hostSearch) > domainCntLimit { log := fmt.Sprintf("Resolv.conf file '%s' contains search line consisting of more than %d domains!", kl.resolverConfig, domainCntLimit) kl.recorder.Event(kl.nodeRef, v1.EventTypeWarning, "checkLimitsForResolvConf", log) glog.Error("checkLimitsForResolvConf: " + log) return } if len(strings.Join(hostSearch, " ")) > resolvSearchLineLenLimit { log := fmt.Sprintf("Resolv.conf file '%s' contains search line which length is more than allowed %d chars!", kl.resolverConfig, resolvSearchLineLenLimit) kl.recorder.Event(kl.nodeRef, v1.EventTypeWarning, "checkLimitsForResolvConf", log) glog.Error("checkLimitsForResolvConf: " + log) return } return } </ins> // parseResolveConf reads a resolv.conf file from the given reader, and parses // it into nameservers and searches, possibly returning an error. // TODO: move to utility package

Discussion:
Kubernetes version v1.3.0 Kubelet concatenates host and cluster domain entries for my pod, resulting in an invalid config (too many entries with duplicates). The max is only 6 search domains. Any more and DNS resolution breaks when trying to leverage search domains. The example below has only cluster DNS entries, but illustrates the issue: Host search nameserver 10.233.0.2 nameserver 10.90.0.1 options timeout:2 options attempts:2 Container kubectl run -i --tty busybox --image=busybox -- sh (skip waiting text) / # cat search nameserver 10.233.0.2 options attempts:2 options ndots:5 I should be enable cluster DNS config in my host DNS settings and still have functional pod DNS. Kubelet should be intelligent enough to filter out duplicate search domain entries (or drop search domains beyond the 6th entry)
I think some sane checks needs to be too. libc limits search field to 6 records and 255(?) characters. This limitation should be checked before creation.
Hey guys, I'm working on it.
Dup of