KEP-3619: Fine-grained SupplementalGroups control (#117842)

* Add `Linux{Sandbox,Container}SecurityContext.SupplementalGroupsPolicy` and `ContainerStatus.user` in cri-api

* Add `PodSecurityContext.SupplementalGroupsPolicy`, `ContainerStatus.User` and its featuregate

* Implement DropDisabledPodFields for PodSecurityContext.SupplementalGroupsPolicy and ContainerStatus.User fields

* Implement kubelet so to wire between SecurityContext.SupplementalGroupsPolicy/ContainerStatus.User and cri-api in kubelet

* Clarify `SupplementalGroupsPolicy` is an OS depdendent field.

* Make `ContainerStatus.User` is initially attached user identity to the first process in the ContainerStatus

It is because, the process identity can be dynamic if the initially attached identity
has enough privilege calling setuid/setgid/setgroups syscalls in Linux.

* Rewording suggestion applied

* Add TODO comment for updating SupplementalGroupsPolicy default value in v1.34

* Added validations for SupplementalGroupsPolicy and ContainerUser

* No need featuregate check in validation when adding new field with no default value

* fix typo: identitiy -> identity

Kubernetes-commit: 552fd7e85084b4cbd3ae8e81ff13433e28dc8327
This commit is contained in:
Shingo Omura 2024-05-30 07:40:29 +09:00 committed by Kubernetes Publisher
parent e8b54718d0
commit 7adab2f2f6
8 changed files with 163 additions and 14 deletions

View File

@ -37,6 +37,7 @@ type ContainerStatusApplyConfiguration struct {
AllocatedResources *corev1.ResourceList `json:"allocatedResources,omitempty"`
Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"`
VolumeMounts []VolumeMountStatusApplyConfiguration `json:"volumeMounts,omitempty"`
User *ContainerUserApplyConfiguration `json:"user,omitempty"`
}
// ContainerStatusApplyConfiguration constructs an declarative configuration of the ContainerStatus type for use with
@ -145,3 +146,11 @@ func (b *ContainerStatusApplyConfiguration) WithVolumeMounts(values ...*VolumeMo
}
return b
}
// WithUser sets the User field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the User field is set to the value of the last call.
func (b *ContainerStatusApplyConfiguration) WithUser(value *ContainerUserApplyConfiguration) *ContainerStatusApplyConfiguration {
b.User = value
return b
}

View File

@ -0,0 +1,39 @@
/*
Copyright 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.
*/
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v1
// ContainerUserApplyConfiguration represents an declarative configuration of the ContainerUser type for use
// with apply.
type ContainerUserApplyConfiguration struct {
Linux *LinuxContainerUserApplyConfiguration `json:"linux,omitempty"`
}
// ContainerUserApplyConfiguration constructs an declarative configuration of the ContainerUser type for use with
// apply.
func ContainerUser() *ContainerUserApplyConfiguration {
return &ContainerUserApplyConfiguration{}
}
// WithLinux sets the Linux field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Linux field is set to the value of the last call.
func (b *ContainerUserApplyConfiguration) WithLinux(value *LinuxContainerUserApplyConfiguration) *ContainerUserApplyConfiguration {
b.Linux = value
return b
}

View File

@ -0,0 +1,59 @@
/*
Copyright 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.
*/
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v1
// LinuxContainerUserApplyConfiguration represents an declarative configuration of the LinuxContainerUser type for use
// with apply.
type LinuxContainerUserApplyConfiguration struct {
UID *int64 `json:"uid,omitempty"`
GID *int64 `json:"gid,omitempty"`
SupplementalGroups []int64 `json:"supplementalGroups,omitempty"`
}
// LinuxContainerUserApplyConfiguration constructs an declarative configuration of the LinuxContainerUser type for use with
// apply.
func LinuxContainerUser() *LinuxContainerUserApplyConfiguration {
return &LinuxContainerUserApplyConfiguration{}
}
// WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call.
func (b *LinuxContainerUserApplyConfiguration) WithUID(value int64) *LinuxContainerUserApplyConfiguration {
b.UID = &value
return b
}
// WithGID sets the GID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the GID field is set to the value of the last call.
func (b *LinuxContainerUserApplyConfiguration) WithGID(value int64) *LinuxContainerUserApplyConfiguration {
b.GID = &value
return b
}
// WithSupplementalGroups adds the given value to the SupplementalGroups field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the SupplementalGroups field.
func (b *LinuxContainerUserApplyConfiguration) WithSupplementalGroups(values ...int64) *LinuxContainerUserApplyConfiguration {
for i := range values {
b.SupplementalGroups = append(b.SupplementalGroups, values[i])
}
return b
}

