mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 15:58:37 +00:00
Merge pull request #16219 from thockin/resolvconf-filter
Add a cloud-provider hook to scrub DNS for pods
This commit is contained in:
commit
e42f5af6a1
@ -39,6 +39,8 @@ type Interface interface {
|
|||||||
Routes() (Routes, bool)
|
Routes() (Routes, bool)
|
||||||
// ProviderName returns the cloud provider ID.
|
// ProviderName returns the cloud provider ID.
|
||||||
ProviderName() string
|
ProviderName() string
|
||||||
|
// ScrubDNS provides an opportunity for cloud-provider-specific code to process DNS settings for pods.
|
||||||
|
ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clusters is an abstract, pluggable interface for clusters of containers.
|
// Clusters is an abstract, pluggable interface for clusters of containers.
|
||||||
|
@ -597,6 +597,11 @@ func (aws *AWSCloud) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (aws *AWSCloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Amazon Web Services.
|
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Amazon Web Services.
|
||||||
func (s *AWSCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
func (s *AWSCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
||||||
return s, true
|
return s, true
|
||||||
|
@ -94,6 +94,11 @@ func (f *FakeCloud) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (f *FakeCloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
// TCPLoadBalancer returns a fake implementation of TCPLoadBalancer.
|
// TCPLoadBalancer returns a fake implementation of TCPLoadBalancer.
|
||||||
// Actually it just returns f itself.
|
// Actually it just returns f itself.
|
||||||
func (f *FakeCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
func (f *FakeCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -201,6 +202,20 @@ func (gce *GCECloud) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Known-useless DNS search path.
|
||||||
|
var uselessDNSSearchRE = regexp.MustCompile(`^[0-9]+.google.internal.$`)
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (gce *GCECloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
// GCE has too many search paths by default. Filter the ones we know are useless.
|
||||||
|
for _, s := range searches {
|
||||||
|
if !uselessDNSSearchRE.MatchString(s) {
|
||||||
|
srchOut = append(srchOut, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nameservers, srchOut
|
||||||
|
}
|
||||||
|
|
||||||
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Google Compute Engine.
|
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Google Compute Engine.
|
||||||
func (gce *GCECloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
func (gce *GCECloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
||||||
return gce, true
|
return gce, true
|
||||||
|
@ -16,7 +16,10 @@ limitations under the License.
|
|||||||
|
|
||||||
package gce
|
package gce
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestGetRegion(t *testing.T) {
|
func TestGetRegion(t *testing.T) {
|
||||||
gce := &GCECloud{
|
gce := &GCECloud{
|
||||||
@ -96,3 +99,39 @@ func TestComparingHostURLs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScrubDNS(t *testing.T) {
|
||||||
|
tcs := []struct {
|
||||||
|
nameserversIn []string
|
||||||
|
searchesIn []string
|
||||||
|
nameserversOut []string
|
||||||
|
searchesOut []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
nameserversIn: []string{"1.2.3.4", "5.6.7.8"},
|
||||||
|
nameserversOut: []string{"1.2.3.4", "5.6.7.8"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
searchesIn: []string{"c.prj.internal.", "12345678910.google.internal.", "google.internal."},
|
||||||
|
searchesOut: []string{"c.prj.internal.", "google.internal."},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
searchesIn: []string{"c.prj.internal.", "12345678910.google.internal.", "zone.c.prj.internal.", "google.internal."},
|
||||||
|
searchesOut: []string{"c.prj.internal.", "zone.c.prj.internal.", "google.internal."},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
searchesIn: []string{"c.prj.internal.", "12345678910.google.internal.", "zone.c.prj.internal.", "google.internal.", "unexpected"},
|
||||||
|
searchesOut: []string{"c.prj.internal.", "zone.c.prj.internal.", "google.internal.", "unexpected"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
gce := &GCECloud{}
|
||||||
|
for i := range tcs {
|
||||||
|
n, s := gce.ScrubDNS(tcs[i].nameserversIn, tcs[i].searchesIn)
|
||||||
|
if !reflect.DeepEqual(n, tcs[i].nameserversOut) {
|
||||||
|
t.Errorf("Expected %v, got %v", tcs[i].nameserversOut, n)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(s, tcs[i].searchesOut) {
|
||||||
|
t.Errorf("Expected %v, got %v", tcs[i].searchesOut, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -124,6 +124,11 @@ func (c *MesosCloud) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (c *MesosCloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
// ListClusters lists the names of the available Mesos clusters.
|
// ListClusters lists the names of the available Mesos clusters.
|
||||||
func (c *MesosCloud) ListClusters() ([]string, error) {
|
func (c *MesosCloud) ListClusters() ([]string, error) {
|
||||||
// Always returns a single cluster (this one!)
|
// Always returns a single cluster (this one!)
|
||||||
|
@ -399,6 +399,11 @@ func (os *OpenStack) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (os *OpenStack) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
type LoadBalancer struct {
|
type LoadBalancer struct {
|
||||||
network *gophercloud.ServiceClient
|
network *gophercloud.ServiceClient
|
||||||
compute *gophercloud.ServiceClient
|
compute *gophercloud.ServiceClient
|
||||||
|
@ -123,6 +123,11 @@ func (v *OVirtCloud) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (v *OVirtCloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for oVirt cloud
|
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for oVirt cloud
|
||||||
func (v *OVirtCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
func (v *OVirtCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@ -362,6 +362,11 @@ func (os *Rackspace) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (os *Rackspace) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
func (os *Rackspace) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
func (os *Rackspace) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,11 @@ func (v *VagrantCloud) ProviderName() string {
|
|||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScrubDNS filters DNS settings for pods.
|
||||||
|
func (v *VagrantCloud) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Vagrant cloud.
|
// TCPLoadBalancer returns an implementation of TCPLoadBalancer for Vagrant cloud.
|
||||||
func (v *VagrantCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
func (v *VagrantCloud) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@ -1245,7 +1245,7 @@ func (kl *Kubelet) getClusterDNS(pod *api.Pod) ([]string, []string, error) {
|
|||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
hostDNS, hostSearch, err = parseResolvConf(f)
|
hostDNS, hostSearch, err = kl.parseResolvConf(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -1282,7 +1282,20 @@ func (kl *Kubelet) getClusterDNS(pod *api.Pod) ([]string, []string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the list of DNS servers and DNS search domains.
|
// Returns the list of DNS servers and DNS search domains.
|
||||||
func parseResolvConf(reader io.Reader) (nameservers []string, searches []string, err error) {
|
func (kl *Kubelet) parseResolvConf(reader io.Reader) (nameservers []string, searches []string, err error) {
|
||||||
|
var scrubber dnsScrubber
|
||||||
|
if kl.cloud != nil {
|
||||||
|
scrubber = kl.cloud
|
||||||
|
}
|
||||||
|
return parseResolvConf(reader, scrubber)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A helper for testing.
|
||||||
|
type dnsScrubber interface {
|
||||||
|
ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseResolvConf(reader io.Reader, dnsScrubber dnsScrubber) (nameservers []string, searches []string, err error) {
|
||||||
file, err := ioutil.ReadAll(reader)
|
file, err := ioutil.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -1311,6 +1324,11 @@ func parseResolvConf(reader io.Reader) (nameservers []string, searches []string,
|
|||||||
searches = fields[1:]
|
searches = fields[1:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Give the cloud-provider a chance to post-process DNS settings.
|
||||||
|
if dnsScrubber != nil {
|
||||||
|
nameservers, searches = dnsScrubber.ScrubDNS(nameservers, searches)
|
||||||
|
}
|
||||||
return nameservers, searches, nil
|
return nameservers, searches, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,6 +878,15 @@ func TestRunInContainer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type countingDNSScrubber struct {
|
||||||
|
counter *int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cds countingDNSScrubber) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) {
|
||||||
|
(*cds.counter)++
|
||||||
|
return nameservers, searches
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseResolvConf(t *testing.T) {
|
func TestParseResolvConf(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
data string
|
data string
|
||||||
@ -908,7 +917,7 @@ func TestParseResolvConf(t *testing.T) {
|
|||||||
{"#comment\nnameserver 1.2.3.4\n#comment\nsearch foo\ncomment", []string{"1.2.3.4"}, []string{"foo"}},
|
{"#comment\nnameserver 1.2.3.4\n#comment\nsearch foo\ncomment", []string{"1.2.3.4"}, []string{"foo"}},
|
||||||
}
|
}
|
||||||
for i, tc := range testCases {
|
for i, tc := range testCases {
|
||||||
ns, srch, err := parseResolvConf(strings.NewReader(tc.data))
|
ns, srch, err := parseResolvConf(strings.NewReader(tc.data), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected success, got %v", err)
|
t.Errorf("expected success, got %v", err)
|
||||||
continue
|
continue
|
||||||
@ -919,6 +928,23 @@ func TestParseResolvConf(t *testing.T) {
|
|||||||
if !reflect.DeepEqual(srch, tc.searches) {
|
if !reflect.DeepEqual(srch, tc.searches) {
|
||||||
t.Errorf("[%d] expected searches %#v, got %#v", i, tc.searches, srch)
|
t.Errorf("[%d] expected searches %#v, got %#v", i, tc.searches, srch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
counter := 0
|
||||||
|
cds := countingDNSScrubber{&counter}
|
||||||
|
ns, srch, err = parseResolvConf(strings.NewReader(tc.data), cds)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected success, got %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(ns, tc.nameservers) {
|
||||||
|
t.Errorf("[%d] expected nameservers %#v, got %#v", i, tc.nameservers, ns)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(srch, tc.searches) {
|
||||||
|
t.Errorf("[%d] expected searches %#v, got %#v", i, tc.searches, srch)
|
||||||
|
}
|
||||||
|
if counter != 1 {
|
||||||
|
t.Errorf("[%d] expected dnsScrubber to have been called: got %d", i, counter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user