Merge pull request #132157 from haircommander/drop-userns-psa

drop UserNamespacesPodSecurityStandards feature gate
This commit is contained in:
Kubernetes Prow Robot
2025-11-04 08:20:08 -08:00
committed by GitHub
183 changed files with 4012 additions and 212 deletions

View File

@@ -990,17 +990,6 @@ const (
// Proxies client to an apiserver capable of serving the request in the event of version skew.
UnknownVersionInteroperabilityProxy featuregate.Feature = "UnknownVersionInteroperabilityProxy"
// owner: @saschagrunert
//
// Enables user namespace support for Pod Security Standards. Enabling this
// feature will modify all Pod Security Standard rules to allow setting:
// spec[.*].securityContext.[runAsNonRoot,runAsUser]
// This feature gate should only be enabled if all nodes in the cluster
// support the user namespace feature and have it enabled. The feature gate
// will not graduate or be enabled by default in future Kubernetes
// releases.
UserNamespacesPodSecurityStandards featuregate.Feature = "UserNamespacesPodSecurityStandards"
// owner: @rata, @giuseppe
// kep: https://kep.k8s.io/127
//
@@ -1764,10 +1753,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
},
UserNamespacesPodSecurityStandards: {
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
},
UserNamespacesSupport: {
{Version: version.MustParse("1.25"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.30"), Default: false, PreRelease: featuregate.Beta},
@@ -2308,8 +2293,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature
UnknownVersionInteroperabilityProxy: {},
UserNamespacesPodSecurityStandards: {},
UserNamespacesSupport: {},
VolumeAttributesClass: {},

View File

@@ -27,7 +27,6 @@ import (
_ "k8s.io/kubernetes/pkg/apis/apps/install"
_ "k8s.io/kubernetes/pkg/apis/batch/install"
_ "k8s.io/kubernetes/pkg/apis/core/install"
"k8s.io/kubernetes/pkg/features"
admissionv1 "k8s.io/api/admission/v1"
appsv1 "k8s.io/api/apps/v1"
@@ -44,7 +43,6 @@ import (
"k8s.io/client-go/kubernetes"
corev1listers "k8s.io/client-go/listers/core/v1"
"k8s.io/component-base/compatibility"
"k8s.io/component-base/featuregate"
"k8s.io/component-base/metrics/legacyregistry"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/apis/apps"
@@ -71,8 +69,6 @@ func Register(plugins *admission.Plugins) {
type Plugin struct {
*admission.Handler
inspectedFeatureGates bool
inspectedEffectiveVersion bool
emulationVersion *podsecurityadmissionapi.Version
@@ -173,16 +169,8 @@ func (p *Plugin) InspectEffectiveVersion(version compatibility.EffectiveVersion)
}
}
func (p *Plugin) InspectFeatureGates(featureGates featuregate.FeatureGate) {
p.inspectedFeatureGates = true
policy.RelaxPolicyForUserNamespacePods(featureGates.Enabled(features.UserNamespacesPodSecurityStandards))
}
// ValidateInitialization ensures all required options are set
func (p *Plugin) ValidateInitialization() error {
if !p.inspectedFeatureGates {
return fmt.Errorf("%s did not see feature gates", PluginName)
}
if !p.inspectedEffectiveVersion {
return fmt.Errorf("%s did not see effective version", PluginName)
}

View File

@@ -33,7 +33,6 @@ import (
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/util/compatibility"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/warning"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
@@ -84,7 +83,6 @@ func BenchmarkVerifyPod(b *testing.B) {
}
p.InspectEffectiveVersion(compatibility.DefaultBuildEffectiveVersion())
p.InspectFeatureGates(utilfeature.DefaultFeatureGate)
enforceImplicitPrivilegedNamespace := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "enforce-implicit", Labels: map[string]string{}}}
enforcePrivilegedNamespace := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "enforce-privileged", Labels: map[string]string{"pod-security.kubernetes.io/enforce": "privileged"}}}
@@ -193,7 +191,6 @@ func BenchmarkVerifyNamespace(b *testing.B) {
}
p.InspectEffectiveVersion(compatibility.DefaultBuildEffectiveVersion())
p.InspectFeatureGates(utilfeature.DefaultFeatureGate)
namespace := "enforce"
enforceNamespaceBaselineV1 := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace, Labels: map[string]string{"pod-security.kubernetes.io/enforce": "baseline"}}}

View File

@@ -27,27 +27,25 @@ import (
/*
The default /proc masks are set up to reduce attack surface, and should be required.
The default /proc masks are set up to reduce attack surface, and should be required
by the baseline policy unless the pod is in a user namespace ("hostUsers: false").
**Restricted Fields:**
spec.containers[*].securityContext.procMount
spec.initContainers[*].securityContext.procMount
**Allowed Values:** undefined/null, "Default"
However, if the pod is in a user namespace (`hostUsers: false`), and the
UserNamespacesPodSecurityStandards feature is enabled, all values are allowed.
**Allowed Values:** undefined/null, "Default" (or any value if "hostUsers" is false)
*/
func init() {
addCheck(CheckProcMount)
addCheck(CheckProcMountBaseline)
}
// CheckProcMount returns a baseline level check that restricts
// setting the value of securityContext.procMount to DefaultProcMount
// in 1.0+
func CheckProcMount() Check {
// in 1.0+.
// Starting in 1.35+, any value is allowed if the pod is in a user namespace ("hostUsers: false").
func CheckProcMountBaseline() Check {
return Check{
ID: "procMount",
Level: api.LevelBaseline,
@@ -56,19 +54,16 @@ func CheckProcMount() Check {
MinimumVersion: api.MajorMinorVersion(1, 0),
CheckPod: procMount_1_0,
},
{
MinimumVersion: api.MajorMinorVersion(1, 35),
CheckPod: procMount1_35baseline,
},
},
}
}
// procMount_1_0 blocks unmasked procMount unconditionally
func procMount_1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
// TODO: When we remove the UserNamespacesPodSecurityStandards feature gate (and GA this relaxation),
// create a new policy version.
// Note: pod validation will check for well formed procMount type, so avoid double validation and allow everything
// here.
if relaxPolicyForUserNamespacePod(podSpec) {
return CheckResult{Allowed: true}
}
var badContainers []string
forbiddenProcMountTypes := sets.NewString()
visitContainers(podSpec, func(container *corev1.Container) {
@@ -100,3 +95,12 @@ func procMount_1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) Chec
}
return CheckResult{Allowed: true}
}
// procMount1_35baseline blocks unmasked procMount for pods that are not in a user namespace
func procMount1_35baseline(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
if relaxPolicyForUserNamespacePod(podSpec) {
return CheckResult{Allowed: true}
}
// If the pod is not in a user namespace, treat it as restricted.
return procMount_1_0(podMetadata, podSpec)
}

View File

@@ -20,21 +20,20 @@ import (
"testing"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/ptr"
)
func TestProcMount(t *testing.T) {
func TestProcMountBaseline(t *testing.T) {
defaultValue := corev1.DefaultProcMount
unmaskedValue := corev1.UnmaskedProcMount
otherValue := corev1.ProcMountType("other")
hostUsers := false
tests := []struct {
name string
pod *corev1.Pod
expectReason string
expectDetail string
expectAllowed bool
relaxForUserNS bool
name string
pod *corev1.Pod
expectReason string
expectDetail string
expectAllowed bool
}{
{
name: "procMount",
@@ -46,14 +45,14 @@ func TestProcMount(t *testing.T) {
{Name: "d", SecurityContext: &corev1.SecurityContext{ProcMount: &unmaskedValue}},
{Name: "e", SecurityContext: &corev1.SecurityContext{ProcMount: &otherValue}},
},
HostUsers: &hostUsers,
HostUsers: ptr.To(true),
}},
expectReason: `procMount`,
expectAllowed: false,
expectDetail: `containers "d", "e" must not set securityContext.procMount to "Unmasked", "other"`,
},
{
name: "procMount",
name: "procMount with userns",
pod: &corev1.Pod{Spec: corev1.PodSpec{
Containers: []corev1.Container{
{Name: "a", SecurityContext: nil},
@@ -62,24 +61,17 @@ func TestProcMount(t *testing.T) {
{Name: "d", SecurityContext: &corev1.SecurityContext{ProcMount: &unmaskedValue}},
{Name: "e", SecurityContext: &corev1.SecurityContext{ProcMount: &otherValue}},
},
HostUsers: &hostUsers,
HostUsers: ptr.To(false),
}},
expectReason: "",
expectDetail: "",
expectAllowed: true,
relaxForUserNS: true,
expectReason: "",
expectDetail: "",
expectAllowed: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
if tc.relaxForUserNS {
RelaxPolicyForUserNamespacePods(true)
t.Cleanup(func() {
RelaxPolicyForUserNamespacePods(false)
})
}
result := procMount_1_0(&tc.pod.ObjectMeta, &tc.pod.Spec)
result := procMount1_35baseline(&tc.pod.ObjectMeta, &tc.pod.Spec)
if result.Allowed != tc.expectAllowed {
t.Fatalf("expected Allowed to be %v was %v", tc.expectAllowed, result.Allowed)
}

View File

@@ -0,0 +1,56 @@
/*
Copyright 2025 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package policy
import (
"k8s.io/pod-security-admission/api"
)
/*
The default /proc masks are set up to reduce attack surface, and should be required by the restricted profile.
**Restricted Fields:**
spec.containers[*].securityContext.procMount
spec.initContainers[*].securityContext.procMount
**Allowed Values:** undefined/null, "Default"
*/
func init() {
addCheck(CheckProcMountRestricted)
}
// CheckProcMountRestricted returns a restricted level check that forbids unmasked procmount.
func CheckProcMountRestricted() Check {
return Check{
ID: "procMount_restricted",
Level: api.LevelRestricted,
Versions: []VersionedCheck{
{
// Prior to 1.35, the baseline "procMount" check ran procMount_1_0 to unconditionally block unmasked procMount.
// In 1.35+, baseline conditionally relaxes for user namespace pods.
// Starting at that version, keep running the unconditional block in the restricted profile,
// and override the slightly weaker version of the same check from the baseline profile.
MinimumVersion: api.MajorMinorVersion(1, 35),
CheckPod: procMount_1_0,
OverrideCheckIDs: []CheckID{"procMount"},
},
},
}
}

View File

@@ -0,0 +1,71 @@
/*
Copyright 2025 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package policy
import (
"testing"
corev1 "k8s.io/api/core/v1"
)
func TestProcMountRestricted(t *testing.T) {
defaultValue := corev1.DefaultProcMount
unmaskedValue := corev1.UnmaskedProcMount
otherValue := corev1.ProcMountType("other")
tests := []struct {
name string
pod *corev1.Pod
expectReason string
expectDetail string
expectAllowed bool
}{
{
name: "procMount",
pod: &corev1.Pod{Spec: corev1.PodSpec{
Containers: []corev1.Container{
{Name: "a", SecurityContext: nil},
{Name: "b", SecurityContext: &corev1.SecurityContext{}},
{Name: "c", SecurityContext: &corev1.SecurityContext{ProcMount: &defaultValue}},
{Name: "d", SecurityContext: &corev1.SecurityContext{ProcMount: &unmaskedValue}},
{Name: "e", SecurityContext: &corev1.SecurityContext{ProcMount: &otherValue}},
},
}},
expectReason: `procMount`,
expectAllowed: false,
expectDetail: `containers "d", "e" must not set securityContext.procMount to "Unmasked", "other"`,
},
}
for _, tc := range tests {
for _, userns := range []bool{true, false} {
t.Run(tc.name, func(t *testing.T) {
tc.pod.Spec.HostUsers = &userns
result := procMount_1_0(&tc.pod.ObjectMeta, &tc.pod.Spec)
if result.Allowed != tc.expectAllowed {
t.Fatalf("expected Allowed to be %v was %v", tc.expectAllowed, result.Allowed)
}
if e, a := tc.expectReason, result.ForbiddenReason; e != a {
t.Errorf("expected\n%s\ngot\n%s", e, a)
}
if e, a := tc.expectDetail, result.ForbiddenDetail; e != a {
t.Errorf("expected\n%s\ngot\n%s", e, a)
}
})
}
}
}

View File

@@ -26,7 +26,8 @@ import (
)
/*
Containers must be required to run as non-root users.
Containers must be required to run as non-root users,
unless the pod is in a user namespace ("hostUsers: false").
**Restricted Fields:**
@@ -37,6 +38,7 @@ spec.initContainers[*].securityContext.runAsNonRoot
**Allowed Values:**
true
undefined/null at container-level if pod-level is set to true
any value if "hostUsers" is false
*/
func init() {
@@ -52,18 +54,28 @@ func CheckRunAsNonRoot() Check {
Versions: []VersionedCheck{
{
MinimumVersion: api.MajorMinorVersion(1, 0),
CheckPod: runAsNonRoot_1_0,
CheckPod: runAsNonRoot1_0,
},
{
MinimumVersion: api.MajorMinorVersion(1, 35),
CheckPod: runAsNonRoot1_35,
},
},
}
}
func runAsNonRoot_1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
func runAsNonRoot1_35(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
// See KEP-127: https://github.com/kubernetes/enhancements/blob/308ba8d/keps/sig-node/127-user-namespaces/README.md?plain=1#L411-L447
// In the 1.0 policy, this relaxation was gated on a perma-alpha feature gate.
// Instead of relaxing 1.0 policy, drop the relaxation there, and add it unconditionally here.
if relaxPolicyForUserNamespacePod(podSpec) {
return CheckResult{Allowed: true}
}
return runAsNonRoot1_0(podMetadata, podSpec)
}
func runAsNonRoot1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
// things that explicitly set runAsNonRoot=false
var badSetters []string

View File

@@ -25,12 +25,11 @@ import (
func TestRunAsNonRoot(t *testing.T) {
tests := []struct {
name string
pod *corev1.Pod
expectReason string
expectDetail string
expectAllowed bool
relaxForUserNS bool
name string
pod *corev1.Pod
expectReason string
expectDetail string
expectAllowed bool
}{
{
name: "no explicit runAsNonRoot",
@@ -83,37 +82,17 @@ func TestRunAsNonRoot(t *testing.T) {
expectDetail: `pod or containers "a", "b" must set securityContext.runAsNonRoot=true`,
},
{
name: "UserNamespacesPodSecurityStandards enabled without HostUsers",
name: "host users false allowed",
pod: &corev1.Pod{Spec: corev1.PodSpec{
HostUsers: ptr.To(false),
}},
expectAllowed: true,
relaxForUserNS: true,
},
{
name: "UserNamespacesPodSecurityStandards enabled with HostUsers",
pod: &corev1.Pod{Spec: corev1.PodSpec{
Containers: []corev1.Container{
{Name: "a"},
},
HostUsers: ptr.To(true),
}},
expectReason: `runAsNonRoot != true`,
expectDetail: `pod or container "a" must set securityContext.runAsNonRoot=true`,
expectAllowed: false,
relaxForUserNS: true,
expectAllowed: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
if tc.relaxForUserNS {
RelaxPolicyForUserNamespacePods(true)
t.Cleanup(func() {
RelaxPolicyForUserNamespacePods(false)
})
}
result := runAsNonRoot_1_0(&tc.pod.ObjectMeta, &tc.pod.Spec)
result := runAsNonRoot1_35(&tc.pod.ObjectMeta, &tc.pod.Spec)
if result.Allowed != tc.expectAllowed {
t.Fatalf("expected Allowed to be %v was %v", tc.expectAllowed, result.Allowed)
}

View File

@@ -27,6 +27,7 @@ import (
/*
Containers must not set runAsUser: 0
unless the pod is in a user namespace ("hostUsers: false").
**Restricted Fields:**
@@ -37,6 +38,7 @@ spec.initContainers[*].securityContext.runAsUser
**Allowed Values:**
non-zero values
undefined/null
any value if "hostUsers" is false
*/
@@ -53,18 +55,28 @@ func CheckRunAsUser() Check {
Versions: []VersionedCheck{
{
MinimumVersion: api.MajorMinorVersion(1, 23),
CheckPod: runAsUser_1_23,
CheckPod: runAsUser1_23,
},
{
MinimumVersion: api.MajorMinorVersion(1, 35),
CheckPod: runAsUser1_35,
},
},
}
}
func runAsUser_1_23(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
func runAsUser1_35(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
// See KEP-127: https://github.com/kubernetes/enhancements/blob/308ba8d/keps/sig-node/127-user-namespaces/README.md?plain=1#L411-L447
// In the 1.23 policy, this relaxation was gated on a perma-alpha feature gate.
// Instead of relaxing 1.0 policy, drop the relaxation there, and add it unconditionally here.
if relaxPolicyForUserNamespacePod(podSpec) {
return CheckResult{Allowed: true}
}
return runAsUser1_23(podMetadata, podSpec)
}
func runAsUser1_23(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
// things that explicitly set runAsUser=0
var badSetters []string

View File

@@ -25,12 +25,11 @@ import (
func TestRunAsUser(t *testing.T) {
tests := []struct {
name string
pod *corev1.Pod
expectAllowed bool
expectReason string
expectDetail string
relaxForUserNS bool
name string
pod *corev1.Pod
expectAllowed bool
expectReason string
expectDetail string
}{
{
name: "pod runAsUser=0",
@@ -92,38 +91,17 @@ func TestRunAsUser(t *testing.T) {
expectAllowed: true,
},
{
name: "UserNamespacesPodSecurityStandards enabled without HostUsers",
name: "host users false allowed",
pod: &corev1.Pod{Spec: corev1.PodSpec{
HostUsers: ptr.To(false),
}},
expectAllowed: true,
relaxForUserNS: true,
},
{
name: "UserNamespacesPodSecurityStandards enabled with HostUsers",
pod: &corev1.Pod{Spec: corev1.PodSpec{
SecurityContext: &corev1.PodSecurityContext{RunAsUser: ptr.To[int64](0)},
Containers: []corev1.Container{
{Name: "a", SecurityContext: nil},
},
HostUsers: ptr.To(true),
}},
expectAllowed: false,
expectReason: `runAsUser=0`,
expectDetail: `pod must not set runAsUser=0`,
relaxForUserNS: true,
expectAllowed: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
if tc.relaxForUserNS {
RelaxPolicyForUserNamespacePods(true)
t.Cleanup(func() {
RelaxPolicyForUserNamespacePods(false)
})
}
result := runAsUser_1_23(&tc.pod.ObjectMeta, &tc.pod.Spec)
result := runAsUser1_35(&tc.pod.ObjectMeta, &tc.pod.Spec)
if result.Allowed != tc.expectAllowed {
t.Fatalf("expected Allowed to be %v was %v", tc.expectAllowed, result.Allowed)
}

View File

@@ -18,7 +18,6 @@ package policy
import (
"strings"
"sync/atomic"
corev1 "k8s.io/api/core/v1"
)
@@ -37,20 +36,8 @@ func pluralize(singular, plural string, count int) string {
return plural
}
var relaxPolicyForUserNamespacePods = &atomic.Bool{}
// RelaxPolicyForUserNamespacePods allows opting into relaxing runAsUser /
// runAsNonRoot restricted policies for user namespace pods, before the
// usernamespace feature has reached GA and propagated to the oldest supported
// nodes.
// This should only be opted into in clusters where the administrator ensures
// all nodes in the cluster enable the user namespace feature.
func RelaxPolicyForUserNamespacePods(relax bool) {
relaxPolicyForUserNamespacePods.Store(relax)
}
// relaxPolicyForUserNamespacePod returns true if a policy should be relaxed
// because of enabled user namespaces in the provided pod spec.
func relaxPolicyForUserNamespacePod(podSpec *corev1.PodSpec) bool {
return relaxPolicyForUserNamespacePods.Load() && podSpec != nil && podSpec.HostUsers != nil && !*podSpec.HostUsers
return podSpec != nil && podSpec.HostUsers != nil && !*podSpec.HostUsers
}

View File

@@ -183,9 +183,14 @@ type fixtureGenerator struct {
// Pass cases are not allowed to be feature-gated (pass cases must only depend on data existing in GA fields).
failRequiresFeatures []featuregate.Feature
// generatePass transforms a minimum valid pod into one or more valid pods.
// failRequiresError indicates the fixtures in the failure cases cannot be created with warnings, but result in API errors.
// This happens when the combination of fields required to fail the PSA check also fails validation.
// When failRequiresError=true, the controller test scenarios expect failure cases to be rejected rather than accepted with warnings.
failRequiresError bool
// generatePass transforms a minimum valid pod into one or more valid pods that pass the given policy level.
// pods do not need to populate metadata.name.
generatePass func(*corev1.Pod) []*corev1.Pod
generatePass func(*corev1.Pod, api.Level) []*corev1.Pod
// generateFail transforms a minimum valid pod into one or more invalid pods.
// pods do not need to populate metadata.name.
generateFail func(*corev1.Pod) []*corev1.Pod
@@ -201,6 +206,11 @@ type fixtureData struct {
// Pass cases are not allowed to be feature-gated (pass cases must only depend on data existing in GA fields).
failRequiresFeatures []featuregate.Feature
// failRequiresError indicates the fixtures in the failure cases cannot be created with warnings, but result in API errors.
// This happens when the combination of fields required to fail the PSA check also fails validation.
// When failRequiresError=true, the controller test scenarios expect failure cases to be rejected rather than accepted with warnings.
failRequiresError bool
pass []*corev1.Pod
fail []*corev1.Pod
}
@@ -248,8 +258,9 @@ func getFixtures(key fixtureKey) (fixtureData, error) {
data := fixtureData{
expectErrorSubstring: generator.expectErrorSubstring,
failRequiresFeatures: generator.failRequiresFeatures,
failRequiresError: generator.failRequiresError,
pass: generator.generatePass(validPodForLevel.DeepCopy()),
pass: generator.generatePass(validPodForLevel.DeepCopy(), key.level),
fail: generator.generateFail(validPodForLevel.DeepCopy()),
}
if len(data.expectErrorSubstring) == 0 {

View File

@@ -33,7 +33,7 @@ containerFields: []string{
func init() {
fixtureData_1_8 := fixtureGenerator{
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
// minimal valid pod already captures all valid combinations
return nil
},

View File

@@ -24,7 +24,7 @@ import (
func init() {
appArmorFixture_1_0 := fixtureGenerator{
expectErrorSubstring: "forbidden AppArmor profile",
generatePass: func(pod *corev1.Pod) []*corev1.Pod {
generatePass: func(pod *corev1.Pod, _ api.Level) []*corev1.Pod {
pod = ensureAnnotation(pod)
return []*corev1.Pod{
// container with runtime/default annotation

View File

@@ -48,7 +48,7 @@ func ensureCapabilities(p *corev1.Pod) *corev1.Pod {
func init() {
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "capabilities",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
// don't generate fixtures if minimal valid pod drops ALL
if p.Spec.Containers[0].SecurityContext != nil && p.Spec.Containers[0].SecurityContext.Capabilities != nil {
for _, capability := range p.Spec.Containers[0].SecurityContext.Capabilities.Drop {

View File

@@ -31,7 +31,7 @@ containerFields: []string{
func init() {
fixtureData_1_22 := fixtureGenerator{
expectErrorSubstring: "unrestricted capabilities",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureCapabilities(p)
return []*corev1.Pod{
tweak(p, func(p *corev1.Pod) {

View File

@@ -29,7 +29,7 @@ func init() {
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "host namespaces",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
// minimal valid pod already captures all valid combinations
return nil
},

View File

@@ -29,7 +29,7 @@ func init() {
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "hostPath",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
// minimal valid pod already captures all valid combinations
return nil
},

View File

@@ -32,7 +32,7 @@ containerFields: []string{
func init() {
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "hostPort",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
return []*corev1.Pod{
// no host ports
tweak(p, func(p *corev1.Pod) {

View File

@@ -25,7 +25,7 @@ import (
func init() {
fixtureDataV1Dot34 := fixtureGenerator{
expectErrorSubstring: "probe or lifecycle host",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
return []*corev1.Pod{
p, // A pod with no probes should pass.
tweak(p, func(p *corev1.Pod) {

View File

@@ -33,7 +33,7 @@ containerFields: []string{
func init() {
fixtureData_1_0 := fixtureGenerator{
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
// privileged explicitly set to false

View File

@@ -20,13 +20,13 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/component-base/featuregate"
"k8s.io/pod-security-admission/api"
"k8s.io/utils/ptr"
)
func init() {
hostUsers := false
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "procMount",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
// set proc mount of container and init container to a valid value
@@ -34,7 +34,7 @@ func init() {
validProcMountType := corev1.DefaultProcMount
copy.Spec.Containers[0].SecurityContext.ProcMount = &validProcMountType
copy.Spec.InitContainers[0].SecurityContext.ProcMount = &validProcMountType
copy.Spec.HostUsers = &hostUsers
copy.Spec.HostUsers = ptr.To(false)
}),
}
},
@@ -46,13 +46,13 @@ func init() {
tweak(p, func(copy *corev1.Pod) {
unmaskedProcMountType := corev1.UnmaskedProcMount
copy.Spec.Containers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.HostUsers = &hostUsers
copy.Spec.HostUsers = ptr.To(false)
}),
// set proc mount of init container to a forbidden value
tweak(p, func(copy *corev1.Pod) {
unmaskedProcMountType := corev1.UnmaskedProcMount
copy.Spec.InitContainers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.HostUsers = &hostUsers
copy.Spec.HostUsers = ptr.To(false)
}),
}
},
@@ -62,4 +62,95 @@ func init() {
fixtureKey{level: api.LevelBaseline, version: api.MajorMinorVersion(1, 0), check: "procMount"},
fixtureData_1_0,
)
fixtureData1_35baseline := fixtureGenerator{
expectErrorSubstring: "procMount",
generatePass: func(p *corev1.Pod, level api.Level) []*corev1.Pod {
p = ensureSecurityContext(p)
retval := []*corev1.Pod{
// set proc mount of container and init container to a valid value
tweak(p, func(copy *corev1.Pod) {
validProcMountType := corev1.DefaultProcMount
copy.Spec.Containers[0].SecurityContext.ProcMount = &validProcMountType
copy.Spec.InitContainers[0].SecurityContext.ProcMount = &validProcMountType
copy.Spec.HostUsers = ptr.To(false)
}),
}
if level != api.LevelRestricted {
// don't expect the unmasked namespace user pod to pass in restricted mode
retval = append(retval, tweak(p, func(copy *corev1.Pod) {
unmaskedProcMountType := corev1.UnmaskedProcMount
copy.Spec.Containers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.InitContainers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.HostUsers = ptr.To(false)
}))
}
return retval
},
failRequiresFeatures: []featuregate.Feature{"ProcMountType"},
failRequiresError: true, // the only combination that can fail the 1.35 baseline check also fails validation
generateFail: func(p *corev1.Pod) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
// set proc mount of container to a forbidden value
tweak(p, func(copy *corev1.Pod) {
unmaskedProcMountType := corev1.UnmaskedProcMount
copy.Spec.Containers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.HostUsers = ptr.To(true)
}),
// set proc mount of init container to a forbidden value
tweak(p, func(copy *corev1.Pod) {
unmaskedProcMountType := corev1.UnmaskedProcMount
copy.Spec.InitContainers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.HostUsers = ptr.To(true)
}),
}
},
}
registerFixtureGenerator(
fixtureKey{level: api.LevelBaseline, version: api.MajorMinorVersion(1, 35), check: "procMount"},
fixtureData1_35baseline,
)
fixtureData1_35restricted := fixtureGenerator{
expectErrorSubstring: "procMount",
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
// set proc mount of container and init container to a valid value
tweak(p, func(copy *corev1.Pod) {
validProcMountType := corev1.DefaultProcMount
copy.Spec.Containers[0].SecurityContext.ProcMount = &validProcMountType
copy.Spec.InitContainers[0].SecurityContext.ProcMount = &validProcMountType
copy.Spec.HostUsers = ptr.To(false)
}),
}
},
failRequiresFeatures: []featuregate.Feature{"ProcMountType"},
generateFail: func(p *corev1.Pod) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
// set proc mount of container to a forbidden value
tweak(p, func(copy *corev1.Pod) {
unmaskedProcMountType := corev1.UnmaskedProcMount
copy.Spec.Containers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.HostUsers = ptr.To(false)
}),
// set proc mount of init container to a forbidden value
tweak(p, func(copy *corev1.Pod) {
unmaskedProcMountType := corev1.UnmaskedProcMount
copy.Spec.InitContainers[0].SecurityContext.ProcMount = &unmaskedProcMountType
copy.Spec.HostUsers = ptr.To(false)
}),
}
},
}
registerFixtureGenerator(
fixtureKey{level: api.LevelRestricted, version: api.MajorMinorVersion(1, 35), check: "procMount_restricted"},
fixtureData1_35restricted,
)
}

View File

@@ -25,7 +25,7 @@ func init() {
// volumeType := "ext4"
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "restricted volume types",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
return []*corev1.Pod{
// pod that has all allowed volume types
tweak(p, func(p *corev1.Pod) {

View File

@@ -37,7 +37,7 @@ containerFields: []string{
func init() {
fixtureData_1_0 := fixtureGenerator{
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
// set at pod level

View File

@@ -37,7 +37,7 @@ containerFields: []string{
func init() {
fixtureData_1_23 := fixtureGenerator{
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
tweak(p, func(p *corev1.Pod) {

View File

@@ -39,7 +39,7 @@ containerFields: []string{
func init() {
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "seLinuxOptions",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureSELinuxOptions(p)
return []*corev1.Pod{
// security context with no seLinuxOptions

View File

@@ -31,7 +31,7 @@ The check implementation looks at the appropriate value based on version.
func init() {
fixtureData_baseline_1_0 := fixtureGenerator{
expectErrorSubstring: "seccompProfile",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
// don't generate fixtures if minimal valid pod already has seccomp config
if val, ok := p.Annotations[annotationKeyPod]; ok &&
val == corev1.SeccompProfileRuntimeDefault {
@@ -67,7 +67,7 @@ func init() {
fixtureData_baseline_1_19 := fixtureGenerator{
expectErrorSubstring: "seccompProfile",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
// don't generate fixtures if minimal valid pod already has seccomp config
if p.Spec.SecurityContext != nil &&
p.Spec.SecurityContext.SeccompProfile != nil &&

View File

@@ -31,7 +31,7 @@ The check implementation looks at the appropriate value based on version.
func init() {
fixtureData_restricted_1_19 := fixtureGenerator{
expectErrorSubstring: "seccompProfile",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
p = ensureSecurityContext(p)
return []*corev1.Pod{
tweak(p, func(p *corev1.Pod) {

View File

@@ -32,7 +32,7 @@ podFields: []string{
func init() {
fixtureData_1_0 := fixtureGenerator{
expectErrorSubstring: "forbidden sysctl",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
if p.Spec.SecurityContext == nil {
p.Spec.SecurityContext = &corev1.PodSecurityContext{}
}
@@ -72,7 +72,7 @@ func init() {
fixtureData_1_27 := fixtureGenerator{
expectErrorSubstring: "forbidden sysctl",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
if p.Spec.SecurityContext == nil {
p.Spec.SecurityContext = &corev1.PodSecurityContext{}
}
@@ -113,7 +113,7 @@ func init() {
fixtureDataV1Dot29 := fixtureGenerator{
expectErrorSubstring: "forbidden sysctl",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
if p.Spec.SecurityContext == nil {
p.Spec.SecurityContext = &corev1.PodSecurityContext{}
}
@@ -159,7 +159,7 @@ func init() {
fixtureDataV1Dot32 := fixtureGenerator{
expectErrorSubstring: "forbidden sysctl",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
if p.Spec.SecurityContext == nil {
p.Spec.SecurityContext = &corev1.PodSecurityContext{}
}

View File

@@ -37,7 +37,7 @@ containerFields: []string{
func init() {
fixtureData_1_0 := fixtureGenerator{
generatePass: func(p *corev1.Pod) []*corev1.Pod {
generatePass: func(p *corev1.Pod, _ api.Level) []*corev1.Pod {
// minimal valid pod already captures all valid combinations
return nil
},

View File

@@ -37,7 +37,7 @@ import (
)
const (
newestMinorVersionToTest = 34
newestMinorVersionToTest = 35
podOSBasedRestrictionEnabledVersion = 29
)
@@ -270,8 +270,9 @@ func Run(t *testing.T, opts Options) {
}
// create controller
createController := func(t *testing.T, i int, pod *corev1.Pod, expectSuccess bool, expectErrorSubstring string) {
createController := func(t *testing.T, i int, pod *corev1.Pod, expectSuccess bool, expectError bool, expectErrorSubstring string) {
t.Helper()
// avoid mutating original pod fixture
pod = pod.DeepCopy()
if pod.Labels == nil {
@@ -292,30 +293,45 @@ func Run(t *testing.T, opts Options) {
},
}
_, err := client.AppsV1().Deployments(ns).Create(context.Background(), deployment, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}})
if err != nil {
t.Errorf("%d: unexpected error creating controller with %s: %v", i, toJSON(pod), err)
failureText := ""
switch {
case expectSuccess && expectError:
t.Error("invalid test combination, cannot expectSuccess and expectError")
return
case expectError:
if err == nil {
t.Errorf("%d: expected error creating controller with %s, got none", i, toJSON(pod))
return
}
failureText = err.Error()
default:
if err != nil {
t.Errorf("%d: unexpected error creating controller with %s: %v", i, toJSON(pod), err)
return
}
failureText = strings.Join(warningHandler.FlushWarnings(), "; ")
}
warningText := strings.Join(warningHandler.FlushWarnings(), "; ")
if !expectSuccess {
if len(warningText) == 0 {
if len(failureText) == 0 {
t.Errorf("%d: expected warnings creating %s, got none", i, toJSON(pod))
return
}
if strings.Contains(warningText, policy.UnknownForbiddenReason) {
t.Errorf("%d: unexpected unknown forbidden reason creating %s: %v", i, toJSON(pod), warningText)
if strings.Contains(failureText, policy.UnknownForbiddenReason) {
t.Errorf("%d: unexpected unknown forbidden reason creating %s: %v", i, toJSON(pod), failureText)
return
}
if !strings.Contains(warningText, expectErrorSubstring) {
t.Errorf("%d: expected warning with substring %q, got %v", i, expectErrorSubstring, warningText)
if !strings.Contains(failureText, expectErrorSubstring) {
t.Errorf("%d: expected warning with substring %q, got %v", i, expectErrorSubstring, failureText)
return
}
}
if expectSuccess && len(warningText) > 0 {
if (len(expectErrorSubstring) > 0 && strings.Contains(warningText, expectErrorSubstring)) ||
strings.Contains(warningText, policy.UnknownForbiddenReason) {
t.Errorf("%d: unexpected warning creating %s: %v", i, toJSON(pod), warningText)
if expectSuccess && len(failureText) > 0 {
if (len(expectErrorSubstring) > 0 && strings.Contains(failureText, expectErrorSubstring)) ||
strings.Contains(failureText, policy.UnknownForbiddenReason) {
t.Errorf("%d: unexpected warning creating %s: %v", i, toJSON(pod), failureText)
}
}
}
@@ -339,15 +355,15 @@ func Run(t *testing.T, opts Options) {
t.Run(ns+"_pass_base", func(t *testing.T) {
createPod(t, 0, minimalValidOSNeutralPod.DeepCopy(), true, "")
createController(t, 0, minimalValidOSNeutralPod.DeepCopy(), true, "")
createController(t, 0, minimalValidOSNeutralPod.DeepCopy(), true, false, "")
if minimalValidLinuxPod != nil && minimalValidWindowsPod != nil {
// Linux specific pods
createPod(t, 0, minimalValidLinuxPod.DeepCopy(), true, "")
createController(t, 0, minimalValidLinuxPod.DeepCopy(), true, "")
createController(t, 0, minimalValidLinuxPod.DeepCopy(), true, false, "")
// Windows specific pods
createPod(t, 0, minimalValidWindowsPod.DeepCopy(), true, "")
createController(t, 0, minimalValidWindowsPod.DeepCopy(), true, "")
createController(t, 0, minimalValidWindowsPod.DeepCopy(), true, false, "")
}
})
@@ -368,7 +384,7 @@ func Run(t *testing.T, opts Options) {
t.Run(ns+"_pass_"+string(checkID), func(t *testing.T) {
for i, pod := range checkData.pass {
createPod(t, i, pod, true, "")
createController(t, i, pod, true, "")
createController(t, i, pod, true, false, "")
}
})
@@ -385,7 +401,7 @@ func Run(t *testing.T, opts Options) {
}
for i, pod := range checkData.fail {
createPod(t, i, pod, false, checkData.expectErrorSubstring)
createController(t, i, pod, false, checkData.expectErrorSubstring)
createController(t, i, pod, false, checkData.failRequiresError, checkData.expectErrorSubstring)
}
})
}

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/container1: unconfined
name: apparmorprofile0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/initcontainer1: unconfined
name: apparmorprofile1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
capabilities:
add:
- NET_RAW
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
capabilities: {}
securityContext: {}

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
capabilities: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
capabilities:
add:
- NET_RAW
securityContext: {}

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
capabilities:
add:
- chown
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
capabilities: {}
securityContext: {}

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline3
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
capabilities:
add:
- CAP_CHOWN
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
capabilities: {}
securityContext: {}

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: hostnamespaces0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
hostIPC: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: hostnamespaces1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
hostNetwork: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: hostnamespaces2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
hostPID: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: hostpathvolumes0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
volumes:
- emptyDir: {}
name: volume-emptydir
- hostPath:
path: /a
name: volume-hostpath

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: hostpathvolumes1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
volumes:
- hostPath:
path: /a
name: volume-hostpath-a
- hostPath:
path: /b
name: volume-hostpath-b

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: hostports0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
ports:
- containerPort: 12345
hostPort: 12345
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: hostports1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
ports:
- containerPort: 12346
hostPort: 12346

View File

@@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: hostports2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
ports:
- containerPort: 12345
hostPort: 12345
- containerPort: 12347
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
ports:
- containerPort: 12346
hostPort: 12346
- containerPort: 12348

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle0
spec:
containers:
- image: registry.k8s.io/pause
livenessProbe:
httpGet:
host: bad.host
port: 8080
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
readinessProbe:
tcpSocket:
host: 8.8.8.8
port: 8080
restartPolicy: Always

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle2
spec:
containers:
- image: registry.k8s.io/pause
lifecycle:
postStart:
httpGet:
host: bad.host
port: 8080
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle3
spec:
containers:
- image: registry.k8s.io/pause
livenessProbe:
httpGet:
host: 127.0.0.1
port: 8080
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle4
spec:
containers:
- image: registry.k8s.io/pause
name: container1
readinessProbe:
tcpSocket:
host: ::1
port: 8080
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: privileged0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
privileged: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext: {}
securityContext: {}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: privileged1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
privileged: true
securityContext: {}

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: procmount0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
procMount: Unmasked
hostUsers: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext: {}
securityContext: {}

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: procmount1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext: {}
hostUsers: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
procMount: Unmasked
securityContext: {}

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: seccompprofile_baseline0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext: {}
securityContext:
seccompProfile:
type: Unconfined

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: seccompprofile_baseline1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seccompProfile:
type: Unconfined
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext: {}
securityContext: {}

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: seccompprofile_baseline2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seccompProfile:
type: Unconfined
securityContext: {}

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: selinuxoptions0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seLinuxOptions: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seLinuxOptions: {}
securityContext:
seLinuxOptions:
type: somevalue

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: selinuxoptions1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seLinuxOptions:
type: somevalue
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seLinuxOptions: {}
securityContext:
seLinuxOptions: {}

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: selinuxoptions2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seLinuxOptions: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seLinuxOptions:
type: somevalue
securityContext:
seLinuxOptions: {}

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: selinuxoptions3
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seLinuxOptions: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seLinuxOptions: {}
securityContext:
seLinuxOptions:
user: somevalue

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: selinuxoptions4
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seLinuxOptions: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seLinuxOptions: {}
securityContext:
seLinuxOptions:
role: somevalue

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: sysctls0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
sysctls:
- name: othersysctl
value: other

View File

@@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: windowshostprocess0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
windowsOptions: {}
hostNetwork: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
windowsOptions: {}
securityContext:
windowsOptions:
hostProcess: true

View File

@@ -0,0 +1,20 @@
apiVersion: v1
kind: Pod
metadata:
name: windowshostprocess1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
windowsOptions:
hostProcess: true
hostNetwork: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
windowsOptions:
hostProcess: true
securityContext:
windowsOptions: {}

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/container1: localhost/foo
name: apparmorprofile0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Pod
metadata:
name: base
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,44 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
capabilities:
add:
- AUDIT_WRITE
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- MKNOD
- NET_BIND_SERVICE
- SETFCAP
- SETGID
- SETPCAP
- SETUID
- SYS_CHROOT
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
capabilities:
add:
- AUDIT_WRITE
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- MKNOD
- NET_BIND_SERVICE
- SETFCAP
- SETGID
- SETPCAP
- SETUID
- SYS_CHROOT
securityContext: {}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: hostports0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
ports:
- containerPort: 12345
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
ports:
- containerPort: 12346

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle1
spec:
containers:
- image: registry.k8s.io/pause
livenessProbe:
httpGet:
port: 8080
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: hostprobesandhostlifecycle2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
readinessProbe:
tcpSocket:
port: 8080
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: privileged0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
privileged: false
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
privileged: false
securityContext: {}

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: procmount0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
procMount: Default
hostUsers: false
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
procMount: Default
securityContext: {}

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: procmount1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
procMount: Unmasked
hostUsers: false
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
procMount: Unmasked
securityContext: {}

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: seccompprofile_baseline0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seccompProfile:
type: RuntimeDefault
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext: {}
securityContext:
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: selinuxoptions0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seLinuxOptions: {}
securityContext: {}

View File

@@ -0,0 +1,21 @@
apiVersion: v1
kind: Pod
metadata:
name: selinuxoptions1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
seLinuxOptions:
level: somevalue
type: container_init_t
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
seLinuxOptions:
type: container_kvm_t
securityContext:
seLinuxOptions:
type: container_t

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: sysctls0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext: {}

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: sysctls1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
sysctls:
- name: net.ipv4.tcp_rmem
value: 4096 87380 16777216
- name: net.ipv4.tcp_wmem
value: 4096 65536 16777216

View File

@@ -0,0 +1,25 @@
apiVersion: v1
kind: Pod
metadata:
name: allowprivilegeescalation0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,25 @@
apiVersion: v1
kind: Pod
metadata:
name: allowprivilegeescalation1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Pod
metadata:
name: allowprivilegeescalation2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,20 @@
apiVersion: v1
kind: Pod
metadata:
name: allowprivilegeescalation3
spec:
containers:
- image: registry.k8s.io/pause
name: container1
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/container1: unconfined
name: apparmorprofile0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/initcontainer1: unconfined
name: apparmorprofile1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_RAW
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_RAW
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- chown
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_baseline3
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- CAP_CHOWN
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_restricted0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities: {}
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_restricted1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities: {}
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,97 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_restricted2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- SYS_TIME
- SYS_MODULE
- SYS_RAWIO
- SYS_PACCT
- SYS_ADMIN
- SYS_NICE
- SYS_RESOURCE
- SYS_TIME
- SYS_TTY_CONFIG
- MKNOD
- AUDIT_WRITE
- AUDIT_CONTROL
- MAC_OVERRIDE
- MAC_ADMIN
- NET_ADMIN
- SYSLOG
- CHOWN
- NET_RAW
- DAC_OVERRIDE
- FOWNER
- DAC_READ_SEARCH
- FSETID
- KILL
- SETGID
- SETUID
- LINUX_IMMUTABLE
- NET_BIND_SERVICE
- NET_BROADCAST
- IPC_LOCK
- IPC_OWNER
- SYS_CHROOT
- SYS_PTRACE
- SYS_BOOT
- LEASE
- SETFCAP
- WAKE_ALARM
- BLOCK_SUSPEND
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- SYS_TIME
- SYS_MODULE
- SYS_RAWIO
- SYS_PACCT
- SYS_ADMIN
- SYS_NICE
- SYS_RESOURCE
- SYS_TIME
- SYS_TTY_CONFIG
- MKNOD
- AUDIT_WRITE
- AUDIT_CONTROL
- MAC_OVERRIDE
- MAC_ADMIN
- NET_ADMIN
- SYSLOG
- CHOWN
- NET_RAW
- DAC_OVERRIDE
- FOWNER
- DAC_READ_SEARCH
- FSETID
- KILL
- SETGID
- SETUID
- LINUX_IMMUTABLE
- NET_BIND_SERVICE
- NET_BROADCAST
- IPC_LOCK
- IPC_OWNER
- SYS_CHROOT
- SYS_PTRACE
- SYS_BOOT
- LEASE
- SETFCAP
- WAKE_ALARM
- BLOCK_SUSPEND
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,53 @@
apiVersion: v1
kind: Pod
metadata:
name: capabilities_restricted3
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- AUDIT_WRITE
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- MKNOD
- NET_BIND_SERVICE
- SETFCAP
- SETGID
- SETPCAP
- SETUID
- SYS_CHROOT
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- AUDIT_WRITE
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- MKNOD
- NET_BIND_SERVICE
- SETFCAP
- SETGID
- SETPCAP
- SETUID
- SYS_CHROOT
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,26 @@
apiVersion: v1
kind: Pod
metadata:
name: hostnamespaces0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
hostIPC: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,26 @@
apiVersion: v1
kind: Pod
metadata:
name: hostnamespaces1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
hostNetwork: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,26 @@
apiVersion: v1
kind: Pod
metadata:
name: hostnamespaces2
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
hostPID: true
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,31 @@
apiVersion: v1
kind: Pod
metadata:
name: hostpathvolumes0
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
volumes:
- emptyDir: {}
name: volume-emptydir
- hostPath:
path: /a
name: volume-hostpath

View File

@@ -0,0 +1,32 @@
apiVersion: v1
kind: Pod
metadata:
name: hostpathvolumes1
spec:
containers:
- image: registry.k8s.io/pause
name: container1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
initContainers:
- image: registry.k8s.io/pause
name: initcontainer1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
volumes:
- hostPath:
path: /a
name: volume-hostpath-a
- hostPath:
path: /b
name: volume-hostpath-b

Some files were not shown because too many files have changed in this diff Show More