Use node hostname in kube play when hostNetwork=true

When the hostNetwork option is set to true in the k8s yaml,
set the pod's hostname to the name of the machine/node as is
done in k8s. Also set the utsns to host.

Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
This commit is contained in:
Urvashi Mohnani
2023-10-17 11:27:24 -04:00
parent 0b0f128bfb
commit 936e30f68b
4 changed files with 101 additions and 0 deletions

View File

@ -146,6 +146,7 @@ type PodCreateOptions struct {
VolumesFrom []string `json:"volumes_from,omitempty"`
SecurityOpt []string `json:"security_opt,omitempty"`
Sysctl []string `json:"sysctl,omitempty"`
Uts string `json:"uts,omitempty"`
}
// PodLogsOptions describes the options to extract pod logs.
@ -362,6 +363,12 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
return nil, err
}
s.Ipc = out
out, err = specgen.ParseNamespace(p.Uts)
if err != nil {
return nil, err
}
s.UtsNs = out
s.Hostname = p.Hostname
s.ExitPolicy = p.ExitPolicy
s.Labels = p.Labels

View File

@ -789,6 +789,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
SecretsManager: secretsManager,
UserNSIsHost: p.Userns.IsHost(),
Volumes: volumes,
UtsNSIsHost: p.UtsNs.IsHost(),
}
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
if err != nil {
@ -858,6 +859,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
SecretsManager: secretsManager,
UserNSIsHost: p.Userns.IsHost(),
Volumes: volumes,
UtsNSIsHost: p.UtsNs.IsHost(),
}
if podYAML.Spec.TerminationGracePeriodSeconds != nil {

View File

@ -69,6 +69,12 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions,
}
if podYAML.Spec.HostNetwork {
p.Net.Network = specgen.Namespace{NSMode: "host"}
nodeHostName, err := os.Hostname()
if err != nil {
return p, err
}
p.Hostname = nodeHostName
p.Uts = "host"
}
if podYAML.Spec.HostAliases != nil {
if p.Net.NoHosts {
@ -156,6 +162,8 @@ type CtrSpecGenOptions struct {
UserNSIsHost bool
// PidNSIsHost tells the container to use the host pidns
PidNSIsHost bool
// UtsNSIsHost tells the container to use the host utsns
UtsNSIsHost bool
// SecretManager to access the secrets
SecretsManager *secrets.SecretsManager
// LogDriver which should be used for the container
@ -563,6 +571,9 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
if opts.IpcNSIsHost {
s.IpcNS.NSMode = specgen.Host
}
if opts.UtsNSIsHost {
s.UtsNS.NSMode = specgen.Host
}
// Add labels that come from kube
if len(s.Labels) == 0 {

View File

@ -6256,4 +6256,85 @@ EXPOSE 2004-2005/tcp`, CITEST_IMAGE)
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(Equal("20"))
})
It("hostname should be node name when hostNetwork=true", func() {
netYaml := `
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
hostNetwork: true
hostname: blah
containers:
- name: alpine
image: alpine
command:
- sleep
- "100"
`
err := writeYaml(netYaml, kubeYaml)
Expect(err).ToNot(HaveOccurred())
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(ExitCleanly())
// Get the name of the host
hostname, err := os.Hostname()
Expect(err).ToNot(HaveOccurred())
exec := podmanTest.Podman([]string{"exec", "test-pod-alpine", "hostname"})
exec.WaitWithDefaultTimeout()
Expect(exec).Should(ExitCleanly())
Expect(exec.OutputToString()).To(Equal(hostname))
// Check that the UTS namespace is set to host also
hostUts := SystemExec("ls", []string{"-l", "/proc/self/ns/uts"})
Expect(hostUts).Should(ExitCleanly())
arr := strings.Split(hostUts.OutputToString(), " ")
exec = podmanTest.Podman([]string{"exec", "test-pod-alpine", "ls", "-l", "/proc/self/ns/uts"})
exec.WaitWithDefaultTimeout()
Expect(exec).Should(ExitCleanly())
execArr := strings.Split(exec.OutputToString(), " ")
Expect(execArr[len(execArr)-1]).To(ContainSubstring(arr[len(arr)-1]))
})
It("hostname should be pod name when hostNetwork=false", func() {
netYaml := `
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: alpine
image: alpine
command:
- sleep
- "100"
`
err := writeYaml(netYaml, kubeYaml)
Expect(err).ToNot(HaveOccurred())
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(ExitCleanly())
exec := podmanTest.Podman([]string{"exec", "test-pod-alpine", "hostname"})
exec.WaitWithDefaultTimeout()
Expect(exec).Should(ExitCleanly())
Expect(exec.OutputToString()).To(Equal("test-pod"))
// Check that the UTS namespace is set to host also
hostUts := SystemExec("ls", []string{"-l", "/proc/self/ns/uts"})
Expect(hostUts).Should(ExitCleanly())
arr := strings.Split(hostUts.OutputToString(), " ")
exec = podmanTest.Podman([]string{"exec", "test-pod-alpine", "ls", "-l", "/proc/self/ns/uts"})
exec.WaitWithDefaultTimeout()
Expect(exec).Should(ExitCleanly())
execArr := strings.Split(exec.OutputToString(), " ")
Expect(execArr[len(execArr)-1]).To(Not(ContainSubstring(arr[len(arr)-1])))
})
})