From 407fe8b356f951a9e7fb3805faed3f9d899c5d6a Mon Sep 17 00:00:00 2001 From: Ricky Pai Date: Thu, 27 Apr 2017 23:12:39 -0700 Subject: [PATCH] write HostAliases to hosts file --- pkg/kubelet/kubelet_pods.go | 19 +++++++++---- pkg/kubelet/kubelet_pods_test.go | 49 +++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 445850692fc..1753de6961e 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -181,7 +181,8 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h }) } if mountEtcHostsFile { - hostsMount, err := makeHostsMount(podDir, podIP, hostName, hostDomain) + hostAliases := pod.Spec.HostAliases + hostsMount, err := makeHostsMount(podDir, podIP, hostName, hostDomain, hostAliases) if err != nil { return nil, err } @@ -192,9 +193,9 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h // makeHostsMount makes the mountpoint for the hosts file that the containers // in a pod are injected with. -func makeHostsMount(podDir, podIP, hostName, hostDomainName string) (*kubecontainer.Mount, error) { +func makeHostsMount(podDir, podIP, hostName, hostDomainName string, hostAliases []v1.HostAlias) (*kubecontainer.Mount, error) { hostsFilePath := path.Join(podDir, "etc-hosts") - if err := ensureHostsFile(hostsFilePath, podIP, hostName, hostDomainName); err != nil { + if err := ensureHostsFile(hostsFilePath, podIP, hostName, hostDomainName, hostAliases); err != nil { return nil, err } return &kubecontainer.Mount{ @@ -208,17 +209,17 @@ func makeHostsMount(podDir, podIP, hostName, hostDomainName string) (*kubecontai // ensureHostsFile ensures that the given host file has an up-to-date ip, host // name, and domain name. -func ensureHostsFile(fileName, hostIP, hostName, hostDomainName string) error { +func ensureHostsFile(fileName, hostIP, hostName, hostDomainName string, hostAliases []v1.HostAlias) error { if _, err := os.Stat(fileName); os.IsExist(err) { glog.V(4).Infof("kubernetes-managed etc-hosts file exits. Will not be recreated: %q", fileName) return nil } - content := hostsFileContent(hostIP, hostName, hostDomainName) + content := hostsFileContent(hostIP, hostName, hostDomainName, hostAliases) return ioutil.WriteFile(fileName, content, 0644) } // hostsFileContent is the content of the managed etc hosts -func hostsFileContent(hostIP, hostName, hostDomainName string) []byte { +func hostsFileContent(hostIP, hostName, hostDomainName string, hostAliases []v1.HostAlias) []byte { var buffer bytes.Buffer buffer.WriteString("# Kubernetes-managed hosts file.\n") buffer.WriteString("127.0.0.1\tlocalhost\n") // ipv4 localhost @@ -232,6 +233,12 @@ func hostsFileContent(hostIP, hostName, hostDomainName string) []byte { } else { buffer.WriteString(fmt.Sprintf("%s\t%s\n", hostIP, hostName)) } + // write each IP/hostname pair as an entry into hosts file + for _, hostAlias := range hostAliases { + for _, hostname := range hostAlias.Hostnames { + buffer.WriteString(fmt.Sprintf("%s\t%s\n", hostAlias.IP, hostname)) + } + } return buffer.Bytes() } diff --git a/pkg/kubelet/kubelet_pods_test.go b/pkg/kubelet/kubelet_pods_test.go index de3ac16fbf6..e8e31aa925e 100644 --- a/pkg/kubelet/kubelet_pods_test.go +++ b/pkg/kubelet/kubelet_pods_test.go @@ -119,12 +119,14 @@ func TestHostsFileContent(t *testing.T) { hostIP string hostName string hostDomainName string + hostAliases []v1.HostAlias expectedContent string }{ { "123.45.67.89", "podFoo", "", + []v1.HostAlias{}, `# Kubernetes-managed hosts file. 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback @@ -139,6 +141,7 @@ fe00::2 ip6-allrouters "203.0.113.1", "podFoo", "domainFoo", + []v1.HostAlias{}, `# Kubernetes-managed hosts file. 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback @@ -147,12 +150,56 @@ fe00::0 ip6-mcastprefix fe00::1 ip6-allnodes fe00::2 ip6-allrouters 203.0.113.1 podFoo.domainFoo podFoo +`, + }, + { + "203.0.113.1", + "podFoo", + "domainFoo", + []v1.HostAlias{ + {IP: "123.45.67.89", Hostnames: []string{"foo", "bar", "baz"}}, + }, + `# Kubernetes-managed hosts file. +127.0.0.1 localhost +::1 localhost ip6-localhost ip6-loopback +fe00::0 ip6-localnet +fe00::0 ip6-mcastprefix +fe00::1 ip6-allnodes +fe00::2 ip6-allrouters +203.0.113.1 podFoo.domainFoo podFoo +123.45.67.89 foo +123.45.67.89 bar +123.45.67.89 baz +`, + }, + { + "203.0.113.1", + "podFoo", + "domainFoo", + []v1.HostAlias{ + {IP: "123.45.67.89", Hostnames: []string{"foo", "bar", "baz"}}, + {IP: "456.78.90.123", Hostnames: []string{"park", "doo", "boo"}}, + }, + `# Kubernetes-managed hosts file. +127.0.0.1 localhost +::1 localhost ip6-localhost ip6-loopback +fe00::0 ip6-localnet +fe00::0 ip6-mcastprefix +fe00::1 ip6-allnodes +fe00::2 ip6-allrouters +203.0.113.1 podFoo.domainFoo podFoo +123.45.67.89 foo +123.45.67.89 bar +123.45.67.89 baz +456.78.90.123 park +456.78.90.123 doo +456.78.90.123 boo `, }, } for _, testCase := range testCases { - actualContent := string(hostsFileContent(testCase.hostIP, testCase.hostName, testCase.hostDomainName)) + actualContent := string(hostsFileContent(testCase.hostIP, testCase.hostName, testCase.hostDomainName, testCase.hostAliases)) assert.Equal(t, testCase.expectedContent, actualContent, "hosts file content not expected") } }