rebase: update kubernetes dep to 1.24.0

As kubernetes 1.24.0 is released, updating
kubernetes dependencies to 1.24.0

updates: #3086

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna
2022-05-05 08:17:06 +05:30
committed by mergify[bot]
parent fc1529f268
commit c4f79d455f
959 changed files with 80055 additions and 27456 deletions

View File

@ -1,5 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- justinsb
- freehan
- justinsb
- freehan

View File

@ -2,7 +2,7 @@
# approval on api packages bubbles to api-approvers
reviewers:
- sig-apps-api-reviewers
- sig-apps-api-approvers
- sig-apps-api-reviewers
- sig-apps-api-approvers
labels:
- sig/apps
- sig/apps

View File

@ -92,9 +92,20 @@ const (
// RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.
type RollingUpdateStatefulSetStrategy struct {
// Partition indicates the ordinal at which the StatefulSet should be
// partitioned.
// Partition indicates the ordinal at which the StatefulSet should be partitioned
// for updates. During a rolling update, all pods from ordinal Replicas-1 to
// Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched.
// This is helpful in being able to do a canary based deployment. The default value is 0.
Partition int32
// The maximum number of pods that can be unavailable during the update.
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
// Absolute number is calculated from percentage by rounding up. This can not be 0.
// Defaults to 1. This field is alpha-level and is only honored by servers that enable the
// MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to
// Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it
// will be counted towards MaxUnavailable.
// +optional
MaxUnavailable *intstr.IntOrString
}
// PersistentVolumeClaimRetentionPolicyType is a string enumeration of the policies that will determine
@ -246,6 +257,7 @@ type StatefulSetStatus struct {
// Total number of available pods (ready for at least minReadySeconds) targeted by this statefulset.
// This is a beta field and requires enabling StatefulSetMinReadySeconds feature gate.
// +optional
AvailableReplicas int32
}

View File

@ -24,6 +24,7 @@ package apps
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
intstr "k8s.io/apimachinery/pkg/util/intstr"
core "k8s.io/kubernetes/pkg/apis/core"
)
@ -621,6 +622,11 @@ func (in *RollingUpdateDeployment) DeepCopy() *RollingUpdateDeployment {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RollingUpdateStatefulSetStrategy) DeepCopyInto(out *RollingUpdateStatefulSetStrategy) {
*out = *in
if in.MaxUnavailable != nil {
in, out := &in.MaxUnavailable, &out.MaxUnavailable
*out = new(intstr.IntOrString)
**out = **in
}
return
}
@ -807,7 +813,7 @@ func (in *StatefulSetUpdateStrategy) DeepCopyInto(out *StatefulSetUpdateStrategy
if in.RollingUpdate != nil {
in, out := &in.RollingUpdate, &out.RollingUpdate
*out = new(RollingUpdateStatefulSetStrategy)
**out = **in
(*in).DeepCopyInto(*out)
}
return
}

View File

@ -1,14 +1,12 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- caesarxuchao
- sttts
- ncdc
- piosz
- dims
- errordeveloper
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- caesarxuchao
- sttts
- ncdc
- dims

View File

@ -2,7 +2,7 @@
# approval on api packages bubbles to api-approvers
reviewers:
- sig-apps-api-reviewers
- sig-apps-api-approvers
- sig-apps-api-reviewers
- sig-apps-api-approvers
labels:
- sig/apps
- sig/apps

View File

