diff --git a/libpod/kube.go b/libpod/kube.go
index c7aa4b57d7..1f4831006b 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -62,6 +62,7 @@ func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, e
 
 	extraHost := make([]v1.HostAlias, 0)
 	hostNetwork := false
+	hostUsers := true
 	if p.HasInfraContainer() {
 		infraContainer, err := p.getInfraContainer()
 		if err != nil {
@@ -87,8 +88,9 @@ func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, e
 			return nil, servicePorts, err
 		}
 		hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
+		hostUsers = infraContainer.IDMappings().HostUIDMapping && infraContainer.IDMappings().HostGIDMapping
 	}
-	pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork)
+	pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork, hostUsers)
 	if err != nil {
 		return nil, servicePorts, err
 	}
@@ -348,7 +350,7 @@ func containersToServicePorts(containers []v1.Container) ([]v1.ServicePort, erro
 	return sps, nil
 }
 
-func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork bool) (*v1.Pod, error) {
+func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork, hostUsers bool) (*v1.Pod, error) {
 	deDupPodVolumes := make(map[string]*v1.Volume)
 	first := true
 	podContainers := make([]v1.Container, 0, len(containers))
@@ -446,10 +448,11 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po
 		podVolumes,
 		&dnsInfo,
 		hostNetwork,
+		hostUsers,
 		hostname), nil
 }
 