View File

@ -25,17 +25,18 @@ import (
// PodSecurityContextApplyConfiguration represents an declarative configuration of the PodSecurityContext type for use
// with apply.
type PodSecurityContextApplyConfiguration struct {
SELinuxOptions *SELinuxOptionsApplyConfiguration `json:"seLinuxOptions,omitempty"`
WindowsOptions *WindowsSecurityContextOptionsApplyConfiguration `json:"windowsOptions,omitempty"`
RunAsUser *int64 `json:"runAsUser,omitempty"`
RunAsGroup *int64 `json:"runAsGroup,omitempty"`
RunAsNonRoot *bool `json:"runAsNonRoot,omitempty"`
SupplementalGroups []int64 `json:"supplementalGroups,omitempty"`
FSGroup *int64 `json:"fsGroup,omitempty"`
Sysctls []SysctlApplyConfiguration `json:"sysctls,omitempty"`
FSGroupChangePolicy *corev1.PodFSGroupChangePolicy `json:"fsGroupChangePolicy,omitempty"`
SeccompProfile *SeccompProfileApplyConfiguration `json:"seccompProfile,omitempty"`
AppArmorProfile *AppArmorProfileApplyConfiguration `json:"appArmorProfile,omitempty"`
SELinuxOptions *SELinuxOptionsApplyConfiguration `json:"seLinuxOptions,omitempty"`
WindowsOptions *WindowsSecurityContextOptionsApplyConfiguration `json:"windowsOptions,omitempty"`
RunAsUser *int64 `json:"runAsUser,omitempty"`
RunAsGroup *int64 `json:"runAsGroup,omitempty"`
RunAsNonRoot *bool `json:"runAsNonRoot,omitempty"`
SupplementalGroups []int64 `json:"supplementalGroups,omitempty"`
SupplementalGroupsPolicy *corev1.SupplementalGroupsPolicy `json:"supplementalGroupsPolicy,omitempty"`
FSGroup *int64 `json:"fsGroup,omitempty"`
Sysctls []SysctlApplyConfiguration `json:"sysctls,omitempty"`
FSGroupChangePolicy *corev1.PodFSGroupChangePolicy `json:"fsGroupChangePolicy,omitempty"`
SeccompProfile *SeccompProfileApplyConfiguration `json:"seccompProfile,omitempty"`
AppArmorProfile *AppArmorProfileApplyConfiguration `json:"appArmorProfile,omitempty"`
}
// PodSecurityContextApplyConfiguration constructs an declarative configuration of the PodSecurityContext type for use with
@ -94,6 +95,14 @@ func (b *PodSecurityContextApplyConfiguration) WithSupplementalGroups(values ...
return b
}
// WithSupplementalGroupsPolicy sets the SupplementalGroupsPolicy field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SupplementalGroupsPolicy field is set to the value of the last call.
func (b *PodSecurityContextApplyConfiguration) WithSupplementalGroupsPolicy(value corev1.SupplementalGroupsPolicy) *PodSecurityContextApplyConfiguration {
b.SupplementalGroupsPolicy = &value
return b
}
// WithFSGroup sets the FSGroup field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the FSGroup field is set to the value of the last call.

View File

@ -5084,6 +5084,9 @@ var schemaYAML = typed.YAMLObject(`types:
type:
namedType: io.k8s.api.core.v1.ContainerState
default: {}
- name: user
type:
namedType: io.k8s.api.core.v1.ContainerUser
- name: volumeMounts
type:
list:
@ -5092,6 +5095,12 @@ var schemaYAML = typed.YAMLObject(`types:
elementRelationship: associative
keys:
- mountPath
- name: io.k8s.api.core.v1.ContainerUser
map:
fields:
- name: linux
type:
namedType: io.k8s.api.core.v1.LinuxContainerUser
- name: io.k8s.api.core.v1.DaemonEndpoint
map:
fields:
@ -5851,6 +5860,23 @@ var schemaYAML = typed.YAMLObject(`types:
elementType:
namedType: io.k8s.api.core.v1.LimitRangeItem
elementRelationship: atomic
- name: io.k8s.api.core.v1.LinuxContainerUser
map:
fields:
- name: gid
type:
scalar: numeric
default: 0
- name: supplementalGroups
type:
list:
elementType:
scalar: numeric
elementRelationship: atomic
- name: uid
type:
scalar: numeric
default: 0
- name: io.k8s.api.core.v1.LoadBalancerIngress
map:
fields:
@ -6822,6 +6848,9 @@ var schemaYAML = typed.YAMLObject(`types:
elementType:
scalar: numeric
elementRelationship: atomic
- name: supplementalGroupsPolicy
type:
scalar: string
- name: sysctls
type:
list:

View File

@ -681,6 +681,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationscorev1.ContainerStateWaitingApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("ContainerStatus"):
return &applyconfigurationscorev1.ContainerStatusApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("ContainerUser"):
return &applyconfigurationscorev1.ContainerUserApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("CSIPersistentVolumeSource"):
return &applyconfigurationscorev1.CSIPersistentVolumeSourceApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("CSIVolumeSource"):
@ -767,6 +769,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationscorev1.LimitRangeItemApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("LimitRangeSpec"):
return &applyconfigurationscorev1.LimitRangeSpecApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("LinuxContainerUser"):
return &applyconfigurationscorev1.LinuxContainerUserApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("LoadBalancerIngress"):
return &applyconfigurationscorev1.LoadBalancerIngressApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("LoadBalancerStatus"):

2
go.mod
View File

@ -25,7 +25,7 @@ require (
golang.org/x/time v0.3.0
google.golang.org/protobuf v1.33.0
gopkg.in/evanphx/json-patch.v4 v4.12.0
k8s.io/api v0.0.0-20240529203521-42619825cf01
k8s.io/api v0.0.0-20240529224029-d93eaf6729fd
k8s.io/apimachinery v0.0.0-20240529203233-63ab494c70e6
k8s.io/klog/v2 v2.120.1
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340

4
go.sum
View File

@ -153,8 +153,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.0.0-20240529203521-42619825cf01 h1:174qeH6d5KbPVqH3AiRwaPF3KLywgsXd3Urb8fB/brY=
k8s.io/api v0.0.0-20240529203521-42619825cf01/go.mod h1:4/2Gq0qr5DtTHoaH7lfOKW6+ZMSOJwvVvbojJlldJh8=
k8s.io/api v0.0.0-20240529224029-d93eaf6729fd h1:voEDf2CuLj5eRTo2rz2qNJwYUP9aPfOZy21SA++W71Q=
k8s.io/api v0.0.0-20240529224029-d93eaf6729fd/go.mod h1:4/2Gq0qr5DtTHoaH7lfOKW6+ZMSOJwvVvbojJlldJh8=
k8s.io/apimachinery v0.0.0-20240529203233-63ab494c70e6 h1:MyOUvhoFRNxMeVhvXMui7xb2huAQiys6tlcNBzvPSb8=
k8s.io/apimachinery v0.0.0-20240529203233-63ab494c70e6/go.mod h1:ClkKrTMwhmMjgsEHpX2w3F+YKj0ctDOaAxqL7clxG0U=
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=