Merge pull request #45148 from rickypai/rpai/use_host_aliases

Automatic merge from submit-queue (batch tested with PRs 45110, 45148)

write HostAliases to hosts file

**What this PR does / why we need it**: using the PodSpec's `HostAliases`, we write entries into the Kubernetes-managed hosts file.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #43632

**Special notes for your reviewer**:
Previous PRs in this series:
- https://github.com/kubernetes/kubernetes/pull/44572 isolates the logic of creating the file and writing the file
- https://github.com/kubernetes/kubernetes/pull/44641 introduces the `HostAliases` field in PodSpec along with validations

**Release note**:
```release-note
PodSpec's `HostAliases` now write entries into the Kubernetes-managed hosts file.
```

@thockin @yujuhong 

Thanks for reviewing!
pull/6/head
Kubernetes Submit Queue 2017-05-01 05:42:16 -07:00 committed by GitHub
commit 08606b530b
2 changed files with 61 additions and 7 deletions

View File

@ -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()
}

View File

@ -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")
}
}