diff --git a/docs/kubernetes_support.md b/docs/kubernetes_support.md index 7a050df1ce..1f80dc45ee 100644 --- a/docs/kubernetes_support.md +++ b/docs/kubernetes_support.md @@ -47,7 +47,7 @@ Note: **N/A** means that the option cannot be supported in a single-node Podman | dnsConfig.searches | ✅ | | dnsPolicy | | | hostNetwork | ✅ | -| hostPID | | +| hostPID | ✅ | | hostIPC | | | shareProcessNamespace | ✅ | | serviceAccountName | | diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 8e1c7e5637..70fe4329c4 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -722,6 +722,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY RestartPolicy: ctrRestartPolicy, SeccompPaths: seccompPaths, SecretsManager: secretsManager, + PidNSIsHost: p.Pid.IsHost(), UserNSIsHost: p.Userns.IsHost(), Volumes: volumes, } diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 2b416e450c..b3098aa099 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -53,6 +53,9 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions, if podYAML.Spec.ShareProcessNamespace != nil && *podYAML.Spec.ShareProcessNamespace { p.Share = append(p.Share, "pid") } + if podYAML.Spec.HostPID { + p.Pid = "host" + } p.Hostname = podYAML.Spec.Hostname if p.Hostname == "" { p.Hostname = podName @@ -131,6 +134,8 @@ type CtrSpecGenOptions struct { NetNSIsHost bool // UserNSIsHost tells the container to use the host userns UserNSIsHost bool + // PidNSIsHost tells the container to use the host pidns + PidNSIsHost bool // SecretManager to access the secrets SecretsManager *secrets.SecretsManager // LogDriver which should be used for the container @@ -462,6 +467,9 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener if opts.UserNSIsHost { s.UserNS.NSMode = specgen.Host } + if opts.PidNSIsHost { + s.PidNS.NSMode = specgen.Host + } // Add labels that come from kube if len(s.Labels) == 0 { diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index fb9536e371..12db9e4ab9 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -940,6 +940,19 @@ spec: protocol: tcp ` +var podWithHostPIDDefined = ` +apiVersion: v1 +kind: Pod +metadata: + name: test-hostpid +spec: + hostPID: true + containers: + - name: alpine + image: quay.io/libpod/alpine:latest + command: ['sh', '-c', 'echo $$'] +` + var ( defaultCtrName = "testCtr" defaultCtrCmd = []string{"top"} @@ -4931,4 +4944,24 @@ spec: Expect(strings.Count(kube.OutputToString(), "Pod:")).To(Equal(1)) Expect(strings.Count(kube.OutputToString(), "Container:")).To(Equal(1)) }) + + It("podman play kube test with hostPID", func() { + err := writeYaml(podWithHostPIDDefined, kubeYaml) + Expect(err).ToNot(HaveOccurred()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + logs := podmanTest.Podman([]string{"pod", "logs", "-c", "test-hostpid-alpine", "test-hostpid"}) + logs.WaitWithDefaultTimeout() + Expect(logs).Should(Exit(0)) + Expect(logs.OutputToString()).To(Not(Equal("1")), "PID should never be 1 because of host pidns") + + inspect := podmanTest.Podman([]string{"inspect", "test-hostpid-alpine", "--format", "{{ .HostConfig.PidMode }}"}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(Equal("host")) + }) + })