@ -194,9 +194,10 @@ type JobSpec struct {
// `$(job-name)-$(index)-$(random-string)`,
// the Pod hostname takes the form `$(job-name)-$(index)`.
//
// This field is beta-level. More completion modes can be added in the future.
// If the Job controller observes a mode that it doesn't recognize, the
// controller skips updates for the Job.
// More completion modes can be added in the future.
// If the Job controller observes a mode that it doesn't recognize, which
// is possible during upgrades due to version skew, the controller
// skips updates for the Job.
// +optional
CompletionMode *CompletionMode
@ -208,9 +209,6 @@ type JobSpec struct {
// Suspending a Job will reset the StartTime field of the Job, effectively
// resetting the ActiveDeadlineSeconds timer too. Defaults to false.
//
// This field is beta-level, gated by SuspendJob feature flag (enabled by
// default).
//
// +optional
Suspend *bool
}
@ -247,8 +245,8 @@ type JobStatus struct {
// The number of active pods which have a Ready condition.
//
// This field is alpha-level. The job controller populates the field when
// the feature gate JobReadyPods is enabled (disabled by default).
// This field is beta-level. The job controller populates the field when
// the feature gate JobReadyPods is enabled (enabled by default).
// +optional
Ready *int32
@ -378,6 +376,12 @@ type CronJobSpec struct {
// The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
Schedule string
// The time zone for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
// If not specified, this will rely on the time zone of the kube-controller-manager process.
// ALPHA: This field is in alpha and must be enabled via the `CronJobTimeZone` feature gate.
// +optional
TimeZone *string
// Optional deadline in seconds for starting the job if it misses scheduled
// time for any reason. Missed jobs executions will be counted as failed ones.
// +optional

View File

@ -92,6 +92,11 @@ func (in *CronJobList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CronJobSpec) DeepCopyInto(out *CronJobSpec) {
*out = *in
if in.TimeZone != nil {
in, out := &in.TimeZone, &out.TimeZone
*out = new(string)
**out = **in
}
if in.StartingDeadlineSeconds != nil {
in, out := &in.StartingDeadlineSeconds, &out.StartingDeadlineSeconds
*out = new(int64)

View File

@ -1,4 +1,4 @@
# See the OWNERS docs at https://go.k8s.io/owners
labels:
- sig/apps
- sig/apps

View File

@ -123,9 +123,8 @@ var standardResourceQuotaScopes = sets.NewString(
)
// IsStandardResourceQuotaScope returns true if the scope is a standard value
func IsStandardResourceQuotaScope(str string, allowNamespaceAffinityScope bool) bool {
return standardResourceQuotaScopes.Has(str) ||
(allowNamespaceAffinityScope && str == string(core.ResourceQuotaScopeCrossNamespacePodAffinity))
func IsStandardResourceQuotaScope(str string) bool {
return standardResourceQuotaScopes.Has(str) || str == string(core.ResourceQuotaScopeCrossNamespacePodAffinity)
}
var podObjectCountQuotaResources = sets.NewString(

View File

@ -1,9 +1,9 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- lavalamp
- smarterclayton
- deads2k
- caesarxuchao
- liggitt
- dims
- lavalamp
- smarterclayton
- deads2k
- caesarxuchao
- liggitt
- dims

View File

@ -472,7 +472,7 @@ type PersistentVolumeClaimSpec struct {
// * While DataSource ignores disallowed values (dropping them), DataSourceRef
// preserves all values, and generates an error if a disallowed value is
// specified.
// (Alpha) Using this field requires the AnyVolumeDataSource feature gate to be enabled.
// (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.
// +optional
DataSourceRef *TypedLocalObjectReference
}
@ -2160,7 +2160,7 @@ type Container struct {
Name string
// Required.
Image string
// Optional: The docker image's entrypoint is used if this is not provided; cannot be updated.
// Optional: The container image's entrypoint is used if this is not provided; cannot be updated.
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
@ -2168,7 +2168,7 @@ type Container struct {
// of whether the variable exists or not.
// +optional
Command []string
// Optional: The docker image's cmd is used if this is not provided; cannot be updated.
// Optional: The container image's cmd is used if this is not provided; cannot be updated.
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
@ -2176,7 +2176,7 @@ type Container struct {
// of whether the variable exists or not.
// +optional
Args []string
// Optional: Defaults to Docker's default.
// Optional: Defaults to the container runtime's default working directory.
// +optional
WorkingDir string
// +optional
@ -2243,7 +2243,7 @@ type ProbeHandler struct {
TCPSocket *TCPSocketAction
// GRPC specifies an action involving a GRPC port.
// This is an alpha field and requires enabling GRPCContainerProbe feature gate.
// This is a beta field and requires enabling GRPCContainerProbe feature gate.
// +featureGate=GRPCContainerProbe
// +optional
GRPC *GRPCAction
@ -2662,7 +2662,7 @@ type PodAffinityTerm struct {
// namespaces specifies a static list of namespace names that the term applies to.
// The term is applied to the union of the namespaces listed in this field
// and the ones selected by namespaceSelector.
// null or empty namespaces list and null namespaceSelector means "this pod's namespace"
// null or empty namespaces list and null namespaceSelector means "this pod's namespace".
// +optional
Namespaces []string
// This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching
@ -2676,7 +2676,6 @@ type PodAffinityTerm struct {
// and the ones listed in the namespaces field.
// null selector and null or empty namespaces list means "this pod's namespace".
// An empty selector ({}) matches all namespaces.
// This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
// +optional
NamespaceSelector *metav1.LabelSelector
}
@ -2868,8 +2867,7 @@ type PodSpec struct {
// +optional
SecurityContext *PodSecurityContext
// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
// If specified, these secrets will be passed to individual puller implementations for them to use. For example,
// in the case of docker, only DockerConfig type secrets are honored.
// If specified, these secrets will be passed to individual puller implementations for them to use.
// +optional
ImagePullSecrets []LocalObjectReference
// Specifies the hostname of the Pod.
@ -2918,7 +2916,6 @@ type PodSpec struct {
// PreemptionPolicy is the Policy for preempting pods with lower priority.
// One of Never, PreemptLowerPriority.
// Defaults to PreemptLowerPriority if unset.
// This field is beta-level, gated by the NonPreemptingPriority feature-gate.
// +optional
PreemptionPolicy *PreemptionPolicy
// Specifies the DNS parameters of a pod.
@ -2946,7 +2943,6 @@ type PodSpec struct {
// set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value
// defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero.
// More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead
// This field is beta-level as of Kubernetes v1.18, and is only honored by servers that enable the PodOverhead feature.
// +optional
Overhead ResourceList
// EnableServiceLinks indicates whether information about services should be injected into pod's
@ -2987,7 +2983,7 @@ type PodSpec struct {
// - spec.containers[*].securityContext.runAsUser
// - spec.containers[*].securityContext.runAsGroup
// +optional
// This is an alpha field and requires the IdentifyPodOS feature
// This is a beta field and requires the IdentifyPodOS feature
OS *PodOS
}
@ -3233,7 +3229,7 @@ type EphemeralContainerCommon struct {
Name string
// Required.
Image string
// Optional: The docker image's entrypoint is used if this is not provided; cannot be updated.
// Optional: The container image's entrypoint is used if this is not provided; cannot be updated.
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
@ -3241,7 +3237,7 @@ type EphemeralContainerCommon struct {
// of whether the variable exists or not.
// +optional
Command []string
// Optional: The docker image's cmd is used if this is not provided; cannot be updated.
// Optional: The container image's cmd is used if this is not provided; cannot be updated.
// Variable references $(VAR_NAME) are expanded using the container's environment. If a variable
// cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
@ -3249,7 +3245,7 @@ type EphemeralContainerCommon struct {
// of whether the variable exists or not.
// +optional
Args []string
// Optional: Defaults to Docker's default.
// Optional: Defaults to the container runtime's default working directory.
// +optional
WorkingDir string
// Ports are not allowed for ephemeral containers.
@ -3380,11 +3376,7 @@ type PodStatus struct {
// startTime set.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-and-container-status
InitContainerStatuses []ContainerStatus
// The list has one entry per container in the manifest. Each entry is
// currently the output of `docker inspect`. This output format is *not*
// final and should not be relied upon.
// TODO: Make real decisions about what our info should look like. Re-enable fuzz test
// when we have done this.
// The list has one entry per app container in the manifest.
// +optional
ContainerStatuses []ContainerStatus
@ -3840,6 +3832,10 @@ type ServiceSpec struct {
// This feature depends on whether the underlying cloud-provider supports specifying
// the loadBalancerIP when a load balancer is created.
// This field will be ignored if the cloud-provider does not support the feature.
// Deprecated: This field was under-specified and its meaning varies across implementations,
// and it cannot support dual-stack.
// As of Kubernetes v1.24, users are encouraged to use implementation-specific annotations when available.
// This field may be removed in a future API version.
// +optional
LoadBalancerIP string
@ -3892,7 +3888,6 @@ type ServiceSpec struct {
// value), those requests will be respected, regardless of this field.
// This field may only be set for services with type LoadBalancer and will
// be cleared if the type is changed to any other type.
// This field is beta-level and is only honored by servers that enable the ServiceLBNodePortControl feature.
// +optional
AllocateLoadBalancerNodePorts *bool
@ -3935,7 +3930,7 @@ type ServicePort struct {
// The application protocol for this port.
// This field follows standard Kubernetes label syntax.
// Un-prefixed names are reserved for IANA standard service names (as per
// RFC-6335 and http://www.iana.org/assignments/service-names).
// RFC-6335 and https://www.iana.org/assignments/service-names).
// Non-standard protocols should use prefixed names such as
// mycompany.com/my-custom-protocol.
// +optional
@ -3987,7 +3982,10 @@ type ServiceAccount struct {
// +optional
metav1.ObjectMeta
// Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount
// Secrets is a list of the secrets in the same namespace that pods running using this ServiceAccount are allowed to use.
// Pods are only limited to this list if this service account has a "kubernetes.io/enforce-mountable-secrets" annotation set to "true".
// This field should not be used to find auto-generated service account token secrets for use outside of pods.
// Instead, tokens can be requested directly using the TokenRequest API, or service account token secrets can be manually created.
Secrets []ObjectReference
// ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images
@ -4085,7 +4083,7 @@ type EndpointPort struct {
// The application protocol for this port.
// This field follows standard Kubernetes label syntax.
// Un-prefixed names are reserved for IANA standard service names (as per
// RFC-6335 and http://www.iana.org/assignments/service-names).
// RFC-6335 and https://www.iana.org/assignments/service-names).
// Non-standard protocols should use prefixed names such as
// mycompany.com/my-custom-protocol.
// +optional
@ -4124,8 +4122,7 @@ type NodeSpec struct {
// +optional
Taints []Taint
// If specified, the source to get node configuration from
// The DynamicKubeletConfig feature gate must be enabled for the Kubelet to use this field
// Deprecated: Previously used to specify the source of the node's configuration for the DynamicKubeletConfig feature. This feature is removed from Kubelets as of 1.24 and will be fully removed in 1.26.
// +optional
ConfigSource *NodeConfigSource
@ -4135,12 +4132,12 @@ type NodeSpec struct {
DoNotUseExternalID string
}
// NodeConfigSource specifies a source of node configuration. Exactly one subfield must be non-nil.
// Deprecated: NodeConfigSource specifies a source of node configuration. Exactly one subfield must be non-nil.
type NodeConfigSource struct {
ConfigMap *ConfigMapNodeConfigSource
}
// ConfigMapNodeConfigSource represents the config map of a node
// Deprecated: ConfigMapNodeConfigSource represents the config map of a node
type ConfigMapNodeConfigSource struct {
// Namespace is the metadata.namespace of the referenced ConfigMap.
// This field is required in all cases.
@ -5064,7 +5061,6 @@ const (
// Match all pod objects that have priority class mentioned
ResourceQuotaScopePriorityClass ResourceQuotaScope = "PriorityClass"
// Match all pod objects that have cross-namespace pod (anti)affinity mentioned
// This is a beta feature enabled by the PodAffinityNamespaceSelector feature flag.
ResourceQuotaScopeCrossNamespacePodAffinity ResourceQuotaScope = "CrossNamespacePodAffinity"
)
@ -5603,15 +5599,18 @@ type TopologySpreadConstraint struct {
// MaxSkew describes the degree to which pods may be unevenly distributed.
// When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference
// between the number of matching pods in the target topology and the global minimum.
// The global minimum is the minimum number of matching pods in an eligible domain
// or zero if the number of eligible domains is less than MinDomains.
// For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same
// labelSelector spread as 1/1/0:
// labelSelector spread as 2/2/1:
// In this case, the global minimum is 1.
// +-------+-------+-------+
// | zone1 | zone2 | zone3 |
// +-------+-------+-------+
// | P | P | |
// | P P | P P | P |
// +-------+-------+-------+
// - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 1/1/1;
// scheduling it onto zone1(zone2) would make the ActualSkew(2-0) on zone1(zone2)
// - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2;
// scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2)
// violate MaxSkew(1).
// - if MaxSkew is 2, incoming pod can be scheduled onto any zone.
// When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence
@ -5622,6 +5621,10 @@ type TopologySpreadConstraint struct {
// and identical values are considered to be in the same topology.
// We consider each <key, value> as a "bucket", and try to put balanced number
// of pods into each bucket.
// We define a domain as a particular instance of a topology.
// Also, we define an eligible domain as a domain whose nodes match the node selector.
// e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology.
// And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology.
// It's a required field.
TopologyKey string
// WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy
@ -5651,6 +5654,32 @@ type TopologySpreadConstraint struct {
// in their corresponding topology domain.
// +optional
LabelSelector *metav1.LabelSelector
// MinDomains indicates a minimum number of eligible domains.
// When the number of eligible domains with matching topology keys is less than minDomains,
// Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed.
// And when the number of eligible domains with matching topology keys equals or greater than minDomains,
// this value has no effect on scheduling.
// As a result, when the number of eligible domains is less than minDomains,
// scheduler won't schedule more than maxSkew Pods to those domains.
// If value is nil, the constraint behaves as if MinDomains is equal to 1.
// Valid values are integers greater than 0.
// When value is not nil, WhenUnsatisfiable must be DoNotSchedule.
//
// For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same
// labelSelector spread as 2/2/2:
// +-------+-------+-------+
// | zone1 | zone2 | zone3 |
// +-------+-------+-------+
// | P P | P P | P P |
// +-------+-------+-------+
// The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0.
// In this situation, new pod with the same labelSelector cannot be scheduled,
// because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones,
// it will violate MaxSkew.
//
// This is an alpha field and requires enabling MinDomainsInPodTopologySpread feature gate.
// +optional
MinDomains *int32
}
// These are the built-in errors for PortStatus.

View File

@ -1,32 +1,24 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- yujuhong
- brendandburns
- derekwaynecarr
- caesarxuchao
- vishh
- mikedanese
- liggitt
- davidopp
- pmorie
- sttts
- dchen1107
- saad-ali
- luxas
- janetkuo
- justinsb
- ncdc
- tallclair
- piosz
- jsafrane
- dims
- errordeveloper
- krousey
- jayunit100
- rootfs
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- yujuhong
- derekwaynecarr
- caesarxuchao
- mikedanese
- liggitt
- sttts
- dchen1107
- saad-ali
- luxas
- janetkuo
- justinsb
- ncdc
- tallclair
- jsafrane
- dims
- jayunit100

View File

@ -22,11 +22,10 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/parsers"
utilpointer "k8s.io/utils/pointer"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/util/parsers"
"k8s.io/utils/pointer"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
@ -64,7 +63,7 @@ func SetDefaults_ReplicationController(obj *v1.ReplicationController) {
}
}
func SetDefaults_Volume(obj *v1.Volume) {
if utilpointer.AllPtrFieldsNil(&obj.VolumeSource) {
if pointer.AllPtrFieldsNil(&obj.VolumeSource) {
obj.VolumeSource = v1.VolumeSource{
EmptyDir: &v1.EmptyDirVolumeSource{},
}
@ -131,16 +130,19 @@ func SetDefaults_Service(obj *v1.Service) {
obj.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeCluster
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) && obj.Spec.InternalTrafficPolicy == nil {
serviceInternalTrafficPolicyCluster := v1.ServiceInternalTrafficPolicyCluster
obj.Spec.InternalTrafficPolicy = &serviceInternalTrafficPolicyCluster
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
if obj.Spec.InternalTrafficPolicy == nil {
if obj.Spec.Type == v1.ServiceTypeNodePort || obj.Spec.Type == v1.ServiceTypeLoadBalancer || obj.Spec.Type == v1.ServiceTypeClusterIP {
serviceInternalTrafficPolicyCluster := v1.ServiceInternalTrafficPolicyCluster
obj.Spec.InternalTrafficPolicy = &serviceInternalTrafficPolicyCluster
}
}
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceLBNodePortControl) {
if obj.Spec.Type == v1.ServiceTypeLoadBalancer {
if obj.Spec.AllocateLoadBalancerNodePorts == nil {
obj.Spec.AllocateLoadBalancerNodePorts = utilpointer.BoolPtr(true)
}
if obj.Spec.Type == v1.ServiceTypeLoadBalancer {
if obj.Spec.AllocateLoadBalancerNodePorts == nil {
obj.Spec.AllocateLoadBalancerNodePorts = pointer.BoolPtr(true)
}
}
}
@ -326,20 +328,17 @@ func SetDefaults_HTTPGetAction(obj *v1.HTTPGetAction) {
// SetDefaults_Namespace adds a default label for all namespaces
func SetDefaults_Namespace(obj *v1.Namespace) {
// TODO, remove the feature gate in 1.22
// we can't SetDefaults for nameless namespaces (generateName).
// This code needs to be kept in sync with the implementation that exists
// in Namespace Canonicalize strategy (pkg/registry/core/namespace)
// note that this can result in many calls to feature enablement in some cases, but
// we assume that there's no real cost there.
if utilfeature.DefaultFeatureGate.Enabled(features.NamespaceDefaultLabelName) {
if len(obj.Name) > 0 {
if obj.Labels == nil {
obj.Labels = map[string]string{}
}
obj.Labels[v1.LabelMetadataName] = obj.Name
if len(obj.Name) > 0 {
if obj.Labels == nil {
obj.Labels = map[string]string{}
}
obj.Labels[v1.LabelMetadataName] = obj.Name
}
}

View File

@ -7994,6 +7994,7 @@ func autoConvert_v1_TopologySpreadConstraint_To_core_TopologySpreadConstraint(in
out.TopologyKey = in.TopologyKey
out.WhenUnsatisfiable = core.UnsatisfiableConstraintAction(in.WhenUnsatisfiable)
out.LabelSelector = (*metav1.LabelSelector)(unsafe.Pointer(in.LabelSelector))
out.MinDomains = (*int32)(unsafe.Pointer(in.MinDomains))
return nil
}
@ -8007,6 +8008,7 @@ func autoConvert_core_TopologySpreadConstraint_To_v1_TopologySpreadConstraint(in
out.TopologyKey = in.TopologyKey
out.WhenUnsatisfiable = v1.UnsatisfiableConstraintAction(in.WhenUnsatisfiable)
out.LabelSelector = (*metav1.LabelSelector)(unsafe.Pointer(in.LabelSelector))
out.MinDomains = (*int32)(unsafe.Pointer(in.MinDomains))
return nil
}

View File

@ -1,31 +1,23 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- yujuhong
- brendandburns
- derekwaynecarr
- caesarxuchao
- vishh
- mikedanese
- liggitt
- davidopp
- pmorie
- sttts
- quinton-hoole
- dchen1107
- janetkuo
- justinsb
- pwittrock
- tallclair
- soltysh
- piosz
- jsafrane
- dims
- fejta
- krousey
- rootfs
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- yujuhong
- derekwaynecarr
- caesarxuchao
- mikedanese
- liggitt
- sttts
- dchen1107
- janetkuo
- justinsb
- pwittrock
- tallclair
- soltysh
- jsafrane
- dims
- fejta

View File

@ -29,6 +29,7 @@ import (
"unicode"
"unicode/utf8"
"github.com/google/go-cmp/cmp"
v1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/resource"
@ -36,7 +37,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation"
@ -53,7 +53,6 @@ import (
"k8s.io/kubernetes/pkg/cluster/ports"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/fieldpath"
"k8s.io/kubernetes/pkg/security/apparmor"
netutils "k8s.io/utils/net"
)
@ -288,9 +287,6 @@ var ValidateServiceAccountName = apimachineryvalidation.ValidateServiceAccountNa
// trailing dashes are allowed.
var ValidateEndpointsName = apimachineryvalidation.NameIsDNSSubdomain
// ValidateClusterName can be used to check whether the given cluster name is valid.
var ValidateClusterName = apimachineryvalidation.ValidateClusterName
// ValidateClassName can be used to check whether the given class name is valid.
// It is defined here to avoid import cycle between pkg/apis/storage/validation
// (where it should be) and this file.
@ -1589,12 +1585,12 @@ func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, fldP
if csi.NodePublishSecretRef != nil {
if len(csi.NodePublishSecretRef.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef ", "name"), ""))
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef", "name"), ""))
} else {
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodePublishSecretRef.Name, fldPath.Child("name"))...)
}
if len(csi.NodePublishSecretRef.Namespace) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef ", "namespace"), ""))
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef", "namespace"), ""))
} else {
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodePublishSecretRef.Namespace, fldPath.Child("namespace"))...)
}
@ -1609,7 +1605,7 @@ func validateCSIVolumeSource(csi *core.CSIVolumeSource, fldPath *field.Path) fie
if csi.NodePublishSecretRef != nil {
if len(csi.NodePublishSecretRef.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef ", "name"), ""))
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef", "name"), ""))
} else {
for _, msg := range ValidateSecretName(csi.NodePublishSecretRef.Name, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), csi.NodePublishSecretRef.Name, msg))
@ -1998,7 +1994,7 @@ func ValidatePersistentVolumeUpdate(newPv, oldPv *core.PersistentVolume, opts Pe
// PersistentVolumeSource should be immutable after creation.
if !apiequality.Semantic.DeepEqual(newPv.Spec.PersistentVolumeSource, oldPv.Spec.PersistentVolumeSource) {
pvcSourceDiff := diff.ObjectDiff(newPv.Spec.PersistentVolumeSource, oldPv.Spec.PersistentVolumeSource)
pvcSourceDiff := cmp.Diff(oldPv.Spec.PersistentVolumeSource, newPv.Spec.PersistentVolumeSource)
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "persistentvolumesource"), fmt.Sprintf("spec.persistentvolumesource is immutable after creation\n%v", pvcSourceDiff)))
}
allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.VolumeMode, oldPv.Spec.VolumeMode, field.NewPath("volumeMode"))...)
@ -2023,8 +2019,6 @@ func ValidatePersistentVolumeStatusUpdate(newPv, oldPv *core.PersistentVolume) f
type PersistentVolumeClaimSpecValidationOptions struct {
// Allow spec to contain the "ReadWiteOncePod" access mode
AllowReadWriteOncePod bool
// Allow pvc expansion after PVC is created and bound to a PV
EnableExpansion bool
// Allow users to recover from previously failing expansion operation
EnableRecoverFromExpansionFailure bool
}
@ -2032,7 +2026,6 @@ type PersistentVolumeClaimSpecValidationOptions struct {
func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolumeClaim) PersistentVolumeClaimSpecValidationOptions {
opts := PersistentVolumeClaimSpecValidationOptions{
AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),
EnableExpansion: utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes),
EnableRecoverFromExpansionFailure: utilfeature.DefaultFeatureGate.Enabled(features.RecoverVolumeExpansionFailure),
}
if oldPvc == nil {
@ -2179,40 +2172,30 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeCl
allErrs = append(allErrs, ValidateImmutableAnnotation(newPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], oldPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], v1.BetaStorageClassAnnotation, field.NewPath("metadata"))...)
}
if opts.EnableExpansion {
// lets make sure storage values are same.
if newPvc.Status.Phase == core.ClaimBound && newPvcClone.Spec.Resources.Requests != nil {
newPvcClone.Spec.Resources.Requests["storage"] = oldPvc.Spec.Resources.Requests["storage"] // +k8s:verify-mutation:reason=clone
}
// lets make sure storage values are same.
if newPvc.Status.Phase == core.ClaimBound && newPvcClone.Spec.Resources.Requests != nil {
newPvcClone.Spec.Resources.Requests["storage"] = oldPvc.Spec.Resources.Requests["storage"] // +k8s:verify-mutation:reason=clone
}
oldSize := oldPvc.Spec.Resources.Requests["storage"]
newSize := newPvc.Spec.Resources.Requests["storage"]
statusSize := oldPvc.Status.Capacity["storage"]
oldSize := oldPvc.Spec.Resources.Requests["storage"]
newSize := newPvc.Spec.Resources.Requests["storage"]
statusSize := oldPvc.Status.Capacity["storage"]
if !apiequality.Semantic.DeepEqual(newPvcClone.Spec, oldPvcClone.Spec) {
specDiff := diff.ObjectDiff(newPvcClone.Spec, oldPvcClone.Spec)
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), fmt.Sprintf("spec is immutable after creation except resources.requests for bound claims\n%v", specDiff)))
}
if newSize.Cmp(oldSize) < 0 {
if !opts.EnableRecoverFromExpansionFailure {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "resources", "requests", "storage"), "field can not be less than previous value"))
} else {
// This validation permits reducing pvc requested size up to capacity recorded in pvc.status
// so that users can recover from volume expansion failure, but Kubernetes does not actually
// support volume shrinking
if newSize.Cmp(statusSize) <= 0 {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "resources", "requests", "storage"), "field can not be less than status.capacity"))
}
if !apiequality.Semantic.DeepEqual(newPvcClone.Spec, oldPvcClone.Spec) {
specDiff := cmp.Diff(oldPvcClone.Spec, newPvcClone.Spec)
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), fmt.Sprintf("spec is immutable after creation except resources.requests for bound claims\n%v", specDiff)))
}
if newSize.Cmp(oldSize) < 0 {
if !opts.EnableRecoverFromExpansionFailure {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "resources", "requests", "storage"), "field can not be less than previous value"))
} else {
// This validation permits reducing pvc requested size up to capacity recorded in pvc.status
// so that users can recover from volume expansion failure, but Kubernetes does not actually
// support volume shrinking
if newSize.Cmp(statusSize) <= 0 {
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "resources", "requests", "storage"), "field can not be less than status.capacity"))
}
}
} else {
// changes to Spec are not allowed, but updates to label/and some annotations are OK.
// no-op updates pass validation.
if !apiequality.Semantic.DeepEqual(newPvcClone.Spec, oldPvcClone.Spec) {
specDiff := diff.ObjectDiff(newPvcClone.Spec, oldPvcClone.Spec)
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), fmt.Sprintf("field is immutable after creation\n%v", specDiff)))
}
}
allErrs = append(allErrs, ValidateImmutableField(newPvc.Spec.VolumeMode, oldPvc.Spec.VolumeMode, field.NewPath("volumeMode"))...)
@ -3236,9 +3219,7 @@ func validatePodDNSConfig(dnsConfig *core.PodDNSConfig, dnsPolicy *core.DNSPolic
}
for i, search := range dnsConfig.Searches {
// it is fine to have a trailing dot
if strings.HasSuffix(search, ".") {
search = search[0 : len(search)-1]
}
search = strings.TrimSuffix(search, ".")
allErrs = append(allErrs, ValidateDNS1123Subdomain(search, fldPath.Child("searches").Index(i))...)
}
// Validate options.
@ -4060,7 +4041,7 @@ func ValidateAppArmorPodAnnotations(annotations map[string]string, spec *core.Po
allErrs = append(allErrs, field.Invalid(fldPath.Key(k), containerName, "container not found"))
}
if err := apparmor.ValidateProfileFormat(p); err != nil {
if err := ValidateAppArmorProfileFormat(p); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Key(k), p, err.Error()))
}
}
@ -4068,6 +4049,16 @@ func ValidateAppArmorPodAnnotations(annotations map[string]string, spec *core.Po
return allErrs
}
func ValidateAppArmorProfileFormat(profile string) error {
if profile == "" || profile == v1.AppArmorBetaProfileRuntimeDefault || profile == v1.AppArmorBetaProfileNameUnconfined {
return nil
}
if !strings.HasPrefix(profile, v1.AppArmorBetaProfileNamePrefix) {
return fmt.Errorf("invalid AppArmor profile name: %q", profile)
}
return nil
}
func podSpecHasContainer(spec *core.PodSpec, containerName string) bool {
var hasContainer bool
podshelper.VisitContainersWithPath(spec, field.NewPath("spec"), func(c *core.Container, _ *field.Path) bool {
@ -4372,7 +4363,7 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel
if !apiequality.Semantic.DeepEqual(mungedPodSpec, oldPod.Spec) {
// This diff isn't perfect, but it's a helluva lot better an "I'm not going to tell you what the difference is".
//TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff
specDiff := diff.ObjectDiff(mungedPodSpec, oldPod.Spec)
specDiff := cmp.Diff(oldPod.Spec, mungedPodSpec)
allErrs = append(allErrs, field.Forbidden(specPath, fmt.Sprintf("pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds`, `spec.tolerations` (only additions to existing tolerations) or `spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)\n%v", specDiff)))
}
@ -4473,7 +4464,7 @@ func ValidatePodEphemeralContainersUpdate(newPod, oldPod *core.Pod, opts PodVali
if new, ok := newContainerIndex[old.Name]; !ok {
allErrs = append(allErrs, field.Forbidden(specPath, fmt.Sprintf("existing ephemeral containers %q may not be removed\n", old.Name)))
} else if !apiequality.Semantic.DeepEqual(old, *new) {
specDiff := diff.ObjectDiff(old, *new)
specDiff := cmp.Diff(old, *new)
allErrs = append(allErrs, field.Forbidden(specPath, fmt.Sprintf("existing ephemeral containers %q may not be changed\n%v", old.Name, specDiff)))
}
}
@ -4685,10 +4676,8 @@ func ValidateService(service *core.Service) field.ErrorList {
allErrs = append(allErrs, field.Forbidden(specPath.Child("allocateLoadBalancerNodePorts"), "may only be used when `type` is 'LoadBalancer'"))
}
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceLBNodePortControl) {
if service.Spec.Type == core.ServiceTypeLoadBalancer && service.Spec.AllocateLoadBalancerNodePorts == nil {
allErrs = append(allErrs, field.Required(field.NewPath("allocateLoadBalancerNodePorts"), ""))
}
if service.Spec.Type == core.ServiceTypeLoadBalancer && service.Spec.AllocateLoadBalancerNodePorts == nil {
allErrs = append(allErrs, field.Required(field.NewPath("allocateLoadBalancerNodePorts"), ""))
}
// validate LoadBalancerClass field
@ -4811,7 +4800,12 @@ func validateServiceInternalTrafficFieldsValue(service *core.Service) field.Erro
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
if service.Spec.InternalTrafficPolicy == nil {
allErrs = append(allErrs, field.Required(field.NewPath("spec").Child("internalTrafficPolicy"), ""))
// We do not forbid internalTrafficPolicy on other Service types because of historical reasons.
// We did not check that before it went beta and we don't want to invalidate existing stored objects.
if service.Spec.Type == core.ServiceTypeNodePort ||
service.Spec.Type == core.ServiceTypeLoadBalancer || service.Spec.Type == core.ServiceTypeClusterIP {
allErrs = append(allErrs, field.Required(field.NewPath("spec").Child("internalTrafficPolicy"), ""))
}
}
}
@ -5564,13 +5558,13 @@ func ValidateSecret(secret *core.Secret) field.ErrorList {
// username or password might be empty, but the field must be present
if !usernameFieldExists && !passwordFieldExists {
allErrs = append(allErrs, field.Required(field.NewPath("data[%s]").Key(core.BasicAuthUsernameKey), ""))
allErrs = append(allErrs, field.Required(field.NewPath("data[%s]").Key(core.BasicAuthPasswordKey), ""))
allErrs = append(allErrs, field.Required(dataPath.Key(core.BasicAuthUsernameKey), ""))
allErrs = append(allErrs, field.Required(dataPath.Key(core.BasicAuthPasswordKey), ""))
break
}
case core.SecretTypeSSHAuth:
if len(secret.Data[core.SSHAuthPrivateKey]) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("data[%s]").Key(core.SSHAuthPrivateKey), ""))
allErrs = append(allErrs, field.Required(dataPath.Key(core.SSHAuthPrivateKey), ""))
break
}
@ -5754,7 +5748,7 @@ func validateResourceQuantityHugePageValue(name core.ResourceName, quantity reso
}
// validateResourceQuotaScopes ensures that each enumerated hard resource constraint is valid for set of scopes
func validateResourceQuotaScopes(resourceQuotaSpec *core.ResourceQuotaSpec, opts ResourceQuotaValidationOptions, fld *field.Path) field.ErrorList {
func validateResourceQuotaScopes(resourceQuotaSpec *core.ResourceQuotaSpec, fld *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(resourceQuotaSpec.Scopes) == 0 {
return allErrs
@ -5766,7 +5760,7 @@ func validateResourceQuotaScopes(resourceQuotaSpec *core.ResourceQuotaSpec, opts
fldPath := fld.Child("scopes")
scopeSet := sets.NewString()
for _, scope := range resourceQuotaSpec.Scopes {
if !helper.IsStandardResourceQuotaScope(string(scope), opts.AllowPodAffinityNamespaceSelector) {
if !helper.IsStandardResourceQuotaScope(string(scope)) {
allErrs = append(allErrs, field.Invalid(fldPath, resourceQuotaSpec.Scopes, "unsupported scope"))
}
for _, k := range hardLimits.List() {
@ -5789,7 +5783,7 @@ func validateResourceQuotaScopes(resourceQuotaSpec *core.ResourceQuotaSpec, opts
}
// validateScopedResourceSelectorRequirement tests that the match expressions has valid data
func validateScopedResourceSelectorRequirement(resourceQuotaSpec *core.ResourceQuotaSpec, opts ResourceQuotaValidationOptions, fld *field.Path) field.ErrorList {
func validateScopedResourceSelectorRequirement(resourceQuotaSpec *core.ResourceQuotaSpec, fld *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
hardLimits := sets.NewString()
for k := range resourceQuotaSpec.Hard {
@ -5798,7 +5792,7 @@ func validateScopedResourceSelectorRequirement(resourceQuotaSpec *core.ResourceQ
fldPath := fld.Child("matchExpressions")
scopeSet := sets.NewString()
for _, req := range resourceQuotaSpec.ScopeSelector.MatchExpressions {
if !helper.IsStandardResourceQuotaScope(string(req.ScopeName), opts.AllowPodAffinityNamespaceSelector) {
if !helper.IsStandardResourceQuotaScope(string(req.ScopeName)) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("scopeName"), req.ScopeName, "unsupported scope"))
}
for _, k := range hardLimits.List() {
@ -5844,26 +5838,20 @@ func validateScopedResourceSelectorRequirement(resourceQuotaSpec *core.ResourceQ
}
// validateScopeSelector tests that the specified scope selector has valid data
func validateScopeSelector(resourceQuotaSpec *core.ResourceQuotaSpec, opts ResourceQuotaValidationOptions, fld *field.Path) field.ErrorList {
func validateScopeSelector(resourceQuotaSpec *core.ResourceQuotaSpec, fld *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if resourceQuotaSpec.ScopeSelector == nil {
return allErrs
}
allErrs = append(allErrs, validateScopedResourceSelectorRequirement(resourceQuotaSpec, opts, fld.Child("scopeSelector"))...)
allErrs = append(allErrs, validateScopedResourceSelectorRequirement(resourceQuotaSpec, fld.Child("scopeSelector"))...)
return allErrs
}
// ResourceQuotaValidationOptions contains the different settings for ResourceQuota validation
type ResourceQuotaValidationOptions struct {
// Allow pod-affinity namespace selector validation.
AllowPodAffinityNamespaceSelector bool
}
// ValidateResourceQuota tests if required fields in the ResourceQuota are set.
func ValidateResourceQuota(resourceQuota *core.ResourceQuota, opts ResourceQuotaValidationOptions) field.ErrorList {
func ValidateResourceQuota(resourceQuota *core.ResourceQuota) field.ErrorList {
allErrs := ValidateObjectMeta(&resourceQuota.ObjectMeta, true, ValidateResourceQuotaName, field.NewPath("metadata"))
allErrs = append(allErrs, ValidateResourceQuotaSpec(&resourceQuota.Spec, opts, field.NewPath("spec"))...)
allErrs = append(allErrs, ValidateResourceQuotaSpec(&resourceQuota.Spec, field.NewPath("spec"))...)
allErrs = append(allErrs, ValidateResourceQuotaStatus(&resourceQuota.Status, field.NewPath("status"))...)
return allErrs
@ -5888,7 +5876,7 @@ func ValidateResourceQuotaStatus(status *core.ResourceQuotaStatus, fld *field.Pa
return allErrs
}
func ValidateResourceQuotaSpec(resourceQuotaSpec *core.ResourceQuotaSpec, opts ResourceQuotaValidationOptions, fld *field.Path) field.ErrorList {
func ValidateResourceQuotaSpec(resourceQuotaSpec *core.ResourceQuotaSpec, fld *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
fldPath := fld.Child("hard")
@ -5898,8 +5886,8 @@ func ValidateResourceQuotaSpec(resourceQuotaSpec *core.ResourceQuotaSpec, opts R
allErrs = append(allErrs, ValidateResourceQuantityValue(string(k), v, resPath)...)
}
allErrs = append(allErrs, validateResourceQuotaScopes(resourceQuotaSpec, opts, fld)...)
allErrs = append(allErrs, validateScopeSelector(resourceQuotaSpec, opts, fld)...)
allErrs = append(allErrs, validateResourceQuotaScopes(resourceQuotaSpec, fld)...)
allErrs = append(allErrs, validateScopeSelector(resourceQuotaSpec, fld)...)
return allErrs
}
@ -5917,9 +5905,9 @@ func ValidateResourceQuantityValue(resource string, value resource.Quantity, fld
}
// ValidateResourceQuotaUpdate tests to see if the update is legal for an end user to make.
func ValidateResourceQuotaUpdate(newResourceQuota, oldResourceQuota *core.ResourceQuota, opts ResourceQuotaValidationOptions) field.ErrorList {
func ValidateResourceQuotaUpdate(newResourceQuota, oldResourceQuota *core.ResourceQuota) field.ErrorList {
allErrs := ValidateObjectMetaUpdate(&newResourceQuota.ObjectMeta, &oldResourceQuota.ObjectMeta, field.NewPath("metadata"))
allErrs = append(allErrs, ValidateResourceQuotaSpec(&newResourceQuota.Spec, opts, field.NewPath("spec"))...)
allErrs = append(allErrs, ValidateResourceQuotaSpec(&newResourceQuota.Spec, field.NewPath("spec"))...)
// ensure scopes cannot change, and that resources are still valid for scope
fldPath := field.NewPath("spec", "scopes")
@ -6377,7 +6365,7 @@ func validateWindowsHostProcessPod(podSpec *core.PodSpec, fieldPath *field.Path,
}
// At present Windows Pods which contain HostProcess containers must also set HostNetwork.
if hostNetwork != true {
if !hostNetwork {
errMsg := "hostNetwork must be true if pod contains any hostProcess containers"
allErrs = append(allErrs, field.Invalid(fieldPath.Child("hostNetwork"), hostNetwork, errMsg))
}
@ -6524,6 +6512,7 @@ func validateTopologySpreadConstraints(constraints []core.TopologySpreadConstrai
if err := ValidateSpreadConstraintNotRepeat(subFldPath.Child("{topologyKey, whenUnsatisfiable}"), constraint, constraints[i+1:]); err != nil {
allErrs = append(allErrs, err)
}
allErrs = append(allErrs, validateMinDomains(subFldPath.Child("minDomains"), constraint.MinDomains, constraint.WhenUnsatisfiable)...)
}
return allErrs
@ -6537,6 +6526,22 @@ func ValidateMaxSkew(fldPath *field.Path, maxSkew int32) *field.Error {
return nil
}
// validateMinDomains tests that the argument is a valid MinDomains.
func validateMinDomains(fldPath *field.Path, minDomains *int32, action core.UnsatisfiableConstraintAction) field.ErrorList {
if minDomains == nil {
return nil
}
var allErrs field.ErrorList
if *minDomains <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath, minDomains, isNotPositiveErrorMsg))
}
// When MinDomains is non-nil, whenUnsatisfiable must be DoNotSchedule.
if action != core.DoNotSchedule {
allErrs = append(allErrs, field.Invalid(fldPath, minDomains, fmt.Sprintf("can only use minDomains if whenUnsatisfiable=%s, not %s", string(core.DoNotSchedule), string(action))))
}
return allErrs
}
// ValidateTopologyKey tests that the argument is a valid TopologyKey.
func ValidateTopologyKey(fldPath *field.Path, topologyKey string) *field.Error {
if len(topologyKey) == 0 {

View File

@ -5629,6 +5629,11 @@ func (in *TopologySpreadConstraint) DeepCopyInto(out *TopologySpreadConstraint)
*out = new(v1.LabelSelector)
(*in).DeepCopyInto(*out)
}
if in.MinDomains != nil {
in, out := &in.MinDomains, &out.MinDomains
*out = new(int32)
**out = **in
}
return
}

View File

@ -1,32 +1,23 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- brendandburns
- derekwaynecarr
- caesarxuchao
- mikedanese
- liggitt
- pmorie
- sttts
- saad-ali
- janetkuo
- justinsb
- ncdc
- tallclair
- mwielgus
- soltysh
- piosz
- dims
- errordeveloper
- rootfs
- resouer
- therc
- pweil-
- lukaszo
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k
- derekwaynecarr
- caesarxuchao
- mikedanese
- liggitt
- sttts
- saad-ali
- janetkuo
- justinsb
- ncdc
- tallclair
- mwielgus
- soltysh
- dims
labels:
- sig/apps
- sig/apps

View File

@ -1,8 +1,8 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- sig-network-api-approvers
- sig-network-api-approvers
reviewers:
- sig-network-api-reviewers
- sig-network-api-reviewers
labels:
- sig/network
- sig/network

View File

@ -33,6 +33,11 @@ type NetworkPolicy struct {
// Specification of the desired behavior for this NetworkPolicy.
// +optional
Spec NetworkPolicySpec
// Status is the current state of the NetworkPolicy.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
Status NetworkPolicyStatus
}
// PolicyType describes the NetworkPolicy type
@ -195,6 +200,42 @@ type NetworkPolicyPeer struct {
IPBlock *IPBlock
}
// NetworkPolicyConditionType is the type for status conditions on
// a NetworkPolicy. This type should be used with the
// NetworkPolicyStatus.Conditions field.
type NetworkPolicyConditionType string
const (
// NetworkPolicyConditionStatusAccepted represents status of a Network Policy that could be properly parsed by
// the Network Policy provider and will be implemented in the cluster
NetworkPolicyConditionStatusAccepted NetworkPolicyConditionType = "Accepted"
// NetworkPolicyConditionStatusPartialFailure represents status of a Network Policy that could be partially
// parsed by the Network Policy provider and may not be completely implemented due to a lack of a feature or some
// other condition
NetworkPolicyConditionStatusPartialFailure NetworkPolicyConditionType = "PartialFailure"
// NetworkPolicyConditionStatusFailure represents status of a Network Policy that could not be parsed by the
// Network Policy provider and will not be implemented in the cluster
NetworkPolicyConditionStatusFailure NetworkPolicyConditionType = "Failure"
)
// NetworkPolicyConditionReason defines the set of reasons that explain why a
// particular NetworkPolicy condition type has been raised.
type NetworkPolicyConditionReason string
const (
// NetworkPolicyConditionReasonFeatureNotSupported represents a reason where the Network Policy may not have been
// implemented in the cluster due to a lack of some feature not supported by the Network Policy provider
NetworkPolicyConditionReasonFeatureNotSupported NetworkPolicyConditionReason = "FeatureNotSupported"
)
// NetworkPolicyStatus describe the current state of the NetworkPolicy.
type NetworkPolicyStatus struct {
// Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy.
Conditions []metav1.Condition
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NetworkPolicyList is a list of NetworkPolicy objects.

View File

@ -432,6 +432,7 @@ func (in *NetworkPolicy) DeepCopyInto(out *NetworkPolicy) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@ -644,6 +645,29 @@ func (in *NetworkPolicySpec) DeepCopy() *NetworkPolicySpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NetworkPolicyStatus) DeepCopyInto(out *NetworkPolicyStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]v1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyStatus.
func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus {
if in == nil {
return nil
}
out := new(NetworkPolicyStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceBackendPort) DeepCopyInto(out *ServiceBackendPort) {
*out = *in

View File

@ -2,10 +2,10 @@
# approval on api packages bubbles to api-approvers
reviewers:
- sig-apps-api-reviewers
- sig-apps-api-approvers
- sig-auth-policy-approvers
- sig-auth-policy-reviewers
- sig-apps-api-reviewers
- sig-apps-api-approvers
- sig-auth-policy-approvers
- sig-auth-policy-reviewers
labels:
- sig/auth
- sig/auth
- sig/apps

View File

@ -1,20 +0,0 @@
/*
Copyright 2017 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.
*/
// +k8s:deepcopy-gen=package
// +groupName=scheduling.k8s.io
package scheduling // import "k8s.io/kubernetes/pkg/apis/scheduling"

View File

@ -1,53 +0,0 @@
/*
Copyright 2017 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 scheduling
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "scheduling.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
// SchemeBuilder points to a list of functions added to Scheme.
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
// AddToScheme applies all the stored functions to the scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&PriorityClass{},
&PriorityClassList{},
)
return nil
}

View File

@ -1,89 +0,0 @@
/*
Copyright 2017 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 scheduling
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/core"
)
const (
// DefaultPriorityWhenNoDefaultClassExists is used to set priority of pods
// that do not specify any priority class and there is no priority class
// marked as default.
DefaultPriorityWhenNoDefaultClassExists = 0
// HighestUserDefinablePriority is the highest priority for user defined priority classes. Priority values larger than 1 billion are reserved for Kubernetes system use.
HighestUserDefinablePriority = int32(1000000000)
// SystemCriticalPriority is the beginning of the range of priority values for critical system components.
SystemCriticalPriority = 2 * HighestUserDefinablePriority
// SystemPriorityClassPrefix is the prefix reserved for system priority class names. Other priority
// classes are not allowed to start with this prefix.
// NOTE: In order to avoid conflict of names with user-defined priority classes, all the names must
// start with SystemPriorityClassPrefix.
SystemPriorityClassPrefix = "system-"
// SystemClusterCritical is the system priority class name that represents cluster-critical.
SystemClusterCritical = SystemPriorityClassPrefix + "cluster-critical"
// SystemNodeCritical is the system priority class name that represents node-critical.
SystemNodeCritical = SystemPriorityClassPrefix + "node-critical"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PriorityClass defines the mapping from a priority class name to the priority
// integer value. The value can be any valid integer.
type PriorityClass struct {
metav1.TypeMeta
// Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta
// The value of this priority class. This is the actual priority that pods
// receive when they have the name of this class in their pod spec.
Value int32
// globalDefault specifies whether this PriorityClass should be considered as
// the default priority for pods that do not have any priority class.
// Only one PriorityClass can be marked as `globalDefault`. However, if more than
// one PriorityClasses exists with their `globalDefault` field set to true,
// the smallest value of such global default PriorityClasses will be used as the default priority.
// +optional
GlobalDefault bool
// Description is an arbitrary string that usually provides guidelines on
// when this priority class should be used.
// +optional
Description string
// PreemptionPolicy it the Policy for preempting pods with lower priority.
// This field is beta-level.
// +optional
PreemptionPolicy *core.PreemptionPolicy
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PriorityClassList is a collection of priority classes.
type PriorityClassList struct {
metav1.TypeMeta
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta
// Items is the list of PriorityClasses.
Items []PriorityClass
}

View File

@ -1,91 +0,0 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
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 deepcopy-gen. DO NOT EDIT.
package scheduling
import (
runtime "k8s.io/apimachinery/pkg/runtime"
core "k8s.io/kubernetes/pkg/apis/core"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PriorityClass) DeepCopyInto(out *PriorityClass) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
if in.PreemptionPolicy != nil {
in, out := &in.PreemptionPolicy, &out.PreemptionPolicy
*out = new(core.PreemptionPolicy)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityClass.
func (in *PriorityClass) DeepCopy() *PriorityClass {
if in == nil {
return nil
}
out := new(PriorityClass)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PriorityClass) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PriorityClassList) DeepCopyInto(out *PriorityClassList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]PriorityClass, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityClassList.
func (in *PriorityClassList) DeepCopy() *PriorityClassList {
if in == nil {
return nil
}
out := new(PriorityClassList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PriorityClassList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@ -1,16 +1,17 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- deads2k
- derekwaynecarr
- mikedanese
- janetkuo
- cheftako
- sig-apps-approvers
- deads2k
- derekwaynecarr
- mikedanese
- janetkuo
- cheftako
- andrewsykim
- sig-apps-approvers
reviewers:
- andrewsykim
- deads2k
- cheftako
- sig-apps-reviewers
- andrewsykim
- deads2k
- cheftako
- sig-apps-reviewers
labels:
- sig/apps
- sig/apps

View File

@ -504,10 +504,10 @@ func validateControllerRef(controllerRef *metav1.OwnerReference) error {
if len(controllerRef.Kind) == 0 {
return fmt.Errorf("controllerRef has empty Kind")
}
if controllerRef.Controller == nil || *controllerRef.Controller != true {
if controllerRef.Controller == nil || !*controllerRef.Controller {
return fmt.Errorf("controllerRef.Controller is not set to true")
}
if controllerRef.BlockOwnerDeletion == nil || *controllerRef.BlockOwnerDeletion != true {
if controllerRef.BlockOwnerDeletion == nil || !*controllerRef.BlockOwnerDeletion {
return fmt.Errorf("controllerRef.BlockOwnerDeletion is not set")
}
return nil

View File

@ -900,7 +900,8 @@ func GetDeploymentsForReplicaSet(deploymentLister appslisters.DeploymentLister,
for _, d := range dList {
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
// This object has an invalid selector, it does not match the replicaset
continue
}
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {

View File

@ -1,4 +1,4 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- feature-approvers
- feature-approvers

View File

@ -78,17 +78,20 @@ const (
// owner: @gnufied
// beta: v1.11
// GA: 1.24
// Ability to Expand persistent volumes
ExpandPersistentVolumes featuregate.Feature = "ExpandPersistentVolumes"
// owner: @mlmhl
// owner: @mlmhl @gnufied
// beta: v1.15
// GA: 1.24
// Ability to expand persistent volumes' file system without unmounting volumes.
ExpandInUsePersistentVolumes featuregate.Feature = "ExpandInUsePersistentVolumes"
// owner: @gnufied
// alpha: v1.14
// beta: v1.16
// GA: 1.24
// Ability to expand CSI volumes
ExpandCSIVolumes featuregate.Feature = "ExpandCSIVolumes"
@ -157,12 +160,15 @@ const (
// owner: @pohly
// alpha: v1.19
// beta: v1.21
// GA: v1.24
//
// Enables tracking of available storage capacity that CSI drivers provide.
CSIStorageCapacity featuregate.Feature = "CSIStorageCapacity"
// owner: @alculquicondor
// alpha: v1.19
// beta: v1.20
// GA: v1.24
//
// Enables the use of PodTopologySpread scheduling plugin to do default
// spreading and disables legacy SelectorSpread plugin.
@ -179,6 +185,7 @@ const (
// owner: @chendave
// alpha: v1.21
// beta: v1.22
// GA: v1.24
//
// PreferNominatedNode tells scheduler whether the nominated node will be checked first before looping
// all the rest of nodes in the cluster.
@ -187,14 +194,6 @@ const (
// and hence is the best candidate instead.
PreferNominatedNode featuregate.Feature = "PreferNominatedNode"
// owner: @tallclair
// alpha: v1.12
// beta: v1.14
// GA: v1.20
//
// Enables RuntimeClass, for selecting between multiple runtimes to run a pod.
RuntimeClass featuregate.Feature = "RuntimeClass"
// owner: @rikatz
// kep: http://kep.k8s.io/2079
// alpha: v1.21
@ -219,6 +218,7 @@ const (
// owner: @alculquicondor
// alpha: v1.21
// beta: v1.22
// stable: v1.24
//
// Allows Job controller to manage Pod completions per completion index.
IndexedJob featuregate.Feature = "IndexedJob"
@ -235,6 +235,7 @@ const (
// owner: @alculquicondor
// alpha: v1.23
// beta: v1.24
//
// Track the number of pods with Ready condition in the Job status.
JobReadyPods featuregate.Feature = "JobReadyPods"
@ -282,6 +283,7 @@ const (
// owner: @andyzhangx
// alpha: v1.15
// beta: v1.19
// GA: v1.24
//
// Enables the Azure Disk in-tree driver to Azure Disk Driver migration feature.
CSIMigrationAzureDisk featuregate.Feature = "CSIMigrationAzureDisk"
@ -306,7 +308,7 @@ const (
InTreePluginAzureFileUnregister featuregate.Feature = "InTreePluginAzureFileUnregister"
// owner: @divyenpatel
// beta: v1.19 (requires: vSphere vCenter/ESXi Version: 7.0u1, HW Version: VM version 15)
// beta: v1.19 (requires: vSphere vCenter/ESXi Version: 7.0u2, HW Version: VM version 15)
//
// Enables the vSphere in-tree driver to vSphere CSI Driver migration feature.
CSIMigrationvSphere featuregate.Feature = "CSIMigrationvSphere"
@ -346,7 +348,7 @@ const (
// alpha: v1.23
//
// Enables the RBD in-tree driver to RBD CSI Driver migration feature.
CSIMigrationRBD featuregate.Feature = "csiMigrationRBD"
CSIMigrationRBD featuregate.Feature = "CSIMigrationRBD"
// owner: @humblec
// alpha: v1.23
@ -388,6 +390,7 @@ const (
// owner: @denkensk
// alpha: v1.15
// beta: v1.19
// ga: v1.24
//
// Enables NonPreempting option for priorityClass and pod.
NonPreemptingPriority featuregate.Feature = "NonPreemptingPriority"
@ -395,6 +398,7 @@ const (
// owner: @egernst
// alpha: v1.16
// beta: v1.18
// ga: v1.24
//
// Enables PodOverhead, for accounting pod overheads which are specific to a given RuntimeClass
PodOverhead featuregate.Feature = "PodOverhead"
@ -403,6 +407,7 @@ const (
// kep: http://kep.k8s.io/563
// alpha: v1.15
// beta: v1.21
// ga: v1.23
//
// Enables ipv6 dual stack
IPv6DualStack featuregate.Feature = "IPv6DualStack"
@ -447,24 +452,6 @@ const (
// DaemonSets allow workloads to maintain availability during update per node
DaemonSetUpdateSurge featuregate.Feature = "DaemonSetUpdateSurge"
// owner: @wojtek-t
// alpha: v1.18
// beta: v1.19
// ga: v1.21
//
// Enables a feature to make secrets and configmaps data immutable.
ImmutableEphemeralVolumes featuregate.Feature = "ImmutableEphemeralVolumes"
// owner: @bart0sh
// alpha: v1.18
// beta: v1.19
// GA: 1.22
//
// Enables usage of HugePages-<size> in a volume medium,
// e.g. emptyDir:
// medium: HugePages-1Gi
HugePageStorageMediumSize featuregate.Feature = "HugePageStorageMediumSize"
// owner: @derekwaynecarr
// alpha: v1.20
// beta: v1.21 (off by default until 1.22)
@ -474,20 +461,11 @@ const (
// owner: @bswartz
// alpha: v1.18
// beta: v1.24
//
// Enables usage of any object for volume data source in PVCs
AnyVolumeDataSource featuregate.Feature = "AnyVolumeDataSource"
// owner: @javidiaz
// kep: http://kep.k8s.io/1797
// alpha: v1.19
// beta: v1.20
// GA: v1.22
//
// Allow setting the Fully Qualified Domain Name (FQDN) in the hostname of a Pod. If a Pod does not
// have FQDN, this feature has no effect.
SetHostnameAsFQDN featuregate.Feature = "SetHostnameAsFQDN"
// owner: @ksubrmnn
// alpha: v1.14
// beta: v1.20
@ -552,8 +530,9 @@ const (
// Lock to default and remove after v1.22 based on user feedback that should be reflected in KEP #1972 update
ExecProbeTimeout featuregate.Feature = "ExecProbeTimeout"
// owner: @andrewsykim
// owner: @andrewsykim @adisky
// alpha: v1.20
// beta: v1.24
//
// Enable kubelet exec plugins for image pull credentials.
KubeletCredentialProviders featuregate.Feature = "KubeletCredentialProviders"
@ -587,7 +566,7 @@ const (
// owner: @wzshiming
// alpha: v1.23
//
// beta: v1.24
// Make the kubelet use shutdown configuration based on pod priority values for graceful shutdown.
GracefulNodeShutdownBasedOnPodPriority featuregate.Feature = "GracefulNodeShutdownBasedOnPodPriority"
@ -595,13 +574,15 @@ const (
// kep: http://kep.k8s.io/1864
// alpha: v1.20
// beta: v1.22
// ga: v1.24
//
// Allows control if NodePorts shall be created for services with "type: LoadBalancer" by defining the spec.AllocateLoadBalancerNodePorts field (bool)
ServiceLBNodePortControl featuregate.Feature = "ServiceLBNodePortControl"
// owner: @janosi
// owner: @janosi @bridgetkromhout
// kep: http://kep.k8s.io/1435
// alpha: v1.20
// beta: v1.24
//
// Enables the usage of different protocols in the same Service with type=LoadBalancer
MixedProtocolLBService featuregate.Feature = "MixedProtocolLBService"
@ -646,6 +627,7 @@ const (
// owner: @ahg-g
// alpha: v1.21
// beta: v1.22
// GA: v1.24
//
// Allow specifying NamespaceSelector in PodAffinityTerm.
PodAffinityNamespaceSelector featuregate.Feature = "PodAffinityNamespaceSelector"
@ -654,6 +636,7 @@ const (
// kep: http://kep.k8s.io/1959
// alpha: v1.21
// beta: v1.22
// GA: v1.24
//
// Enable support multiple Service "type: LoadBalancer" implementations in a cluster by specifying LoadBalancerClass
ServiceLoadBalancerClass featuregate.Feature = "ServiceLoadBalancerClass"
@ -685,6 +668,7 @@ const (
// owner: @adtac
// alpha: v1.21
// beta: v1.22
// GA: v1.24
//
// Allows jobs to be created in the suspended state.
SuspendJob featuregate.Feature = "SuspendJob"
@ -695,14 +679,6 @@ const (
// Enable POD resources API to return allocatable resources
KubeletPodResourcesGetAllocatable featuregate.Feature = "KubeletPodResourcesGetAllocatable"
// owner: @jayunit100 @abhiraut @rikatz
// kep: http://kep.k8s.io/2161
// beta: v1.21
// ga: v1.22
//
// Labels all namespaces with a default label "kubernetes.io/metadata.name: <namespaceName>"
NamespaceDefaultLabelName featuregate.Feature = "NamespaceDefaultLabelName"
// owner: @fengzixu
// alpha: v1.21
//
@ -725,7 +701,7 @@ const (
// owner: @ravig
// alpha: v1.23
//
// beta: v1.24
// IdentifyPodOS allows user to specify OS on which they'd like the Pod run. The user should still set the nodeSelector
// with appropriate `kubernetes.io/os` label for scheduler to identify appropriate node for the pod to run.
IdentifyPodOS featuregate.Feature = "IdentifyPodOS"
@ -758,6 +734,7 @@ const (
// owner: @enj
// beta: v1.22
// ga: v1.24
//
// Allows clients to request a duration for certificates issued via the Kubernetes CSR API.
CSRDuration featuregate.Feature = "CSRDuration"
@ -787,6 +764,7 @@ const (
// owner: @jiahuif
// alpha: v1.21
// beta: v1.22
// GA: v1.24
//
// Enables Leader Migration for kube-controller-manager and cloud-controller-manager
ControllerManagerLeaderMigration featuregate.Feature = "ControllerManagerLeaderMigration"
@ -849,12 +827,61 @@ const (
// Allow users to recover from volume expansion failure
RecoverVolumeExpansionFailure featuregate.Feature = "RecoverVolumeExpansionFailure"
// owner: @yuzhiquan, @bowei, @PxyUp
// owner: @yuzhiquan, @bowei, @PxyUp, @SergeyKanzhelev
// kep: http://kep.k8s.io/2727
// alpha: v1.23
// beta: v1.24
//
// Enables GRPC probe method for {Liveness,Readiness,Startup}Probe.
GRPCContainerProbe featuregate.Feature = "GRPCContainerProbe"
// owner: @zshihang
// kep: http://kep.k8s.io/2800
// beta: v1.24
//
// Stop auto-generation of secret-based service account tokens.
LegacyServiceAccountTokenNoAutoGeneration featuregate.Feature = "LegacyServiceAccountTokenNoAutoGeneration"
// owner: @sanposhiho
// kep: http://kep.k8s.io/3022
// alpha: v1.24
//
// Enable MinDomains in Pod Topology Spread.
MinDomainsInPodTopologySpread featuregate.Feature = "MinDomainsInPodTopologySpread"
// owner: @aojea
// kep: http://kep.k8s.io/3070
// alpha: v1.24
//
// Subdivide the ClusterIP range for dynamic and static IP allocation.
ServiceIPStaticSubrange featuregate.Feature = "ServiceIPStaticSubrange"
// owner: @xing-yang @sonasingh46
// kep: http://kep.k8s.io/2268
// alpha: v1.24
//
// Allow pods to failover to a different node in case of non graceful node shutdown
NodeOutOfServiceVolumeDetach featuregate.Feature = "NodeOutOfServiceVolumeDetach"
// owner: @krmayankk
// alpha: v1.24
//
// Enables maxUnavailable for StatefulSet
MaxUnavailableStatefulSet featuregate.Feature = "MaxUnavailableStatefulSet"
// owner: @rikatz
// kep: http://kep.k8s.io/2943
// alpha: v1.24
//
// Enables NetworkPolicy status subresource
NetworkPolicyStatus featuregate.Feature = "NetworkPolicyStatus"
// owner: @deejross
// kep: http://kep.k8s.io/3140
// alpha: v1.24
//
// Enables support for time zones in CronJobs.
CronJobTimeZone featuregate.Feature = "CronJobTimeZone"
)
func init() {
@ -866,16 +893,16 @@ func init() {
// available throughout Kubernetes binaries.
var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
AppArmor: {Default: true, PreRelease: featuregate.Beta},
DynamicKubeletConfig: {Default: false, PreRelease: featuregate.Deprecated}, // feature gate is deprecated in 1.22, remove no early than 1.23
DynamicKubeletConfig: {Default: false, PreRelease: featuregate.Deprecated}, // feature gate is deprecated in 1.22, kubelet logic is removed in 1.24, api server logic can be removed in 1.26
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: featuregate.Beta},
DevicePlugins: {Default: true, PreRelease: featuregate.Beta},
RotateKubeletServerCertificate: {Default: true, PreRelease: featuregate.Beta},
LocalStorageCapacityIsolation: {Default: true, PreRelease: featuregate.Beta},
EphemeralContainers: {Default: true, PreRelease: featuregate.Beta},
QOSReserved: {Default: false, PreRelease: featuregate.Alpha},
ExpandPersistentVolumes: {Default: true, PreRelease: featuregate.Beta},
ExpandInUsePersistentVolumes: {Default: true, PreRelease: featuregate.Beta},
ExpandCSIVolumes: {Default: true, PreRelease: featuregate.Beta},
ExpandPersistentVolumes: {Default: true, PreRelease: featuregate.GA}, // remove in 1.25
ExpandInUsePersistentVolumes: {Default: true, PreRelease: featuregate.GA}, // remove in 1.25
ExpandCSIVolumes: {Default: true, PreRelease: featuregate.GA}, // remove in 1.25
CPUManager: {Default: true, PreRelease: featuregate.Beta},
MemoryManager: {Default: true, PreRelease: featuregate.Beta},
CPUCFSQuotaPeriod: {Default: false, PreRelease: featuregate.Alpha},
@ -886,13 +913,13 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
InTreePluginGCEUnregister: {Default: false, PreRelease: featuregate.Alpha},
CSIMigrationAWS: {Default: true, PreRelease: featuregate.Beta},
InTreePluginAWSUnregister: {Default: false, PreRelease: featuregate.Alpha},
CSIMigrationAzureDisk: {Default: true, PreRelease: featuregate.Beta}, // On by default in 1.23 (requires Azure Disk CSI driver)
CSIMigrationAzureDisk: {Default: true, PreRelease: featuregate.GA}, // On by default in 1.23 (requires Azure Disk CSI driver)
InTreePluginAzureDiskUnregister: {Default: false, PreRelease: featuregate.Alpha},
CSIMigrationAzureFile: {Default: false, PreRelease: featuregate.Beta}, // Off by default (requires Azure File CSI driver)
CSIMigrationAzureFile: {Default: true, PreRelease: featuregate.Beta}, // On by default in 1.24 (requires Azure File CSI driver)
InTreePluginAzureFileUnregister: {Default: false, PreRelease: featuregate.Alpha},
CSIMigrationvSphere: {Default: false, PreRelease: featuregate.Beta}, // Off by default (requires vSphere CSI driver)
InTreePluginvSphereUnregister: {Default: false, PreRelease: featuregate.Alpha},
CSIMigrationOpenStack: {Default: true, PreRelease: featuregate.Beta},
CSIMigrationOpenStack: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
InTreePluginOpenStackUnregister: {Default: false, PreRelease: featuregate.Alpha},
CSIMigrationRBD: {Default: false, PreRelease: featuregate.Alpha}, // Off by default (requires RBD CSI driver)
InTreePluginRBDUnregister: {Default: false, PreRelease: featuregate.Alpha},
@ -900,22 +927,21 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
CSIMigrationPortworx: {Default: false, PreRelease: featuregate.Alpha}, // Off by default (requires Portworx CSI driver)
InTreePluginPortworxUnregister: {Default: false, PreRelease: featuregate.Alpha},
CSIInlineVolume: {Default: true, PreRelease: featuregate.Beta},
CSIStorageCapacity: {Default: true, PreRelease: featuregate.Beta},
CSIStorageCapacity: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
CSIServiceAccountToken: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
GenericEphemeralVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
CSIVolumeFSGroupPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
VolumeSubpath: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
RuntimeClass: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
NetworkPolicyEndPort: {Default: true, PreRelease: featuregate.Beta},
ProcMountType: {Default: false, PreRelease: featuregate.Alpha},
TTLAfterFinished: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
IndexedJob: {Default: true, PreRelease: featuregate.Beta},
JobTrackingWithFinalizers: {Default: true, PreRelease: featuregate.Beta},
JobReadyPods: {Default: false, PreRelease: featuregate.Alpha},
IndexedJob: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
JobTrackingWithFinalizers: {Default: false, PreRelease: featuregate.Beta}, // Disabled due to #109485
JobReadyPods: {Default: true, PreRelease: featuregate.Beta},
KubeletPodResources: {Default: true, PreRelease: featuregate.Beta},
LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha},
NonPreemptingPriority: {Default: true, PreRelease: featuregate.Beta},
PodOverhead: {Default: true, PreRelease: featuregate.Beta},
NonPreemptingPriority: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
PodOverhead: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
IPv6DualStack: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
EndpointSlice: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
EndpointSliceProxying: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
@ -925,38 +951,34 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
WindowsEndpointSliceProxying: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
PodDisruptionBudget: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
DaemonSetUpdateSurge: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.22
ImmutableEphemeralVolumes: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
HugePageStorageMediumSize: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
DownwardAPIHugePages: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.22
AnyVolumeDataSource: {Default: false, PreRelease: featuregate.Alpha},
DefaultPodTopologySpread: {Default: true, PreRelease: featuregate.Beta},
SetHostnameAsFQDN: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
AnyVolumeDataSource: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.24
DefaultPodTopologySpread: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
WinOverlay: {Default: true, PreRelease: featuregate.Beta},
WinDSR: {Default: false, PreRelease: featuregate.Alpha},
DisableAcceleratorUsageMetrics: {Default: true, PreRelease: featuregate.Beta},
HPAContainerMetrics: {Default: false, PreRelease: featuregate.Alpha},
SizeMemoryBackedVolumes: {Default: true, PreRelease: featuregate.Beta},
ExecProbeTimeout: {Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update
KubeletCredentialProviders: {Default: false, PreRelease: featuregate.Alpha},
KubeletCredentialProviders: {Default: true, PreRelease: featuregate.Beta},
GracefulNodeShutdown: {Default: true, PreRelease: featuregate.Beta},
GracefulNodeShutdownBasedOnPodPriority: {Default: false, PreRelease: featuregate.Alpha},
ServiceLBNodePortControl: {Default: true, PreRelease: featuregate.Beta},
MixedProtocolLBService: {Default: false, PreRelease: featuregate.Alpha},
GracefulNodeShutdownBasedOnPodPriority: {Default: true, PreRelease: featuregate.Beta},
ServiceLBNodePortControl: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
MixedProtocolLBService: {Default: true, PreRelease: featuregate.Beta},
VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha},
PreferNominatedNode: {Default: true, PreRelease: featuregate.Beta},
ProbeTerminationGracePeriod: {Default: false, PreRelease: featuregate.Beta}, // Default to false in beta 1.22, set to true in 1.24
PreferNominatedNode: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
ProbeTerminationGracePeriod: {Default: false, PreRelease: featuregate.Beta}, // Default to false in beta 1.22, set to true in 1.24
NodeSwap: {Default: false, PreRelease: featuregate.Alpha},
PodDeletionCost: {Default: true, PreRelease: featuregate.Beta},
StatefulSetAutoDeletePVC: {Default: false, PreRelease: featuregate.Alpha},
TopologyAwareHints: {Default: false, PreRelease: featuregate.Beta},
PodAffinityNamespaceSelector: {Default: true, PreRelease: featuregate.Beta},
ServiceLoadBalancerClass: {Default: true, PreRelease: featuregate.Beta},
IngressClassNamespacedParams: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
TopologyAwareHints: {Default: true, PreRelease: featuregate.Beta},
PodAffinityNamespaceSelector: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
ServiceLoadBalancerClass: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
IngressClassNamespacedParams: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25
ServiceInternalTrafficPolicy: {Default: true, PreRelease: featuregate.Beta},
LogarithmicScaleDown: {Default: true, PreRelease: featuregate.Beta},
SuspendJob: {Default: true, PreRelease: featuregate.Beta},
SuspendJob: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
KubeletPodResourcesGetAllocatable: {Default: true, PreRelease: featuregate.Beta},
NamespaceDefaultLabelName: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
CSIVolumeHealth: {Default: false, PreRelease: featuregate.Alpha},
WindowsHostProcessContainers: {Default: true, PreRelease: featuregate.Beta},
DisableCloudProviders: {Default: false, PreRelease: featuregate.Alpha},
@ -966,35 +988,39 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
SeccompDefault: {Default: false, PreRelease: featuregate.Alpha},
PodSecurity: {Default: true, PreRelease: featuregate.Beta},
ReadWriteOncePod: {Default: false, PreRelease: featuregate.Alpha},
CSRDuration: {Default: true, PreRelease: featuregate.Beta},
CSRDuration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
DelegateFSGroupToCSIDriver: {Default: true, PreRelease: featuregate.Beta},
KubeletInUserNamespace: {Default: false, PreRelease: featuregate.Alpha},
MemoryQoS: {Default: false, PreRelease: featuregate.Alpha},
CPUManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta},
ControllerManagerLeaderMigration: {Default: true, PreRelease: featuregate.Beta},
ControllerManagerLeaderMigration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26
CPUManagerPolicyAlphaOptions: {Default: false, PreRelease: featuregate.Alpha},
CPUManagerPolicyBetaOptions: {Default: true, PreRelease: featuregate.Beta},
JobMutableNodeSchedulingDirectives: {Default: true, PreRelease: featuregate.Beta},
IdentifyPodOS: {Default: false, PreRelease: featuregate.Alpha},
IdentifyPodOS: {Default: true, PreRelease: featuregate.Beta},
PodAndContainerStatsFromCRI: {Default: false, PreRelease: featuregate.Alpha},
HonorPVReclaimPolicy: {Default: false, PreRelease: featuregate.Alpha},
RecoverVolumeExpansionFailure: {Default: false, PreRelease: featuregate.Alpha},
GRPCContainerProbe: {Default: false, PreRelease: featuregate.Alpha},
GRPCContainerProbe: {Default: true, PreRelease: featuregate.Beta},
LegacyServiceAccountTokenNoAutoGeneration: {Default: true, PreRelease: featuregate.Beta},
MinDomainsInPodTopologySpread: {Default: false, PreRelease: featuregate.Alpha},
ServiceIPStaticSubrange: {Default: false, PreRelease: featuregate.Alpha},
NodeOutOfServiceVolumeDetach: {Default: false, PreRelease: featuregate.Alpha},
MaxUnavailableStatefulSet: {Default: false, PreRelease: featuregate.Alpha},
NetworkPolicyStatus: {Default: false, PreRelease: featuregate.Alpha},
CronJobTimeZone: {Default: false, PreRelease: featuregate.Alpha},
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side:
genericfeatures.StreamingProxyRedirects: {Default: false, PreRelease: featuregate.Deprecated}, // remove in 1.24
genericfeatures.ValidateProxyRedirects: {Default: true, PreRelease: featuregate.Deprecated},
genericfeatures.AdvancedAuditing: {Default: true, PreRelease: featuregate.GA},
genericfeatures.APIResponseCompression: {Default: true, PreRelease: featuregate.Beta},
genericfeatures.APIListChunking: {Default: true, PreRelease: featuregate.Beta},
genericfeatures.DryRun: {Default: true, PreRelease: featuregate.GA},
genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.GA},
genericfeatures.APIPriorityAndFairness: {Default: true, PreRelease: featuregate.Beta},
genericfeatures.WarningHeaders: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
genericfeatures.OpenAPIEnums: {Default: false, PreRelease: featuregate.Alpha},
genericfeatures.OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
genericfeatures.CustomResourceValidationExpressions: {Default: false, PreRelease: featuregate.Alpha},
genericfeatures.OpenAPIV3: {Default: false, PreRelease: featuregate.Alpha},
genericfeatures.OpenAPIV3: {Default: true, PreRelease: featuregate.Beta},
genericfeatures.ServerSideFieldValidation: {Default: false, PreRelease: featuregate.Alpha},
// features that enable backwards compatibility but are scheduled to be removed
// ...

View File

@ -4,6 +4,6 @@
options:
no_parent_owners: true
approvers:
- api-approvers
- api-approvers
reviewers:
- sig-node-api-reviewers
- sig-node-api-reviewers

View File

@ -98,7 +98,7 @@ type KubeletConfiguration struct {
// staticPodURL is the URL for accessing static pods to run
StaticPodURL string
// staticPodURLHeader is a map of slices with HTTP headers to use when accessing the podURL
StaticPodURLHeader map[string][]string
StaticPodURLHeader map[string][]string `datapolicy:"token"`
// address is the IP address for the Kubelet to serve on (set to 0.0.0.0
// for all interfaces)
Address string
@ -340,9 +340,10 @@ type KubeletConfiguration struct {
ContainerLogMaxFiles int32
// ConfigMapAndSecretChangeDetectionStrategy is a mode in which config map and secret managers are running.
ConfigMapAndSecretChangeDetectionStrategy ResourceChangeDetectionStrategy
// A comma separated allowlist of unsafe sysctls or sysctl patterns (ending in *).
// Unsafe sysctl groups are kernel.shm*, kernel.msg*, kernel.sem, fs.mqueue.*, and net.*.
// These sysctls are namespaced but not allowed by default. For example: "kernel.msg*,net.ipv4.route.min_pmtu"
// A comma separated allowlist of unsafe sysctls or sysctl patterns (ending in `*`).
// Unsafe sysctl groups are `kernel.shm*`, `kernel.msg*`, `kernel.sem`, `fs.mqueue.*`, and `net.*`.
// These sysctls are namespaced but not allowed by default.
// For example: "`kernel.msg*,net.ipv4.route.min_pmtu`"
// +optional
AllowedUnsafeSysctls []string
// kernelMemcgNotification if enabled, the kubelet will integrate with the kernel memcg
@ -554,9 +555,9 @@ type CredentialProvider struct {
//
// Each entry in matchImages is a pattern which can optionally contain a port and a path.
// Globs can be used in the domain, but not in the port or the path. Globs are supported
// as subdomains like '*.k8s.io' or 'k8s.*.io', and top-level-domains such as 'k8s.*'.
// Matching partial subdomains like 'app*.k8s.io' is also supported. Each glob can only match
// a single subdomain segment, so *.io does not match *.k8s.io.
// as subdomains like `*.k8s.io` or `k8s.*.io`, and top-level-domains such as `k8s.*`.
// Matching partial subdomains like `app*.k8s.io` is also supported. Each glob can only match
// a single subdomain segment, so `*.io` does not match *.k8s.io.
//
// A match exists between an image and a matchImage when all of the below are true:
// - Both contain the same number of domain parts and each part matches.
@ -564,11 +565,11 @@ type CredentialProvider struct {
// - If the imageMatch contains a port, then the port must match in the image as well.
//
// Example values of matchImages:
// - 123456789.dkr.ecr.us-east-1.amazonaws.com
// - *.azurecr.io
// - gcr.io
// - *.*.registry.io
// - registry.io:8080/path
// - `123456789.dkr.ecr.us-east-1.amazonaws.com`
// - `*.azurecr.io`
// - `gcr.io`
// - `*.*.registry.io`
// - `registry.io:8080/path`
MatchImages []string
// defaultCacheDuration is the default duration the plugin will cache credentials in-memory
@ -578,6 +579,7 @@ type CredentialProvider struct {
// Required input version of the exec CredentialProviderRequest. The returned CredentialProviderResponse
// MUST use the same encoding version as the input. Current supported values are:
// - credentialprovider.kubelet.k8s.io/v1alpha1
// - credentialprovider.kubelet.k8s.io/v1beta1
APIVersion string
// Arguments to pass to the command when executing it.

View File

@ -0,0 +1,101 @@
/*
Copyright 2019 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 metrics
import (
"sync"
"time"
"k8s.io/component-base/metrics"
"k8s.io/component-base/metrics/legacyregistry"
)
const (
kubeletSubsystem = "kubelet"
)
var (
// HTTPRequests tracks the number of the http requests received since the server started.
HTTPRequests = metrics.NewCounterVec(
&metrics.CounterOpts{
Subsystem: kubeletSubsystem,
Name: "http_requests_total",
Help: "Number of the http requests received since the server started",
StabilityLevel: metrics.ALPHA,
},
// server_type aims to differentiate the readonly server and the readwrite server.
// long_running marks whether the request is long-running or not.
// Currently, long-running requests include exec/attach/portforward/debug.
[]string{"method", "path", "server_type", "long_running"},
)
// HTTPRequestsDuration tracks the duration in seconds to serve http requests.
HTTPRequestsDuration = metrics.NewHistogramVec(
&metrics.HistogramOpts{
Subsystem: kubeletSubsystem,
Name: "http_requests_duration_seconds",
Help: "Duration in seconds to serve http requests",
// Use DefBuckets for now, will customize the buckets if necessary.
Buckets: metrics.DefBuckets,
StabilityLevel: metrics.ALPHA,
},
[]string{"method", "path", "server_type", "long_running"},
)
// HTTPInflightRequests tracks the number of the inflight http requests.
HTTPInflightRequests = metrics.NewGaugeVec(
&metrics.GaugeOpts{
Subsystem: kubeletSubsystem,
Name: "http_inflight_requests",
Help: "Number of the inflight http requests",
StabilityLevel: metrics.ALPHA,
},
[]string{"method", "path", "server_type", "long_running"},
)
// VolumeStatCalDuration tracks the duration in seconds to calculate volume stats.
// this metric is mainly for comparison between fsquota monitoring and `du` for disk usage.
VolumeStatCalDuration = metrics.NewHistogramVec(
&metrics.HistogramOpts{
Subsystem: kubeletSubsystem,
Name: "volume_metric_collection_duration_seconds",
Help: "Duration in seconds to calculate volume stats",
Buckets: metrics.DefBuckets,
StabilityLevel: metrics.ALPHA,
},
[]string{"metric_source"},
)
)
var registerMetrics sync.Once
// Register all metrics.
func Register() {
registerMetrics.Do(func() {
legacyregistry.MustRegister(HTTPRequests)
legacyregistry.MustRegister(HTTPRequestsDuration)
legacyregistry.MustRegister(HTTPInflightRequests)
legacyregistry.MustRegister(VolumeStatCalDuration)
})
}
// SinceInSeconds gets the time since the specified start in seconds.
func SinceInSeconds(start time.Time) float64 {
return time.Since(start).Seconds()
}
// CollectVolumeStatCalDuration collects the duration in seconds to calculate volume stats.
func CollectVolumeStatCalDuration(metricSource string, start time.Time) {
VolumeStatCalDuration.WithLabelValues(metricSource).Observe(SinceInSeconds(start))
}

View File

@ -1,46 +0,0 @@
/*
Copyright 2015 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 types
const (
// ResolvConfDefault is the system default DNS resolver configuration.
ResolvConfDefault = "/etc/resolv.conf"
// RFC3339NanoFixed is the fixed width version of time.RFC3339Nano.
RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
// RFC3339NanoLenient is the variable width RFC3339 time format for lenient parsing of strings into timestamps.
RFC3339NanoLenient = "2006-01-02T15:04:05.999999999Z07:00"
)
// Different container runtimes.
const (
DockerContainerRuntime = "docker"
RemoteContainerRuntime = "remote"
)
// User visible keys for managing node allocatable enforcement on the node.
const (
NodeAllocatableEnforcementKey = "pods"
SystemReservedEnforcementKey = "system-reserved"
KubeReservedEnforcementKey = "kube-reserved"
NodeAllocatableNoneKey = "none"
)
// SwapBehavior types
const (
LimitedSwap = "LimitedSwap"
UnlimitedSwap = "UnlimitedSwap"
)

View File

@ -1,18 +0,0 @@
/*
Copyright 2015 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 types contains common types in the Kubelet.
package types // import "k8s.io/kubernetes/pkg/kubelet/types"

View File

@ -1,45 +0,0 @@
/*
Copyright 2016 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 types
// Label keys for labels used in this package.
const (
KubernetesPodNameLabel = "io.kubernetes.pod.name"
KubernetesPodNamespaceLabel = "io.kubernetes.pod.namespace"
KubernetesPodUIDLabel = "io.kubernetes.pod.uid"
KubernetesContainerNameLabel = "io.kubernetes.container.name"
)
// GetContainerName returns the value of the KubernetesContainerNameLabel.
func GetContainerName(labels map[string]string) string {
return labels[KubernetesContainerNameLabel]
}
// GetPodName returns the value of the KubernetesPodNameLabel.
func GetPodName(labels map[string]string) string {
return labels[KubernetesPodNameLabel]
}
// GetPodUID returns the value of the KubernetesPodUIDLabel.
func GetPodUID(labels map[string]string) string {
return labels[KubernetesPodUIDLabel]
}
// GetPodNamespace returns the value of the KubernetesPodNamespaceLabel.
func GetPodNamespace(labels map[string]string) string {
return labels[KubernetesPodNamespaceLabel]
}

View File

@ -1,39 +0,0 @@
/*
Copyright 2018 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 types
import (
v1 "k8s.io/api/core/v1"
)
// PodConditionsByKubelet is the list of pod conditions owned by kubelet
var PodConditionsByKubelet = []v1.PodConditionType{
v1.PodScheduled,
v1.PodReady,
v1.PodInitialized,
v1.ContainersReady,
}
// PodConditionByKubelet returns if the pod condition type is owned by kubelet
func PodConditionByKubelet(conditionType v1.PodConditionType) bool {
for _, c := range PodConditionsByKubelet {
if c == conditionType {
return true
}
}
return false
}

View File

@ -1,194 +0,0 @@
/*
Copyright 2014 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 types
import (
"fmt"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/scheduling"
)
// Annotation keys for annotations used in this package.
const (
ConfigSourceAnnotationKey = "kubernetes.io/config.source"
ConfigMirrorAnnotationKey = v1.MirrorPodAnnotationKey
ConfigFirstSeenAnnotationKey = "kubernetes.io/config.seen"
ConfigHashAnnotationKey = "kubernetes.io/config.hash"
)
// PodOperation defines what changes will be made on a pod configuration.
type PodOperation int
// These constants identify the PodOperations that can be made on a pod configuration.
const (
// SET is the current pod configuration.
SET PodOperation = iota
// ADD signifies pods that are new to this source.
ADD
// DELETE signifies pods that are gracefully deleted from this source.
DELETE
// REMOVE signifies pods that have been removed from this source.
REMOVE
// UPDATE signifies pods have been updated in this source.
UPDATE
// RECONCILE signifies pods that have unexpected status in this source,
// kubelet should reconcile status with this source.
RECONCILE
)
// These constants identify the sources of pods.
const (
// Filesource idenitified updates from a file.
FileSource = "file"
// HTTPSource identifies updates from querying a web page.
HTTPSource = "http"
// ApiserverSource identifies updates from Kubernetes API Server.
ApiserverSource = "api"
// AllSource identifies updates from all sources.
AllSource = "*"
)
// NamespaceDefault is a string representing the default namespace.
const NamespaceDefault = metav1.NamespaceDefault
// PodUpdate defines an operation sent on the channel. You can add or remove single services by
// sending an array of size one and Op == ADD|REMOVE (with REMOVE, only the ID is required).
// For setting the state of the system to a given state for this source configuration, set
// Pods as desired and Op to SET, which will reset the system state to that specified in this
// operation for this source channel. To remove all pods, set Pods to empty object and Op to SET.
//
// Additionally, Pods should never be nil - it should always point to an empty slice. While
// functionally similar, this helps our unit tests properly check that the correct PodUpdates
// are generated.
type PodUpdate struct {
Pods []*v1.Pod
Op PodOperation
Source string
}
// GetValidatedSources gets all validated sources from the specified sources.
func GetValidatedSources(sources []string) ([]string, error) {
validated := make([]string, 0, len(sources))
for _, source := range sources {
switch source {
case AllSource:
return []string{FileSource, HTTPSource, ApiserverSource}, nil
case FileSource, HTTPSource, ApiserverSource:
validated = append(validated, source)
case "":
// Skip
default:
return []string{}, fmt.Errorf("unknown pod source %q", source)
}
}
return validated, nil
}
// GetPodSource returns the source of the pod based on the annotation.
func GetPodSource(pod *v1.Pod) (string, error) {
if pod.Annotations != nil {
if source, ok := pod.Annotations[ConfigSourceAnnotationKey]; ok {
return source, nil
}
}
return "", fmt.Errorf("cannot get source of pod %q", pod.UID)
}
// SyncPodType classifies pod updates, eg: create, update.
type SyncPodType int
const (
// SyncPodSync is when the pod is synced to ensure desired state
SyncPodSync SyncPodType = iota
// SyncPodUpdate is when the pod is updated from source
SyncPodUpdate
// SyncPodCreate is when the pod is created from source
SyncPodCreate
// SyncPodKill is when the pod should have no running containers. A pod stopped in this way could be
// restarted in the future due config changes.
SyncPodKill
)
func (sp SyncPodType) String() string {
switch sp {
case SyncPodCreate:
return "create"
case SyncPodUpdate:
return "update"
case SyncPodSync:
return "sync"
case SyncPodKill:
return "kill"
default:
return "unknown"
}
}
// IsMirrorPod returns true if the passed Pod is a Mirror Pod.
func IsMirrorPod(pod *v1.Pod) bool {
if pod.Annotations == nil {
return false
}
_, ok := pod.Annotations[ConfigMirrorAnnotationKey]
return ok
}
// IsStaticPod returns true if the pod is a static pod.
func IsStaticPod(pod *v1.Pod) bool {
source, err := GetPodSource(pod)
return err == nil && source != ApiserverSource
}
// IsCriticalPod returns true if pod's priority is greater than or equal to SystemCriticalPriority.
func IsCriticalPod(pod *v1.Pod) bool {
if IsStaticPod(pod) {
return true
}
if IsMirrorPod(pod) {
return true
}
if pod.Spec.Priority != nil && IsCriticalPodBasedOnPriority(*pod.Spec.Priority) {
return true
}
return false
}
// Preemptable returns true if preemptor pod can preempt preemptee pod
// if preemptee is not critical or if preemptor's priority is greater than preemptee's priority
func Preemptable(preemptor, preemptee *v1.Pod) bool {
if IsCriticalPod(preemptor) && !IsCriticalPod(preemptee) {
return true
}
if (preemptor != nil && preemptor.Spec.Priority != nil) &&
(preemptee != nil && preemptee.Spec.Priority != nil) {
return *(preemptor.Spec.Priority) > *(preemptee.Spec.Priority)
}
return false
}
// IsCriticalPodBasedOnPriority checks if the given pod is a critical pod based on priority resolved from pod Spec.
func IsCriticalPodBasedOnPriority(priority int32) bool {
return priority >= scheduling.SystemCriticalPriority
}
// IsNodeCriticalPod checks if the given pod is a system-node-critical
func IsNodeCriticalPod(pod *v1.Pod) bool {
return IsCriticalPod(pod) && (pod.Spec.PriorityClassName == scheduling.SystemNodeCritical)
}

View File

@ -1,115 +0,0 @@
/*
Copyright 2015 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 types
import (
"net/http"
"time"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
)
// TODO: Reconcile custom types in kubelet/types and this subpackage
// HTTPGetter is an interface representing the ability to perform HTTP GET requests.
type HTTPGetter interface {
// Get issues a GET to the specified URL.
Get(url string) (*http.Response, error)
}
// Timestamp wraps around time.Time and offers utilities to format and parse
// the time using RFC3339Nano
type Timestamp struct {
time time.Time
}
// NewTimestamp returns a Timestamp object using the current time.
func NewTimestamp() *Timestamp {
return &Timestamp{time.Now()}
}
// ConvertToTimestamp takes a string, parses it using the RFC3339NanoLenient layout,
// and converts it to a Timestamp object.
func ConvertToTimestamp(timeString string) *Timestamp {
parsed, _ := time.Parse(RFC3339NanoLenient, timeString)
return &Timestamp{parsed}
}
// Get returns the time as time.Time.
func (t *Timestamp) Get() time.Time {
return t.time
}
// GetString returns the time in the string format using the RFC3339NanoFixed
// layout.
func (t *Timestamp) GetString() string {
return t.time.Format(RFC3339NanoFixed)
}
// SortedContainerStatuses is a type to help sort container statuses based on container names.
type SortedContainerStatuses []v1.ContainerStatus
func (s SortedContainerStatuses) Len() int { return len(s) }
func (s SortedContainerStatuses) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s SortedContainerStatuses) Less(i, j int) bool {
return s[i].Name < s[j].Name
}
// SortInitContainerStatuses ensures that statuses are in the order that their
// init container appears in the pod spec
func SortInitContainerStatuses(p *v1.Pod, statuses []v1.ContainerStatus) {
containers := p.Spec.InitContainers
current := 0
for _, container := range containers {
for j := current; j < len(statuses); j++ {
if container.Name == statuses[j].Name {
statuses[current], statuses[j] = statuses[j], statuses[current]
current++
break
}
}
}
}
// SortStatusesOfInitContainers returns the statuses of InitContainers of pod p,
// in the order that they appear in its spec.
func SortStatusesOfInitContainers(p *v1.Pod, statusMap map[string]*v1.ContainerStatus) []v1.ContainerStatus {
containers := p.Spec.InitContainers
statuses := []v1.ContainerStatus{}
for _, container := range containers {
if status, found := statusMap[container.Name]; found {
statuses = append(statuses, *status)
}
}
return statuses
}
// Reservation represents reserved resources for non-pod components.
type Reservation struct {
// System represents resources reserved for non-kubernetes components.
System v1.ResourceList
// Kubernetes represents resources reserved for kubernetes system components.
Kubernetes v1.ResourceList
}
// ResolvedPodUID is a pod UID which has been translated/resolved to the representation known to kubelets.
type ResolvedPodUID types.UID
// MirrorPodUID is a pod UID for a mirror pod.
type MirrorPodUID types.UID

View File

@ -78,6 +78,37 @@ func BuildPortsToEndpointsMap(endpoints *v1.Endpoints) map[string][]string {
return portsToEndpoints
}
// ContainsIPv4Loopback returns true if the input is empty or one of the CIDR contains an IPv4 loopback address.
func ContainsIPv4Loopback(cidrStrings []string) bool {
if len(cidrStrings) == 0 {
return true
}
// RFC 5735 127.0.0.0/8 - This block is assigned for use as the Internet host loopback address
ipv4LoopbackStart := netutils.ParseIPSloppy("127.0.0.0")
for _, cidr := range cidrStrings {
if IsZeroCIDR(cidr) {
return true
}
ip, ipnet, err := netutils.ParseCIDRSloppy(cidr)
if err != nil {
continue
}
if netutils.IsIPv6CIDR(ipnet) {
continue
}
if ip.IsLoopback() {
return true
}
if ipnet.Contains(ipv4LoopbackStart) {
return true
}
}
return false
}
// IsZeroCIDR checks whether the input CIDR string is either
// the IPv4 or IPv6 zero CIDR
func IsZeroCIDR(cidr string) bool {
@ -97,7 +128,7 @@ func IsProxyableIP(ip string) error {
}
func isProxyableIP(ip net.IP) error {
if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsInterfaceLocalMulticast() {
if !ip.IsGlobalUnicast() {
return ErrAddressNotAllowed
}
return nil
@ -490,7 +521,8 @@ func GetClusterIPByFamily(ipFamily v1.IPFamily, service *v1.Service) string {
}
type LineBuffer struct {
b bytes.Buffer
b bytes.Buffer
lines int
}
// Write takes a list of arguments, each a string or []string, joins all the
@ -516,22 +548,34 @@ func (buf *LineBuffer) Write(args ...interface{}) {
}
}
buf.b.WriteByte('\n')
buf.lines++
}
// WriteBytes writes bytes to buffer, and terminates with newline.
func (buf *LineBuffer) WriteBytes(bytes []byte) {
buf.b.Write(bytes)
buf.b.WriteByte('\n')
buf.lines++
}
// Reset clears buf
func (buf *LineBuffer) Reset() {
buf.b.Reset()
buf.lines = 0
}
// Bytes returns the contents of buf as a []byte
func (buf *LineBuffer) Bytes() []byte {
return buf.b.Bytes()
}
// Lines returns the number of lines in buf. Note that more precisely, this returns the
// number of times Write() or WriteBytes() was called; it assumes that you never wrote
// any newlines to the buffer yourself.
func (buf *LineBuffer) Lines() int {
return buf.lines
}
// RevertPorts is closing ports in replacementPortsMap but not in originalPortsMap. In other words, it only
// closes the ports opened in this sync.
func RevertPorts(replacementPortsMap, originalPortsMap map[netutils.LocalPort]netutils.Closeable) {
@ -543,8 +587,3 @@ func RevertPorts(replacementPortsMap, originalPortsMap map[netutils.LocalPort]ne
}
}
}
// CountBytesLines counts the number of lines in a bytes slice
func CountBytesLines(b []byte) int {
return bytes.Count(b, []byte{'\n'})
}

View File

@ -1,62 +0,0 @@
/*
Copyright 2016 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 apparmor
import (
"strings"
"k8s.io/api/core/v1"
)
// Checks whether app armor is required for pod to be run.
func isRequired(pod *v1.Pod) bool {
for key, value := range pod.Annotations {
if strings.HasPrefix(key, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
return value != v1.AppArmorBetaProfileNameUnconfined
}
}
return false
}
// GetProfileName returns the name of the profile to use with the container.
func GetProfileName(pod *v1.Pod, containerName string) string {
return GetProfileNameFromPodAnnotations(pod.Annotations, containerName)
}
// GetProfileNameFromPodAnnotations gets the name of the profile to use with container from
// pod annotations
func GetProfileNameFromPodAnnotations(annotations map[string]string, containerName string) string {
return annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+containerName]
}
// SetProfileName sets the name of the profile to use with the container.
func SetProfileName(pod *v1.Pod, containerName, profileName string) error {
if pod.Annotations == nil {
pod.Annotations = map[string]string{}
}
pod.Annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+containerName] = profileName
return nil
}
// SetProfileNameFromPodAnnotations sets the name of the profile to use with the container.
func SetProfileNameFromPodAnnotations(annotations map[string]string, containerName, profileName string) error {
if annotations == nil {
return nil
}
annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+containerName] = profileName
return nil
}

View File

@ -1,214 +0,0 @@
/*
Copyright 2016 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 apparmor
import (
"bufio"
"errors"
"fmt"
"os"
"path"
"strings"
"github.com/opencontainers/runc/libcontainer/apparmor"
v1 "k8s.io/api/core/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/features"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
utilpath "k8s.io/utils/path"
)
// Whether AppArmor should be disabled by default.
// Set to true if the wrong build tags are set (see validate_disabled.go).
var isDisabledBuild bool
// Validator is a interface for validating that a pod with an AppArmor profile can be run by a Node.
type Validator interface {
Validate(pod *v1.Pod) error
ValidateHost() error
}
// NewValidator is in order to find AppArmor FS
func NewValidator(runtime string) Validator {
if err := validateHost(runtime); err != nil {
return &validator{validateHostErr: err}
}
appArmorFS, err := getAppArmorFS()
if err != nil {
return &validator{
validateHostErr: fmt.Errorf("error finding AppArmor FS: %v", err),
}
}
return &validator{
appArmorFS: appArmorFS,
}
}
type validator struct {
validateHostErr error
appArmorFS string
}
func (v *validator) Validate(pod *v1.Pod) error {
if !isRequired(pod) {
return nil
}
if v.ValidateHost() != nil {
return v.validateHostErr
}
loadedProfiles, err := v.getLoadedProfiles()
if err != nil {
return fmt.Errorf("could not read loaded profiles: %v", err)
}
var retErr error
podutil.VisitContainers(&pod.Spec, podutil.AllContainers, func(container *v1.Container, containerType podutil.ContainerType) bool {
retErr = validateProfile(GetProfileName(pod, container.Name), loadedProfiles)
if retErr != nil {
return false
}
return true
})
return retErr
}
func (v *validator) ValidateHost() error {
return v.validateHostErr
}
// Verify that the host and runtime is capable of enforcing AppArmor profiles.
func validateHost(runtime string) error {
// Check feature-gates
if !utilfeature.DefaultFeatureGate.Enabled(features.AppArmor) {
return errors.New("AppArmor disabled by feature-gate")
}
// Check build support.
if isDisabledBuild {
return errors.New("binary not compiled for linux")
}
// Check kernel support.
if !apparmor.IsEnabled() {
return errors.New("AppArmor is not enabled on the host")
}
// Check runtime support. Currently only Docker is supported.
if runtime != kubetypes.DockerContainerRuntime && runtime != kubetypes.RemoteContainerRuntime {
return fmt.Errorf("AppArmor is only enabled for 'docker' and 'remote' runtimes. Found: %q", runtime)
}
return nil
}
// Verify that the profile is valid and loaded.
func validateProfile(profile string, loadedProfiles map[string]bool) error {
if err := ValidateProfileFormat(profile); err != nil {
return err
}
if strings.HasPrefix(profile, v1.AppArmorBetaProfileNamePrefix) {
profileName := strings.TrimPrefix(profile, v1.AppArmorBetaProfileNamePrefix)
if !loadedProfiles[profileName] {
return fmt.Errorf("profile %q is not loaded", profileName)
}
}
return nil
}
// ValidateProfileFormat checks the format of the profile.
func ValidateProfileFormat(profile string) error {
if profile == "" || profile == v1.AppArmorBetaProfileRuntimeDefault || profile == v1.AppArmorBetaProfileNameUnconfined {
return nil
}
if !strings.HasPrefix(profile, v1.AppArmorBetaProfileNamePrefix) {
return fmt.Errorf("invalid AppArmor profile name: %q", profile)
}
return nil
}
func (v *validator) getLoadedProfiles() (map[string]bool, error) {
profilesPath := path.Join(v.appArmorFS, "profiles")
profilesFile, err := os.Open(profilesPath)
if err != nil {
return nil, fmt.Errorf("failed to open %s: %v", profilesPath, err)
}
defer profilesFile.Close()
profiles := map[string]bool{}
scanner := bufio.NewScanner(profilesFile)
for scanner.Scan() {
profileName := parseProfileName(scanner.Text())
if profileName == "" {
// Unknown line format; skip it.
continue
}
profiles[profileName] = true
}
return profiles, nil
}
// The profiles file is formatted with one profile per line, matching a form:
// namespace://profile-name (mode)
// profile-name (mode)
// Where mode is {enforce, complain, kill}. The "namespace://" is only included for namespaced
// profiles. For the purposes of Kubernetes, we consider the namespace part of the profile name.
func parseProfileName(profileLine string) string {
modeIndex := strings.IndexRune(profileLine, '(')
if modeIndex < 0 {
return ""
}
return strings.TrimSpace(profileLine[:modeIndex])
}
func getAppArmorFS() (string, error) {
mountsFile, err := os.Open("/proc/mounts")
if err != nil {
return "", fmt.Errorf("could not open /proc/mounts: %v", err)
}
defer mountsFile.Close()
scanner := bufio.NewScanner(mountsFile)
for scanner.Scan() {
fields := strings.Fields(scanner.Text())
if len(fields) < 3 {
// Unknown line format; skip it.
continue
}
if fields[2] == "securityfs" {
appArmorFS := path.Join(fields[1], "apparmor")
if ok, err := utilpath.Exists(utilpath.CheckFollowSymlink, appArmorFS); !ok {
msg := fmt.Sprintf("path %s does not exist", appArmorFS)
if err != nil {
return "", fmt.Errorf("%s: %v", msg, err)
}
return "", errors.New(msg)
}
return appArmorFS, nil
}
}
if err := scanner.Err(); err != nil {
return "", fmt.Errorf("error scanning mounts: %v", err)
}
return "", errors.New("securityfs not found")
}

View File

@ -1,25 +0,0 @@
//go:build !linux
// +build !linux
/*
Copyright 2016 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 apparmor
func init() {
// If Kubernetes was not built for linux, apparmor is always disabled.
isDisabledBuild = true
}

View File

@ -1,19 +0,0 @@
/*
Copyright 2015 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 selinux contains wrapper functions for the libcontainer SELinux
// package. A NOP implementation is provided for non-linux platforms.
package selinux // import "k8s.io/kubernetes/pkg/util/selinux"

View File

@ -1,39 +0,0 @@
/*
Copyright 2014 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 selinux
// Note: the libcontainer SELinux package is only built for Linux, so it is
// necessary to have a NOP wrapper which is built for non-Linux platforms to
// allow code that links to this package not to differentiate its own methods
// for Linux and non-Linux platforms.
//
// SELinuxRunner wraps certain libcontainer SELinux calls. For more
// information, see:
//
// https://github.com/opencontainers/runc/blob/master/libcontainer/selinux/selinux.go
type SELinuxRunner interface {
// Getfilecon returns the SELinux context for the given path or returns an
// error.
Getfilecon(path string) (string, error)
}
// NewSELinuxRunner returns a new SELinuxRunner appropriate for the platform.
// On Linux, all methods short-circuit and return NOP values if SELinux is
// disabled. On non-Linux platforms, a NOP implementation is returned.
func NewSELinuxRunner() SELinuxRunner {
return &realSELinuxRunner{}
}

View File

@ -1,58 +0,0 @@
//go:build linux
// +build linux
/*
Copyright 2014 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 selinux
import (
selinux "github.com/opencontainers/selinux/go-selinux"
)
// SELinuxEnabled returns whether SELinux is enabled on the system. SELinux
// has a tri-state:
//
// 1. disabled: SELinux Kernel modules not loaded, SELinux policy is not
// checked during Kernel MAC checks
// 2. enforcing: Enabled; SELinux policy violations are denied and logged
// in the audit log
// 3. permissive: Enabled, but SELinux policy violations are permitted and
// logged in the audit log
//
// SELinuxEnabled returns true if SELinux is enforcing or permissive, and
// false if it is disabled.
func SELinuxEnabled() bool {
return selinux.GetEnabled()
}
// realSELinuxRunner is the real implementation of SELinuxRunner interface for
// Linux.
type realSELinuxRunner struct{}
var _ SELinuxRunner = &realSELinuxRunner{}
func (_ *realSELinuxRunner) Getfilecon(path string) (string, error) {
if !SELinuxEnabled() {
return "", nil
}
return selinux.FileLabel(path)
}
// SetFileLabel applies the SELinux label on the path or returns an error.
func SetFileLabel(path string, label string) error {
return selinux.SetFileLabel(path, label)
}

View File

@ -1,39 +0,0 @@
//go:build !linux
// +build !linux
/*
Copyright 2014 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 selinux
// SELinuxEnabled always returns false on non-linux platforms.
func SELinuxEnabled() bool {
return false
}
// realSELinuxRunner is the NOP implementation of the SELinuxRunner interface.
type realSELinuxRunner struct{}
var _ SELinuxRunner = &realSELinuxRunner{}
func (_ *realSELinuxRunner) Getfilecon(path string) (string, error) {
return "", nil
}
// FileLabel returns the SELinux label for this path or returns an error.
func SetFileLabel(path string, label string) error {
return nil
}

View File

@ -275,6 +275,16 @@ func TaintExists(taints []v1.Taint, taintToFind *v1.Taint) bool {
return false
}
// TaintKeyExists checks if the given taint key exists in list of taints. Returns true if exists false otherwise.
func TaintKeyExists(taints []v1.Taint, taintKeyToMatch string) bool {
for _, taint := range taints {
if taint.Key == taintKeyToMatch {
return true
}
}
return false
}
func TaintSetDiff(t1, t2 []v1.Taint) (taintsToAdd []*v1.Taint, taintsToRemove []*v1.Taint) {
for _, taint := range t1 {
if !TaintExists(t2, &taint) {

View File

@ -1,8 +1,8 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- sig-storage-approvers
- sig-storage-approvers
reviewers:
- sig-storage-reviewers
- sig-storage-reviewers
labels:
- sig/storage
- sig/storage

View File

@ -21,9 +21,11 @@ import (
"io"
"os"
"runtime"
"time"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
servermetrics "k8s.io/kubernetes/pkg/kubelet/server/metrics"
)
var _ MetricsProvider = &metricsBlock{}
@ -49,6 +51,9 @@ func NewMetricsBlock(device string) MetricsProvider {
// tools. Storage systems may have more information that they can provide by
// going through specialized APIs.
func (mb *metricsBlock) GetMetrics() (*Metrics, error) {
startTime := time.Now()
defer servermetrics.CollectVolumeStatCalDuration("block", startTime)
// TODO: Windows does not yet support VolumeMode=Block
if runtime.GOOS == "windows" {
return nil, NewNotImplementedError("Windows does not support Block volumes")

View File

@ -17,8 +17,11 @@ limitations under the License.
package volume
import (
"time"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
servermetrics "k8s.io/kubernetes/pkg/kubelet/server/metrics"
"k8s.io/kubernetes/pkg/volume/util/fs"
)
@ -40,6 +43,9 @@ func NewMetricsStatFS(path string) MetricsProvider {
// GetMetrics calculates the volume usage and device free space by executing "du"
// and gathering filesystem info for the Volume path.
func (md *metricsStatFS) GetMetrics() (*Metrics, error) {
startTime := time.Now()
defer servermetrics.CollectVolumeStatCalDuration("statfs", startTime)
metrics := &Metrics{Time: metav1.Now()}
if md.path == "" {
return metrics, NewNoPathDefinedError()

View File

@ -53,9 +53,6 @@ type ProbeEvent struct {
Op ProbeOperation // The operation to the plugin
}
// CSIVolumePhaseType stores information about CSI volume path.
type CSIVolumePhaseType string
const (
// Common parameter which can be specified in StorageClass to specify the desired FSType
// Provisioners SHOULD implement support for this if they are block device based
@ -65,8 +62,6 @@ const (
ProbeAddOrUpdate ProbeOperation = 1 << iota
ProbeRemove
CSIVolumeStaged CSIVolumePhaseType = "staged"
CSIVolumePublished CSIVolumePhaseType = "published"
)
var (
@ -124,15 +119,12 @@ type NodeResizeOptions struct {
NewSize resource.Quantity
OldSize resource.Quantity
// CSIVolumePhase contains volume phase on the node
CSIVolumePhase CSIVolumePhaseType
}
type DynamicPluginProber interface {
Init() error
// If an error occurs, events are undefined.
// aggregates events for successful drivers and errors for failed drivers
Probe() (events []ProbeEvent, err error)
}
@ -503,7 +495,6 @@ func (spec *Spec) IsKubeletExpandable() bool {
return spec.PersistentVolume.Spec.FlexVolume != nil
default:
return false
}
}
@ -708,30 +699,26 @@ func (pm *VolumePluginMgr) FindPluginByName(name string) (VolumePlugin, error) {
defer pm.mutex.RUnlock()
// Once we can get rid of legacy names we can reduce this to a map lookup.
matches := []VolumePlugin{}
var match VolumePlugin
if v, found := pm.plugins[name]; found {
matches = append(matches, v)
match = v
}
pm.refreshProbedPlugins()
if plugin, found := pm.probedPlugins[name]; found {
matches = append(matches, plugin)
if match != nil {
return nil, fmt.Errorf("multiple volume plugins matched: %s and %s", match.GetPluginName(), plugin.GetPluginName())
}
match = plugin
}
if len(matches) == 0 {
if match == nil {
return nil, fmt.Errorf("no volume plugin matched name: %s", name)
}
if len(matches) > 1 {
matchedPluginNames := []string{}
for _, plugin := range matches {
matchedPluginNames = append(matchedPluginNames, plugin.GetPluginName())
}
return nil, fmt.Errorf("multiple volume plugins matched: %s", strings.Join(matchedPluginNames, ","))
}
// Issue warning if the matched provider is deprecated
pm.logDeprecation(matches[0].GetPluginName())
return matches[0], nil
pm.logDeprecation(match.GetPluginName())
return match, nil
}
// logDeprecation logs warning when a deprecated plugin is used.
@ -748,11 +735,14 @@ func (pm *VolumePluginMgr) logDeprecation(plugin string) {
// If it is, initialize all probed plugins and replace the cache with them.
func (pm *VolumePluginMgr) refreshProbedPlugins() {
events, err := pm.prober.Probe()
if err != nil {
klog.ErrorS(err, "Error dynamically probing plugins")
return // Use cached plugins upon failure.
}
// because the probe function can return a list of valid plugins
// even when an error is present we still must add the plugins
// or they will be skipped because each event only fires once
for _, event := range events {
if event.Op == ProbeAddOrUpdate {
if err := pm.initProbedPlugin(event.Plugin); err != nil {
@ -1084,7 +1074,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod {
Containers: []v1.Container{
{
Name: "pv-recycler",
Image: "busybox:1.27",
Image: "k8s.gcr.io/debian-base:v2.0.0",
Command: []string{"/bin/sh"},
Args: []string{"-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"},
VolumeMounts: []v1.VolumeMount{

View File

@ -24,9 +24,11 @@ import (
"os"
"path/filepath"
"syscall"
"time"
"golang.org/x/sys/unix"
servermetrics "k8s.io/kubernetes/pkg/kubelet/server/metrics"
"k8s.io/kubernetes/pkg/volume/util/fsquota"
)
@ -71,9 +73,13 @@ func DiskUsage(path string) (UsageInfo, error) {
// First check whether the quota system knows about this directory
// A nil quantity or error means that the path does not support quotas
// or xfs_quota tool is missing and we should use other mechanisms.
startTime := time.Now()
consumption, _ := fsquota.GetConsumption(path)
if consumption != nil {
usage.Bytes = consumption.Value()
defer servermetrics.CollectVolumeStatCalDuration("fsquota", startTime)
} else {
defer servermetrics.CollectVolumeStatCalDuration("du", startTime)
}
inodes, _ := fsquota.GetInodes(path)

View File

@ -27,9 +27,9 @@ import (
"strings"
"syscall"
"github.com/opencontainers/selinux/go-selinux"
"golang.org/x/sys/unix"
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/util/selinux"
"k8s.io/mount-utils"
utilpath "k8s.io/utils/path"
)
@ -263,7 +263,7 @@ func GetSELinux(path string, mountInfoFilename string, selinuxEnabled seLinuxEna
// GetSELinuxSupport returns true if given path is on a mount that supports
// SELinux.
func (hu *HostUtil) GetSELinuxSupport(pathname string) (bool, error) {
return GetSELinux(pathname, procMountInfoPath, selinux.SELinuxEnabled)
return GetSELinux(pathname, procMountInfoPath, selinux.GetEnabled)
}
// GetOwner returns the integer ID for the user and group of the given path

View File

@ -10,4 +10,3 @@ approvers:
- jingxu97
- saad-ali
- jsafrane

View File

@ -260,7 +260,12 @@ func doCleanSubPaths(mounter mount.Interface, podDir string, volumeName string)
// scan /var/lib/kubelet/pods/<uid>/volume-subpaths/<volume>/<container name>/*
fullContainerDirPath := filepath.Join(subPathDir, containerDir.Name())
err = filepath.Walk(fullContainerDirPath, func(path string, info os.FileInfo, _ error) error {
// The original traversal method here was ReadDir, which was not so robust to handle some error such as "stale NFS file handle",
// so it was replaced with filepath.Walk in a later patch, which can pass through error and handled by the callback WalkFunc.
// After go 1.16, WalkDir was introduced, it's more effective than Walk because the callback WalkDirFunc is called before
// reading a directory, making it save some time when a container's subPath contains lots of dirs.
// See https://github.com/kubernetes/kubernetes/pull/71804 and https://github.com/kubernetes/kubernetes/issues/107667 for more details.
err = filepath.WalkDir(fullContainerDirPath, func(path string, info os.DirEntry, _ error) error {
if path == fullContainerDirPath {
// Skip top level directory
return nil

View File

@ -115,9 +115,9 @@ type Metrics struct {
// Attributes represents the attributes of this mounter.
type Attributes struct {
ReadOnly bool
Managed bool
SupportsSELinux bool
ReadOnly bool
Managed bool
SELinuxRelabel bool
}
// MounterArgs provides more easily extensible arguments to Mounter
@ -136,17 +136,6 @@ type Mounter interface {
// Uses Interface to provide the path for Docker binds.
Volume
// CanMount is called immediately prior to Setup to check if
// the required components (binaries, etc.) are available on
// the underlying node to complete the subsequent SetUp (mount)
// operation. If CanMount returns error, the mount operation is
// aborted and an event is generated indicating that the node
// does not have the required binaries to complete the mount.
// If CanMount succeeds, the mount operation continues
// normally. The CanMount check can be enabled or disabled
// using the experimental-check-mount-binaries binary flag
CanMount() error
// SetUp prepares and mounts/unpacks the volume to a
// self-determined directory path. The mount point and its
// content should be owned by `fsUser` or 'fsGroup' so that it can be

View File

@ -98,7 +98,7 @@ func changeFilePermission(filename string, fsGroup *int64, readonly bool, info o
err = os.Chmod(filename, info.Mode()|mask)
if err != nil {
klog.ErrorS(err, "Chown failed", "path", filename)
klog.ErrorS(err, "chmod failed", "path", filename)
}
return nil