-func newPodObject(podName string, annotations map[string]string, initCtrs, containers []v1.Container, volumes []v1.Volume, dnsOptions *v1.PodDNSConfig, hostNetwork bool, hostname string) *v1.Pod {
+func newPodObject(podName string, annotations map[string]string, initCtrs, containers []v1.Container, volumes []v1.Volume, dnsOptions *v1.PodDNSConfig, hostNetwork, hostUsers bool, hostname string) *v1.Pod {
 	tm := v12.TypeMeta{
 		Kind:       "Pod",
 		APIVersion: "v1",
@@ -481,6 +484,9 @@ func newPodObject(podName string, annotations map[string]string, initCtrs, conta
 		EnableServiceLinks:           &enableServiceLinks,
 		AutomountServiceAccountToken: &automountServiceAccountToken,
 	}
+	if !hostUsers {
+		ps.HostUsers = &hostUsers
+	}
 	if dnsOptions != nil && (len(dnsOptions.Nameservers)+len(dnsOptions.Searches)+len(dnsOptions.Options) > 0) {
 		ps.DNSConfig = dnsOptions
 	}
@@ -498,6 +504,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
 	kubeCtrs := make([]v1.Container, 0, len(ctrs))
 	kubeInitCtrs := []v1.Container{}
 	kubeVolumes := make([]v1.Volume, 0)
+	hostUsers := true
 	hostNetwork := true
 	podDNS := v1.PodDNSConfig{}
 	kubeAnnotations := make(map[string]string)
@@ -527,6 +534,9 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
 		if !ctr.HostNetwork() {
 			hostNetwork = false
 		}
+		if !(ctr.IDMappings().HostUIDMapping && ctr.IDMappings().HostGIDMapping) {
+			hostUsers = false
+		}
 		kubeCtr, kubeVols, ctrDNS, annotations, err := containerToV1Container(ctx, ctr)
 		if err != nil {
 			return nil, err
@@ -588,6 +598,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
 		kubeVolumes,
 		&podDNS,
 		hostNetwork,
+		hostUsers,
 		hostname), nil
 }
 
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 12786afcd1..57d7956825 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -355,6 +355,11 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
 
 	if options.Userns == "" {
 		options.Userns = "host"
+		if podYAML.Spec.HostUsers != nil && !*podYAML.Spec.HostUsers {
+			options.Userns = "auto"
+		}
+	} else if podYAML.Spec.HostUsers != nil {
+		logrus.Info("overriding the user namespace mode in the pod spec")
 	}
 
 	// Validate the userns modes supported.
diff --git a/pkg/k8s.io/api/core/v1/types.go b/pkg/k8s.io/api/core/v1/types.go
index d471788782..6f20cd3517 100644
--- a/pkg/k8s.io/api/core/v1/types.go
+++ b/pkg/k8s.io/api/core/v1/types.go
@@ -1984,6 +1984,18 @@ type PodSpec struct {
 	// Default to false.
 	// +optional
 	SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty"`
+	// Use the host's user namespace.
+	// Optional: Default to true.
+	// If set to true or not present, the pod will be run in the host user namespace, useful
+	// for when the pod needs a feature only available to the host user namespace, such as
+	// loading a kernel module with CAP_SYS_MODULE.
+	// When set to false, a new userns is created for the pod. Setting false is useful for
+	// mitigating container breakout vulnerabilities even allowing users to run their
+	// containers as root without actually having root privileges on the host.
+	// This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.
+	// +k8s:conversion-gen=false
+	// +optional
+	HostUsers *bool `json:"hostUsers,omitempty"`
 }
 
 type UnsatisfiableConstraintAction string
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 39acff6dc7..d8308aeea3 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -3,6 +3,7 @@ package integration
 import (
 	"io/ioutil"
 	"os"
+	"os/user"
 	"path/filepath"
 	"strconv"
 	"strings"
@@ -270,6 +271,39 @@ var _ = Describe("Podman generate kube", func() {
 		Expect(numContainers).To(Equal(1))
 	})
 
+	It("podman generate kube on pod with user namespace", func() {
+		u, err := user.Current()
+		Expect(err).To(BeNil())
+		name := u.Name
+		if name == "root" {
+			name = "containers"
+		}
+		content, err := ioutil.ReadFile("/etc/subuid")
+		if err != nil {
+			Skip("cannot read /etc/subuid")
+		}
+		if !strings.Contains(string(content), name) {
+			Skip("cannot find mappings for the current user")
+		}
+		podSession := podmanTest.Podman([]string{"pod", "create", "--name", "testPod", "--userns=auto"})
+		podSession.WaitWithDefaultTimeout()
+		Expect(podSession).Should(Exit(0))
+
+		session := podmanTest.Podman([]string{"create", "--name", "topcontainer", "--pod", "testPod", ALPINE, "top"})
+		session.WaitWithDefaultTimeout()
+		Expect(session).Should(Exit(0))
+
+		kube := podmanTest.Podman([]string{"generate", "kube", "testPod"})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube).Should(Exit(0))
+
+		pod := new(v1.Pod)
+		err = yaml.Unmarshal(kube.Out.Contents(), pod)
+		Expect(err).To(BeNil())
+		expected := false
+		Expect(pod.Spec).To(HaveField("HostUsers", &expected))
+	})
+
 	It("podman generate kube on pod with host network", func() {
 		podSession := podmanTest.Podman([]string{"pod", "create", "--name", "testHostNetwork", "--network", "host"})
 		podSession.WaitWithDefaultTimeout()
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index d1eb960cd7..baa74cb517 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -380,6 +380,9 @@ spec:
   restartPolicy: {{ .RestartPolicy }}
   hostname: {{ .Hostname }}
   hostNetwork: {{ .HostNetwork }}
+{{ if .HostUsers }}
+  hostUsers: {{ .HostUsers }}
+{{ end }}
   hostAliases:
 {{ range .HostAliases }}
   - hostnames:
@@ -844,6 +847,7 @@ type Pod struct {
 	RestartPolicy   string
 	Hostname        string
 	HostNetwork     bool
+	HostUsers       *bool
 	HostAliases     []HostAlias
 	Ctrs            []*Ctr
 	InitCtrs        []*Ctr
@@ -968,6 +972,12 @@ func withHostNetwork() podOption {
 	}
 }
 
+func withHostUsers(val bool) podOption {
+	return func(pod *Pod) {
+		pod.HostUsers = &val
+	}
+}
+
 // Deployment describes the options a kube yaml can be configured at deployment level
 type Deployment struct {
 	Name        string
@@ -3783,8 +3793,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q
 		Expect((inspect.InspectContainerToJSON()[0]).HostConfig.LogConfig.Tag).To(Equal("{{.ImageName}}"))
 	})
 
-	// Check that --userns=auto creates a user namespace
-	It("podman play kube --userns=auto", func() {
+	It("podman play kube using a user namespace", func() {
 		u, err := user.Current()
 		Expect(err).To(BeNil())
 		name := u.Name
@@ -3831,6 +3840,26 @@ ENV OPENJ9_JAVA_OPTIONS=%q
 		usernsInCtr.WaitWithDefaultTimeout()
 		Expect(usernsInCtr).Should(Exit(0))
 		Expect(string(usernsInCtr.Out.Contents())).To(Not(Equal(string(initialUsernsConfig))))
+
+		// Now try with hostUsers in the pod spec
+		for _, hostUsers := range []bool{true, false} {
+			pod = getPod(withHostUsers(hostUsers))
+			err = generateKubeYaml("pod", pod, kubeYaml)
+			Expect(err).To(BeNil())
+
+			kube = podmanTest.PodmanNoCache([]string{"play", "kube", "--replace", kubeYaml})
+			kube.WaitWithDefaultTimeout()
+			Expect(kube).Should(Exit(0))
+
+			usernsInCtr = podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/proc/self/uid_map"})
+			usernsInCtr.WaitWithDefaultTimeout()
+			Expect(usernsInCtr).Should(Exit(0))
+			if hostUsers {
+				Expect(string(usernsInCtr.Out.Contents())).To(Equal(string(initialUsernsConfig)))
+			} else {
+				Expect(string(usernsInCtr.Out.Contents())).To(Not(Equal(string(initialUsernsConfig))))
+			}
+		}
 	})
 
 	// Check the block devices are exposed inside container