diff --git a/charts/kserve-resources/templates/clusterrole.yaml b/charts/kserve-resources/templates/clusterrole.yaml index d95d1c79b7e..68dbb8f1f17 100644 --- a/charts/kserve-resources/templates/clusterrole.yaml +++ b/charts/kserve-resources/templates/clusterrole.yaml @@ -186,14 +186,6 @@ rules: - get - patch - update -- apiGroups: - - operator.knative.dev - resources: - - knativeservings - verbs: - - get - - list - - watch - apiGroups: - rbac.authorization.k8s.io resourceNames: diff --git a/cmd/manager/main.go b/cmd/manager/main.go index fe4b7b6c17e..419a21d75ea 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -31,7 +31,6 @@ import ( typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" "k8s.io/client-go/tools/record" - operatorv1beta1 "knative.dev/operator/pkg/apis/operator/v1beta1" knservingv1 "knative.dev/serving/pkg/apis/serving/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/config" @@ -191,19 +190,6 @@ func main() { } } - knServingFound, knServingCheckErr := utils.IsCrdAvailable(cfg, operatorv1beta1.SchemeGroupVersion.String(), constants.KnativeServingKind) - if knServingCheckErr != nil { - setupLog.Error(knServingCheckErr, "error when checking if Knative KnativeServing kind is available") - os.Exit(1) - } - if knServingFound { - setupLog.Info("Setting up Knative Operator scheme") - if err := operatorv1beta1.AddToScheme(mgr.GetScheme()); err != nil { - setupLog.Error(err, "unable to add Knative Operator APIs to scheme") - os.Exit(1) - } - } - if !ingressConfig.DisableIstioVirtualHost { vsFound, vsCheckErr := utils.IsCrdAvailable(cfg, istioclientv1beta1.SchemeGroupVersion.String(), constants.IstioVirtualServiceKind) if vsCheckErr != nil { diff --git a/config/configmap/inferenceservice.yaml b/config/configmap/inferenceservice.yaml index ca9033c6e89..cfa5b092dc5 100644 --- a/config/configmap/inferenceservice.yaml +++ b/config/configmap/inferenceservice.yaml @@ -59,7 +59,6 @@ data: # revisions, which prevents the reconciliation loop to be triggered if the annotations is # configured here are used. # Default values are: - # "autoscaling.knative.dev/initial-scale", # "autoscaling.knative.dev/min-scale", # "autoscaling.knative.dev/max-scale", # "internal.serving.kserve.io/storage-initializer-sourceuri", diff --git a/config/overlays/odh/inferenceservice-config-patch.yaml b/config/overlays/odh/inferenceservice-config-patch.yaml index 6a232d7583a..9f25d5d252e 100644 --- a/config/overlays/odh/inferenceservice-config-patch.yaml +++ b/config/overlays/odh/inferenceservice-config-patch.yaml @@ -88,7 +88,6 @@ data: inferenceService: |- { "serviceAnnotationDisallowedList": [ - "autoscaling.knative.dev/initial-scale", "autoscaling.knative.dev/min-scale", "autoscaling.knative.dev/max-scale", "internal.serving.kserve.io/storage-initializer-sourceuri", diff --git a/config/overlays/test/configmap/inferenceservice-openshift-ci-serverless-predictor.yaml b/config/overlays/test/configmap/inferenceservice-openshift-ci-serverless-predictor.yaml index 0f716d94595..1497292dcc3 100644 --- a/config/overlays/test/configmap/inferenceservice-openshift-ci-serverless-predictor.yaml +++ b/config/overlays/test/configmap/inferenceservice-openshift-ci-serverless-predictor.yaml @@ -88,7 +88,6 @@ data: inferenceService: |- { "serviceAnnotationDisallowedList": [ - "autoscaling.knative.dev/initial-scale", "autoscaling.knative.dev/min-scale", "autoscaling.knative.dev/max-scale", "internal.serving.kserve.io/storage-initializer-sourceuri", diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 35cee3e83ba..07f061cae30 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -173,14 +173,6 @@ rules: - get - patch - update -- apiGroups: - - operator.knative.dev - resources: - - knativeservings - verbs: - - get - - list - - watch - apiGroups: - rbac.authorization.k8s.io resourceNames: diff --git a/go.mod b/go.mod index f7b8bbbb67a..ce95fc34c73 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,6 @@ require ( k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9 k8s.io/utils v0.0.0-20241210054802-24370beab758 knative.dev/networking v0.0.0-20250117155906-67d1c274ba6a - knative.dev/operator v0.42.2 knative.dev/pkg v0.0.0-20250117084104-c43477f0052b knative.dev/serving v0.44.0 sigs.k8s.io/controller-runtime v0.19.1 diff --git a/go.sum b/go.sum index 1a396ea51a5..d080426bb11 100644 --- a/go.sum +++ b/go.sum @@ -397,8 +397,6 @@ github.com/linode/linodego v1.40.0 h1:7ESY0PwK94hoggoCtIroT1Xk6b1flrFBNZ6KwqbTql github.com/linode/linodego v1.40.0/go.mod h1:NsUw4l8QrLdIofRg1NYFBbW5ZERnmbZykVBszPZLORM= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/manifestival/manifestival v0.7.2 h1:l4uFdWX/xQK4QcRfqGoMtBvaZeWPEuwD6hVsCwUqZY4= -github.com/manifestival/manifestival v0.7.2/go.mod h1:nl3T6HlfHCeidooWVTMI9vYNTBkQ1GdhLNb+smozbdk= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -959,12 +957,8 @@ k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9 h1:t0huyHnz6HsokckRxAF1bY k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -knative.dev/caching v0.0.0-20250117155405-a76aa7cd2bb6 h1:a6oO186Ibm9iBmy9GzJPlJCVJnPPCppwo8NEm12Nnus= -knative.dev/caching v0.0.0-20250117155405-a76aa7cd2bb6/go.mod h1:xCMZSPoup5BSZ5GQ/Xa8xTEWNIZLLHx9mhPMeREt/ck= knative.dev/networking v0.0.0-20250117155906-67d1c274ba6a h1:FaDPXtv42+AkYh/mE269pttPSZ3fDVAjJiEsYUaM4SM= knative.dev/networking v0.0.0-20250117155906-67d1c274ba6a/go.mod h1:AIKYMfZydhwXR/60c/3KXEnqEnH6aNEEqulifdqJVcQ= -knative.dev/operator v0.42.2 h1:wgAWYHwoSFmV+wPHCt5dZahHTHLy2VCM4G82PEo9iSc= -knative.dev/operator v0.42.2/go.mod h1:cfSpJMgvwmuZ7USaxC+zgEuizMFc/xweREW5DG6J1DA= knative.dev/pkg v0.0.0-20250117084104-c43477f0052b h1:a+gP7Yzu5NmoX2w1p8nfTgmSKF+aHLKGzqYT82ijJTw= knative.dev/pkg v0.0.0-20250117084104-c43477f0052b/go.mod h1:bedSpkdLybR6JhL1J7XDLpd+JMKM/x8M5Apr80i5TeE= knative.dev/serving v0.44.0 h1:c6TXhoSAI6eXt0/1ET3C69jMWYA4ES9FskSan/fBaac= diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 36fe224cfcc..5c150db3557 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -283,11 +283,8 @@ type InferenceServiceProtocol string // Knative constants const ( - AutoscalerKey = "autoscaler" - AutoscalerInitialScaleKey = "initial-scale" AutoscalerConfigmapName = "config-autoscaler" AutoscalerAllowZeroScaleKey = "allow-zero-initial-scale" - DefaultKnServingName = "knative-serving" DefaultKnServingNamespace = "knative-serving" KnativeLocalGateway = "knative-serving/knative-local-gateway" KnativeIngressGateway = "knative-serving/knative-ingress-gateway" @@ -407,7 +404,6 @@ var ( // revisions, which prevents the reconciliation loop to be triggered if the annotations is // configured here are used. ServiceAnnotationDisallowedList = []string{ - autoscaling.InitialScaleAnnotationKey, autoscaling.MinScaleAnnotationKey, autoscaling.MaxScaleAnnotationKey, StorageInitializerSourceUriInternalAnnotationKey, @@ -533,7 +529,6 @@ const ( const ( IstioVirtualServiceKind = "VirtualService" KnativeServiceKind = "Service" - KnativeServingKind = "KnativeServing" HTTPRouteKind = "HTTPRoute" GatewayKind = "Gateway" ServiceKind = "Service" diff --git a/pkg/controller/v1alpha1/inferencegraph/controller.go b/pkg/controller/v1alpha1/inferencegraph/controller.go index 89340dea2e8..5f0856555ca 100644 --- a/pkg/controller/v1alpha1/inferencegraph/controller.go +++ b/pkg/controller/v1alpha1/inferencegraph/controller.go @@ -23,7 +23,6 @@ limitations under the License. // +kubebuilder:rbac:groups=serving.knative.dev,resources=services/status,verbs=get;update;patch // +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=create;get;update;patch;watch;delete // +kubebuilder:rbac:groups=route.openshift.io,resources=routes/status,verbs=get -// +kubebuilder:rbac:groups=operator.knative.dev,resources=knativeservings,verbs=get;list;watch package inferencegraph import ( @@ -48,7 +47,6 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/record" - operatorv1beta1 "knative.dev/operator/pkg/apis/operator/v1beta1" "knative.dev/pkg/apis" knservingv1 "knative.dev/serving/pkg/apis/serving/v1" ctrl "sigs.k8s.io/controller-runtime" @@ -285,19 +283,7 @@ func (r *InferenceGraphReconciler) Reconcile(ctx context.Context, req ctrl.Reque if !ksvcAvailable { r.Recorder.Event(graph, corev1.EventTypeWarning, "ServerlessModeRejected", "It is not possible to use Serverless deployment mode when Knative Services are not available") - return reconcile.Result{Requeue: false}, reconcile.TerminalError(fmt.Errorf("the resolved deployment mode of InferenceGraph '%s' is Serverless, but Knative Services are not available", graph.Name)) - } - - // Abort if Knative KnativeServings are not available - knServingFound, knServingCheckErr := utils.IsCrdAvailable(r.ClientConfig, operatorv1beta1.SchemeGroupVersion.String(), constants.KnativeServingKind) - if knServingCheckErr != nil { - return reconcile.Result{}, knServingCheckErr - } - - if !knServingFound { - r.Recorder.Event(graph, corev1.EventTypeWarning, "ServerlessModeRejected", - "It is not possible to use Serverless deployment mode when Knative KnativeServings are not available") - return reconcile.Result{Requeue: false}, reconcile.TerminalError(fmt.Errorf("the resolved deployment mode of InferenceGraph '%s' is Serverless, but Knative KnativeServings are not available", graph.Name)) + return reconcile.Result{Requeue: false}, reconcile.TerminalError(fmt.Errorf("the resolved deployment mode of InferenceGraph '%s' is Serverless, but Knative Serving is not available", graph.Name)) } // Retrieve the allow-zero-initial-scale value from the knative autoscaler configuration. @@ -306,7 +292,7 @@ func (r *InferenceGraphReconciler) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve the knative autoscaler configuration") } - knutils.ValidateInitialScaleAnnotation(graph.Annotations, allowZeroInitialScale, r.Log) + knutils.ValidateInitialScaleAnnotation(graph.Annotations, allowZeroInitialScale, graph.Spec.MinReplicas, r.Log) desired := createKnativeService(graph.ObjectMeta, graph, routerConfig) diff --git a/pkg/controller/v1alpha1/inferencegraph/controller_test.go b/pkg/controller/v1alpha1/inferencegraph/controller_test.go index 13860ed0473..1bf2a485048 100644 --- a/pkg/controller/v1alpha1/inferencegraph/controller_test.go +++ b/pkg/controller/v1alpha1/inferencegraph/controller_test.go @@ -239,6 +239,61 @@ var _ = Describe("Inference Graph controller test", func() { Expect(k8sClient.Create(ctx, ig)).Should(Succeed()) defer k8sClient.Delete(ctx, ig) + actualService := &knservingv1.Service{} + Eventually(func() error { + return k8sClient.Get(context.TODO(), serviceKey, actualService) + }, timeout). + Should(Succeed()) + + Expect(actualService.Spec.Template.Annotations).NotTo(HaveKey(autoscaling.InitialScaleAnnotationKey)) + }) + }) + When("a Serverless InferenceGraph is created with zero min replicas", func() { + It("should use the default initial scale value", func() { + // Create configmap + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: constants.InferenceServiceConfigMapName, + Namespace: constants.KServeNamespace, + }, + Data: configs, + } + Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred()) + defer k8sClient.Delete(context.TODO(), configMap) + + // Create InferenceGraph + graphName := "initialscale4" + expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: graphName, Namespace: "default"}} + serviceKey := expectedRequest.NamespacedName + ctx := context.Background() + var minScale int32 = 0 + ig := &v1alpha1.InferenceGraph{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceKey.Name, + Namespace: serviceKey.Namespace, + Annotations: map[string]string{ + "serving.kserve.io/deploymentMode": string(constants.Serverless), + }, + }, + Spec: v1alpha1.InferenceGraphSpec{ + MinReplicas: &minScale, + Nodes: map[string]v1alpha1.InferenceRouter{ + v1alpha1.GraphRootNodeName: { + RouterType: v1alpha1.Sequence, + Steps: []v1alpha1.InferenceStep{ + { + InferenceTarget: v1alpha1.InferenceTarget{ + ServiceURL: "http://someservice.exmaple.com", + }, + }, + }, + }, + }, + }, + } + Expect(k8sClient.Create(ctx, ig)).Should(Succeed()) + defer k8sClient.Delete(ctx, ig) + actualService := &knservingv1.Service{} Eventually(func() error { return k8sClient.Get(context.TODO(), serviceKey, actualService) @@ -291,7 +346,7 @@ var _ = Describe("Inference Graph controller test", func() { Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred()) defer k8sClient.Delete(context.TODO(), configMap) - graphName := "initialscale4" + graphName := "initialscale5" expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: graphName, Namespace: "default"}} serviceKey := expectedRequest.NamespacedName ctx := context.Background() @@ -346,7 +401,7 @@ var _ = Describe("Inference Graph controller test", func() { Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred()) defer k8sClient.Delete(context.TODO(), configMap) - graphName := "initialscale5" + graphName := "initialscale6" expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: graphName, Namespace: "default"}} serviceKey := expectedRequest.NamespacedName ctx := context.Background() @@ -401,7 +456,7 @@ var _ = Describe("Inference Graph controller test", func() { Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred()) defer k8sClient.Delete(context.TODO(), configMap) - graphName := "initialscale6" + graphName := "initialscale7" expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: graphName, Namespace: "default"}} serviceKey := expectedRequest.NamespacedName ctx := context.Background() @@ -443,6 +498,60 @@ var _ = Describe("Inference Graph controller test", func() { Expect(actualService.Spec.Template.Annotations).NotTo(HaveKey(autoscaling.InitialScaleAnnotationKey)) }) }) + When("a Serverless InferenceGraph is created with zero min replicas", func() { + It("should override the default initial scale value with zero", func() { + // Create configmap + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: constants.InferenceServiceConfigMapName, + Namespace: constants.KServeNamespace, + }, + Data: configs, + } + Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred()) + defer k8sClient.Delete(context.TODO(), configMap) + + graphName := "initialscale8" + expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: graphName, Namespace: "default"}} + serviceKey := expectedRequest.NamespacedName + ctx := context.Background() + var minScale int32 = 0 + ig := &v1alpha1.InferenceGraph{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceKey.Name, + Namespace: serviceKey.Namespace, + Annotations: map[string]string{ + "serving.kserve.io/deploymentMode": string(constants.Serverless), + }, + }, + Spec: v1alpha1.InferenceGraphSpec{ + MinReplicas: &minScale, + Nodes: map[string]v1alpha1.InferenceRouter{ + v1alpha1.GraphRootNodeName: { + RouterType: v1alpha1.Sequence, + Steps: []v1alpha1.InferenceStep{ + { + InferenceTarget: v1alpha1.InferenceTarget{ + ServiceURL: "http://someservice.exmaple.com", + }, + }, + }, + }, + }, + }, + } + Expect(k8sClient.Create(ctx, ig)).Should(Succeed()) + defer k8sClient.Delete(ctx, ig) + + actualService := &knservingv1.Service{} + Eventually(func() error { + return k8sClient.Get(context.TODO(), serviceKey, actualService) + }, timeout). + Should(Succeed()) + + Expect(actualService.Spec.Template.Annotations[autoscaling.InitialScaleAnnotationKey]).To(Equal("0")) + }) + }) }) Context("When creating an inferencegraph with headers in global config", func() { diff --git a/pkg/controller/v1alpha1/inferencegraph/suite_test.go b/pkg/controller/v1alpha1/inferencegraph/suite_test.go index 4ddc9af1d4f..5fa491693de 100644 --- a/pkg/controller/v1alpha1/inferencegraph/suite_test.go +++ b/pkg/controller/v1alpha1/inferencegraph/suite_test.go @@ -30,8 +30,6 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - "knative.dev/operator/pkg/apis/operator/base" - operatorv1beta1 "knative.dev/operator/pkg/apis/operator/v1beta1" knservingv1 "knative.dev/serving/pkg/apis/serving/v1" ctrl "sigs.k8s.io/controller-runtime" @@ -134,24 +132,6 @@ var _ = BeforeSuite(func() { } Expect(k8sClient.Create(context.Background(), configAutoscaler)).Should(Succeed()) - // Create knativeserving custom resource - knativeCr := &operatorv1beta1.KnativeServing{ - ObjectMeta: metav1.ObjectMeta{ - Name: constants.DefaultKnServingName, - Namespace: constants.DefaultKnServingNamespace, - }, - Spec: operatorv1beta1.KnativeServingSpec{ - CommonSpec: base.CommonSpec{ - Config: base.ConfigMapData{ - "autoscaler": map[string]string{ - "allow-zero-initial-scale": "true", - }, - }, - }, - }, - } - Expect(k8sClient.Create(context.Background(), knativeCr)).Should(Succeed()) - deployConfig := &v1beta1.DeployConfig{DefaultDeploymentMode: "Serverless"} err = (&InferenceGraphReconciler{ diff --git a/pkg/controller/v1alpha1/utils/utils.go b/pkg/controller/v1alpha1/utils/utils.go index b3279822c73..f305719102a 100644 --- a/pkg/controller/v1alpha1/utils/utils.go +++ b/pkg/controller/v1alpha1/utils/utils.go @@ -24,9 +24,7 @@ import ( "github.com/go-logr/logr" "github.com/pkg/errors" "k8s.io/client-go/kubernetes" - operatorv1beta1 "knative.dev/operator/pkg/apis/operator/v1beta1" "knative.dev/serving/pkg/apis/autoscaling" - "sigs.k8s.io/controller-runtime/pkg/client" "github.com/kserve/kserve/pkg/constants" @@ -35,48 +33,6 @@ import ( corev1helpers "k8s.io/component-helpers/scheduling/corev1" ) -// GetAutoscalerConfiguration reads the global knative serving configuration and retrieves values related to the autoscaler. -// This configuration is defined in the knativeserving custom resource. -func GetAutoscalerConfiguration(ctx context.Context, client client.Client) (string, string, error) { - // Set allow-zero-initial-scale and intitial-scale to their default values to start. - // If autoscaling values are not set in the configuration, then the defaults are used. - allowZeroInitialScale := "false" - globalInitialScale := "1" - - // List all knativeserving custom resources to handle scenarios where the custom resource is not created in the default knative-serving namespace. - knservingList := &operatorv1beta1.KnativeServingList{} - err := client.List(ctx, knservingList) - if err != nil { - return allowZeroInitialScale, globalInitialScale, errors.Wrapf( - err, - "fails to retrieve the knativeserving custom resource.", - ) - } else if len(knservingList.Items) == 0 { - return allowZeroInitialScale, globalInitialScale, errors.New("no knativeserving resources found in cluster.") - } - - // Always use the first knativeserving resource returned. - // We are operating under the assumption that there should be a single knativeserving custom resource created on the cluster. - knserving := knservingList.Items[0] - - // Check for both the autoscaler key with and without the 'config-' prefix. Both are supported by knative. - var knservingAutoscalerConfig map[string]string - if _, ok := knserving.Spec.Config[constants.AutoscalerKey]; ok { - knservingAutoscalerConfig = knserving.Spec.Config[constants.AutoscalerKey] - } else if _, ok := knserving.Spec.Config["config-"+constants.AutoscalerKey]; ok { - knservingAutoscalerConfig = knserving.Spec.Config["config-"+constants.AutoscalerKey] - } - - if configuredAllowZeroInitialScale, ok := knservingAutoscalerConfig[constants.AutoscalerAllowZeroScaleKey]; ok { - allowZeroInitialScale = configuredAllowZeroInitialScale - } - if configuredInitialScale, ok := knservingAutoscalerConfig[constants.AutoscalerInitialScaleKey]; ok { - globalInitialScale = configuredInitialScale - } - - return allowZeroInitialScale, globalInitialScale, nil -} - // CheckNodeAffinity returns true if the node matches the node affinity specified in the PV Spec func CheckNodeAffinity(pvSpec *corev1.PersistentVolumeSpec, node corev1.Node) (bool, error) { if pvSpec.NodeAffinity == nil || pvSpec.NodeAffinity.Required == nil { @@ -154,10 +110,20 @@ func CheckZeroInitialScaleAllowed(ctx context.Context, clientset kubernetes.Inte // ValidateInitialScaleAnnotation checks the annotations of a resource for the knative initial scale annotation. // When the annotation is set validation is performed. If any of this validation fails, the annotation will // be removed and the default initial scale behavior will be used. -func ValidateInitialScaleAnnotation(annotations map[string]string, allowZeroInitialScale bool, log logr.Logger) { +func ValidateInitialScaleAnnotation(annotations map[string]string, allowZeroInitialScale bool, minReplicas *int32, log logr.Logger) { // Check that the annoation is set. _, set := annotations[autoscaling.InitialScaleAnnotationKey] if !set { + // For scenarios where zero min replicas are requested, set the initial scale annotation to 0 + // unless explicitly set by an end user. + if allowZeroInitialScale { + if minReplicas == nil && constants.DefaultMinReplicas == 0 { + annotations[autoscaling.InitialScaleAnnotationKey] = "0" + } + if minReplicas != nil && *minReplicas == 0 { + annotations[autoscaling.InitialScaleAnnotationKey] = "0" + } + } return } diff --git a/pkg/controller/v1beta1/inferenceservice/components/explainer.go b/pkg/controller/v1beta1/inferenceservice/components/explainer.go index 998a4dd8007..6ea4c8c37c0 100644 --- a/pkg/controller/v1beta1/inferenceservice/components/explainer.go +++ b/pkg/controller/v1beta1/inferenceservice/components/explainer.go @@ -33,6 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/kserve/kserve/pkg/constants" + knutils "github.com/kserve/kserve/pkg/controller/v1alpha1/utils" "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/reconcilers/knative" "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/reconcilers/raw" isvcutils "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/utils" @@ -50,11 +51,12 @@ type Explainer struct { scheme *runtime.Scheme inferenceServiceConfig *v1beta1.InferenceServicesConfig deploymentMode constants.DeploymentModeType + allowZeroInitialScale bool Log logr.Logger } func NewExplainer(client client.Client, clientset kubernetes.Interface, scheme *runtime.Scheme, - inferenceServiceConfig *v1beta1.InferenceServicesConfig, deploymentMode constants.DeploymentModeType, + inferenceServiceConfig *v1beta1.InferenceServicesConfig, deploymentMode constants.DeploymentModeType, allowZeroInitialScale bool, ) Component { return &Explainer{ client: client, @@ -62,6 +64,7 @@ func NewExplainer(client client.Client, clientset kubernetes.Interface, scheme * scheme: scheme, inferenceServiceConfig: inferenceServiceConfig, deploymentMode: deploymentMode, + allowZeroInitialScale: allowZeroInitialScale, Log: ctrl.Log.WithName("ExplainerReconciler"), } } @@ -187,6 +190,7 @@ func (e *Explainer) Reconcile(ctx context.Context, isvc *v1beta1.InferenceServic } isvc.Status.PropagateRawStatus(v1beta1.ExplainerComponent, deployment, r.URL) } else { + knutils.ValidateInitialScaleAnnotation(objectMeta.Annotations, e.allowZeroInitialScale, isvc.Spec.Explainer.MinReplicas, e.Log) r := knative.NewKsvcReconciler(e.client, e.scheme, objectMeta, &isvc.Spec.Explainer.ComponentExtensionSpec, &podSpec, isvc.Status.Components[v1beta1.ExplainerComponent], e.inferenceServiceConfig.ServiceLabelDisallowedList) diff --git a/pkg/controller/v1beta1/inferenceservice/components/predictor.go b/pkg/controller/v1beta1/inferenceservice/components/predictor.go index 933c7806ceb..37bab4a515d 100644 --- a/pkg/controller/v1beta1/inferenceservice/components/predictor.go +++ b/pkg/controller/v1beta1/inferenceservice/components/predictor.go @@ -41,6 +41,7 @@ import ( "github.com/kserve/kserve/pkg/apis/serving/v1alpha1" "github.com/kserve/kserve/pkg/apis/serving/v1beta1" "github.com/kserve/kserve/pkg/constants" + knutils "github.com/kserve/kserve/pkg/controller/v1alpha1/utils" "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/reconcilers/knative" modelconfig "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/reconcilers/modelconfig" "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/reconcilers/raw" @@ -63,11 +64,12 @@ type Predictor struct { scheme *runtime.Scheme inferenceServiceConfig *v1beta1.InferenceServicesConfig deploymentMode constants.DeploymentModeType + allowZeroInitialScale bool Log logr.Logger } func NewPredictor(client client.Client, clientset kubernetes.Interface, scheme *runtime.Scheme, - inferenceServiceConfig *v1beta1.InferenceServicesConfig, deploymentMode constants.DeploymentModeType, + inferenceServiceConfig *v1beta1.InferenceServicesConfig, deploymentMode constants.DeploymentModeType, allowZeroInitialScale bool, ) Component { return &Predictor{ client: client, @@ -75,6 +77,7 @@ func NewPredictor(client client.Client, clientset kubernetes.Interface, scheme * scheme: scheme, inferenceServiceConfig: inferenceServiceConfig, deploymentMode: deploymentMode, + allowZeroInitialScale: allowZeroInitialScale, Log: ctrl.Log.WithName("PredictorReconciler"), } } @@ -741,6 +744,7 @@ func (p *Predictor) reconcileRawDeployment(ctx context.Context, isvc *v1beta1.In } func (p *Predictor) reconcileKnativeDeployment(ctx context.Context, isvc *v1beta1.InferenceService, objectMeta *metav1.ObjectMeta, podSpec *corev1.PodSpec) (*knservingv1.ServiceStatus, error) { + knutils.ValidateInitialScaleAnnotation(objectMeta.Annotations, p.allowZeroInitialScale, isvc.Spec.Predictor.MinReplicas, p.Log) r := knative.NewKsvcReconciler(p.client, p.scheme, *objectMeta, &isvc.Spec.Predictor.ComponentExtensionSpec, podSpec, isvc.Status.Components[v1beta1.PredictorComponent], p.inferenceServiceConfig.ServiceLabelDisallowedList) diff --git a/pkg/controller/v1beta1/inferenceservice/components/transformer.go b/pkg/controller/v1beta1/inferenceservice/components/transformer.go index 52f223a0eb1..2b6c07b0d77 100644 --- a/pkg/controller/v1beta1/inferenceservice/components/transformer.go +++ b/pkg/controller/v1beta1/inferenceservice/components/transformer.go @@ -36,6 +36,7 @@ import ( "github.com/kserve/kserve/pkg/apis/serving/v1beta1" "github.com/kserve/kserve/pkg/constants" + knutils "github.com/kserve/kserve/pkg/controller/v1alpha1/utils" "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/reconcilers/knative" raw "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/reconcilers/raw" isvcutils "github.com/kserve/kserve/pkg/controller/v1beta1/inferenceservice/utils" @@ -51,11 +52,12 @@ type Transformer struct { scheme *runtime.Scheme inferenceServiceConfig *v1beta1.InferenceServicesConfig deploymentMode constants.DeploymentModeType + allowZeroInitialScale bool Log logr.Logger } func NewTransformer(client client.Client, clientset kubernetes.Interface, scheme *runtime.Scheme, - inferenceServiceConfig *v1beta1.InferenceServicesConfig, deploymentMode constants.DeploymentModeType, + inferenceServiceConfig *v1beta1.InferenceServicesConfig, deploymentMode constants.DeploymentModeType, allowZeroInitialScale bool, ) Component { return &Transformer{ client: client, @@ -63,6 +65,7 @@ func NewTransformer(client client.Client, clientset kubernetes.Interface, scheme scheme: scheme, inferenceServiceConfig: inferenceServiceConfig, deploymentMode: deploymentMode, + allowZeroInitialScale: allowZeroInitialScale, Log: ctrl.Log.WithName("TransformerReconciler"), } } @@ -215,6 +218,7 @@ func (p *Transformer) Reconcile(ctx context.Context, isvc *v1beta1.InferenceServ } isvc.Status.PropagateRawStatus(v1beta1.TransformerComponent, deployment, r.URL) } else { + knutils.ValidateInitialScaleAnnotation(objectMeta.Annotations, p.allowZeroInitialScale, isvc.Spec.Transformer.MinReplicas, p.Log) r := knative.NewKsvcReconciler(p.client, p.scheme, objectMeta, &isvc.Spec.Transformer.ComponentExtensionSpec, &podSpec, isvc.Status.Components[v1beta1.TransformerComponent], p.inferenceServiceConfig.ServiceLabelDisallowedList) diff --git a/pkg/controller/v1beta1/inferenceservice/controller.go b/pkg/controller/v1beta1/inferenceservice/controller.go index 3ffa41fe0ab..eeac6401b81 100644 --- a/pkg/controller/v1beta1/inferenceservice/controller.go +++ b/pkg/controller/v1beta1/inferenceservice/controller.go @@ -38,7 +38,6 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/record" - operatorv1beta1 "knative.dev/operator/pkg/apis/operator/v1beta1" "knative.dev/pkg/apis" knservingv1 "knative.dev/serving/pkg/apis/serving/v1" ctrl "sigs.k8s.io/controller-runtime" @@ -90,7 +89,6 @@ import ( // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch // +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch // +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=operator.knative.dev,resources=knativeservings,verbs=get;list;watch // +kubebuilder:rbac:groups=keda.sh,resources=scaledobjects,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=keda.sh,resources=scaledobjects/finalizers,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=keda.sh,resources=scaledobjects/status,verbs=get;update;patch @@ -201,7 +199,8 @@ func (r *InferenceServiceReconciler) Reconcile(ctx context.Context, req ctrl.Req return ctrl.Result{}, nil } - // Abort early if the resolved deployment mode is Serverless, but Knative Services or KnativeServings are not available + // Abort early if the resolved deployment mode is Serverless, but Knative Services are not available + var allowZeroInitialScale bool if deploymentMode == constants.Serverless { ksvcAvailable, checkKsvcErr := utils.IsCrdAvailable(r.ClientConfig, knservingv1.SchemeGroupVersion.String(), constants.KnativeServiceKind) if checkKsvcErr != nil { @@ -211,28 +210,14 @@ func (r *InferenceServiceReconciler) Reconcile(ctx context.Context, req ctrl.Req if !ksvcAvailable { r.Recorder.Event(isvc, corev1.EventTypeWarning, "ServerlessModeRejected", "It is not possible to use Serverless deployment mode when Knative Services are not available") - return reconcile.Result{Requeue: false}, reconcile.TerminalError(fmt.Errorf("the resolved deployment mode of InferenceService '%s' is Serverless, but Knative Services are not available", isvc.Name)) - } - - // Abort if Knative KnativeServings are not available - knServingFound, knServingCheckErr := utils.IsCrdAvailable(r.ClientConfig, operatorv1beta1.SchemeGroupVersion.String(), constants.KnativeServingKind) - if knServingCheckErr != nil { - return reconcile.Result{}, knServingCheckErr - } - - if !knServingFound { - r.Recorder.Event(isvc, corev1.EventTypeWarning, "ServerlessModeRejected", - "It is not possible to use Serverless deployment mode when Knative KnativeServings are not available") - return reconcile.Result{Requeue: false}, reconcile.TerminalError(fmt.Errorf("the resolved deployment mode of InferenceService '%s' is Serverless, but Knative KnativeServings are not available", isvc.Name)) + return reconcile.Result{Requeue: false}, reconcile.TerminalError(fmt.Errorf("the resolved deployment mode of InferenceService '%s' is Serverless, but Knative Serving is not available", isvc.Name)) } // Retrieve the allow-zero-initial-scale value from the knative autoscaler configuration. - allowZeroInitialScale, err := knutils.CheckZeroInitialScaleAllowed(ctx, r.Clientset) + allowZeroInitialScale, err = knutils.CheckZeroInitialScaleAllowed(ctx, r.Clientset) if err != nil { return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve the knative autoscaler configuration") } - - knutils.ValidateInitialScaleAnnotation(isvc.Annotations, allowZeroInitialScale, r.Log) } // Setup reconcilers @@ -246,13 +231,13 @@ func (r *InferenceServiceReconciler) Reconcile(ctx context.Context, req ctrl.Req reconcilers := []components.Component{} if deploymentMode != constants.ModelMeshDeployment { - reconcilers = append(reconcilers, components.NewPredictor(r.Client, r.Clientset, r.Scheme, isvcConfig, deploymentMode)) + reconcilers = append(reconcilers, components.NewPredictor(r.Client, r.Clientset, r.Scheme, isvcConfig, deploymentMode, allowZeroInitialScale)) } if isvc.Spec.Transformer != nil { - reconcilers = append(reconcilers, components.NewTransformer(r.Client, r.Clientset, r.Scheme, isvcConfig, deploymentMode)) + reconcilers = append(reconcilers, components.NewTransformer(r.Client, r.Clientset, r.Scheme, isvcConfig, deploymentMode, allowZeroInitialScale)) } if isvc.Spec.Explainer != nil { - reconcilers = append(reconcilers, components.NewExplainer(r.Client, r.Clientset, r.Scheme, isvcConfig, deploymentMode)) + reconcilers = append(reconcilers, components.NewExplainer(r.Client, r.Clientset, r.Scheme, isvcConfig, deploymentMode, allowZeroInitialScale)) } for _, reconciler := range reconcilers { result, err := reconciler.Reconcile(ctx, isvc) diff --git a/pkg/controller/v1beta1/inferenceservice/controller_test.go b/pkg/controller/v1beta1/inferenceservice/controller_test.go index 9b6aa917c94..bd0c31955d0 100644 --- a/pkg/controller/v1beta1/inferenceservice/controller_test.go +++ b/pkg/controller/v1beta1/inferenceservice/controller_test.go @@ -270,6 +270,66 @@ var _ = Describe("v1beta1 inference service controller", func() { Expect(k8sClient.Create(ctx, isvc)).Should(Succeed()) defer k8sClient.Delete(ctx, isvc) + predictorServiceKey := types.NamespacedName{ + Name: constants.PredictorServiceName(serviceKey.Name), + Namespace: serviceKey.Namespace, + } + actualService := &knservingv1.Service{} + Eventually(func() error { return k8sClient.Get(context.TODO(), predictorServiceKey, actualService) }, timeout). + Should(Succeed()) + + Expect(actualService.Spec.Template.Annotations).NotTo(HaveKey(autoscaling.InitialScaleAnnotationKey)) + }) + }) + When("a Serverless InferenceService is created with zero min replicas", func() { + It("should use the default initial scale value", func() { + // Create configmap + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: constants.InferenceServiceConfigMapName, + Namespace: constants.KServeNamespace, + }, + Data: configs, + } + Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred()) + defer k8sClient.Delete(context.TODO(), configMap) + + // Create InferenceService + serviceName := "initialscale4" + expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: serviceName, Namespace: "default"}} + serviceKey := expectedRequest.NamespacedName + storageUri := "s3://test/mnist/export" + ctx := context.Background() + var minScale int32 = 0 + isvc := &v1beta1.InferenceService{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceKey.Name, + Namespace: serviceKey.Namespace, + Annotations: map[string]string{ + "serving.kserve.io/deploymentMode": "Serverless", + }, + }, + Spec: v1beta1.InferenceServiceSpec{ + Predictor: v1beta1.PredictorSpec{ + ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{ + MinReplicas: &minScale, + }, + Tensorflow: &v1beta1.TFServingSpec{ + PredictorExtensionSpec: v1beta1.PredictorExtensionSpec{ + StorageURI: &storageUri, + RuntimeVersion: proto.String("1.14.0"), + Container: corev1.Container{ + Name: constants.InferenceServiceContainerName, + Resources: defaultResource, + }, + }, + }, + }, + }, + } + Expect(k8sClient.Create(ctx, isvc)).Should(Succeed()) + defer k8sClient.Delete(ctx, isvc) + predictorServiceKey := types.NamespacedName{ Name: constants.PredictorServiceName(serviceKey.Name), Namespace: serviceKey.Namespace, @@ -325,7 +385,7 @@ var _ = Describe("v1beta1 inference service controller", func() { defer k8sClient.Delete(context.TODO(), configMap) // Create InferenceService - serviceName := "initialscale4" + serviceName := "initialscale5" expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: serviceName, Namespace: "default"}} serviceKey := expectedRequest.NamespacedName storageUri := "s3://test/mnist/export" @@ -386,7 +446,7 @@ var _ = Describe("v1beta1 inference service controller", func() { defer k8sClient.Delete(context.TODO(), configMap) // Create InferenceService - serviceName := "initialscale5" + serviceName := "initialscale6" expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: serviceName, Namespace: "default"}} serviceKey := expectedRequest.NamespacedName storageUri := "s3://test/mnist/export" @@ -447,7 +507,7 @@ var _ = Describe("v1beta1 inference service controller", func() { defer k8sClient.Delete(context.TODO(), configMap) // Create InferenceService - serviceName := "initialscale6" + serviceName := "initialscale7" expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: serviceName, Namespace: "default"}} serviceKey := expectedRequest.NamespacedName storageUri := "s3://test/mnist/export" @@ -494,6 +554,66 @@ var _ = Describe("v1beta1 inference service controller", func() { Expect(actualService.Spec.Template.Annotations).NotTo(HaveKey(autoscaling.InitialScaleAnnotationKey)) }) }) + When("a Serverless InferenceService is created with zero min replicas", func() { + It("should override the default initial scale value with zero", func() { + // Create configmap + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: constants.InferenceServiceConfigMapName, + Namespace: constants.KServeNamespace, + }, + Data: configs, + } + Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred()) + defer k8sClient.Delete(context.TODO(), configMap) + + // Create InferenceService + serviceName := "initialscale8" + expectedRequest := reconcile.Request{NamespacedName: types.NamespacedName{Name: serviceName, Namespace: "default"}} + serviceKey := expectedRequest.NamespacedName + storageUri := "s3://test/mnist/export" + ctx := context.Background() + var minScale int32 = 0 + isvc := &v1beta1.InferenceService{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceKey.Name, + Namespace: serviceKey.Namespace, + Annotations: map[string]string{ + "serving.kserve.io/deploymentMode": "Serverless", + }, + }, + Spec: v1beta1.InferenceServiceSpec{ + Predictor: v1beta1.PredictorSpec{ + ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{ + MinReplicas: &minScale, + }, + Tensorflow: &v1beta1.TFServingSpec{ + PredictorExtensionSpec: v1beta1.PredictorExtensionSpec{ + StorageURI: &storageUri, + RuntimeVersion: proto.String("1.14.0"), + Container: corev1.Container{ + Name: constants.InferenceServiceContainerName, + Resources: defaultResource, + }, + }, + }, + }, + }, + } + Expect(k8sClient.Create(ctx, isvc)).Should(Succeed()) + defer k8sClient.Delete(ctx, isvc) + + predictorServiceKey := types.NamespacedName{ + Name: constants.PredictorServiceName(serviceKey.Name), + Namespace: serviceKey.Namespace, + } + actualService := &knservingv1.Service{} + Eventually(func() error { return k8sClient.Get(context.TODO(), predictorServiceKey, actualService) }, timeout). + Should(Succeed()) + + Expect(actualService.Spec.Template.Annotations[autoscaling.InitialScaleAnnotationKey]).To(Equal("0")) + }) + }) }) Context("an annotation is applied to an InferenceService resource", func() { diff --git a/pkg/controller/v1beta1/inferenceservice/suite_test.go b/pkg/controller/v1beta1/inferenceservice/suite_test.go index 6d5da7b4240..571ea5ea575 100644 --- a/pkg/controller/v1beta1/inferenceservice/suite_test.go +++ b/pkg/controller/v1beta1/inferenceservice/suite_test.go @@ -30,8 +30,6 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - "knative.dev/operator/pkg/apis/operator/base" - operatorv1beta1 "knative.dev/operator/pkg/apis/operator/v1beta1" knservingv1 "knative.dev/serving/pkg/apis/serving/v1" ctrl "sigs.k8s.io/controller-runtime" @@ -149,24 +147,6 @@ var _ = BeforeSuite(func() { } Expect(k8sClient.Create(context.Background(), configAutoscaler)).Should(Succeed()) - // Create knativeserving custom resource - knativeCr := &operatorv1beta1.KnativeServing{ - ObjectMeta: metav1.ObjectMeta{ - Name: constants.DefaultKnServingName, - Namespace: constants.DefaultKnServingNamespace, - }, - Spec: operatorv1beta1.KnativeServingSpec{ - CommonSpec: base.CommonSpec{ - Config: base.ConfigMapData{ - "autoscaler": map[string]string{ - "allow-zero-initial-scale": "true", - }, - }, - }, - }, - } - Expect(k8sClient.Create(context.Background(), knativeCr)).Should(Succeed()) - deployConfig := &v1beta1.DeployConfig{DefaultDeploymentMode: "Serverless"} ingressConfig := &v1beta1.IngressConfig{ IngressGateway: constants.KnativeIngressGateway, diff --git a/pkg/testing/envtest_setup.go b/pkg/testing/envtest_setup.go index e8f83e41abf..22eb63db06b 100644 --- a/pkg/testing/envtest_setup.go +++ b/pkg/testing/envtest_setup.go @@ -28,7 +28,6 @@ import ( "github.com/onsi/gomega" otelv1beta1 "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" "k8s.io/client-go/kubernetes/scheme" - operatorv1beta1 "knative.dev/operator/pkg/apis/operator/v1beta1" knservingv1 "knative.dev/serving/pkg/apis/serving/v1" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -59,10 +58,6 @@ func SetupEnvTest(crdDirectoryPaths []string) *envtest.Environment { log.Error(err, "Failed to add istio scheme") } - if err := operatorv1beta1.SchemeBuilder.AddToScheme(scheme.Scheme); err != nil { - log.Error(err, "Failed to add knative operator scheme") - } - if err := gatewayapiv1.Install(scheme.Scheme); err != nil { log.Error(err, "Failed to add gateway scheme") } diff --git a/test/crds/knative_knativeserving.yaml b/test/crds/knative_knativeserving.yaml deleted file mode 100644 index 2fb7d773871..00000000000 --- a/test/crds/knative_knativeserving.yaml +++ /dev/null @@ -1,2510 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: knativeservings.operator.knative.dev -spec: - conversion: - strategy: None - group: operator.knative.dev - names: - kind: KnativeServing - listKind: KnativeServingList - plural: knativeservings - singular: knativeserving - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .status.version - name: Version - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].reason - name: Reason - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: Schema for the knativeservings API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of KnativeServing - properties: - config: - additionalProperties: - additionalProperties: - type: string - type: object - description: A means to override the corresponding entries in the - upstream configmaps - type: object - controller-custom-certs: - description: Enabling the controller to trust registries with self-signed - certificates - properties: - name: - description: The name of the ConfigMap or Secret - type: string - type: - description: One of ConfigMap or Secret - enum: - - ConfigMap - - Secret - - "" - type: string - type: object - deployments: - description: A mapping of deployment name to override - items: - properties: - affinity: - description: If specified, the pod's scheduling constraints. - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for - the pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a - no-op). A null preferred scheduling term matches - no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range - 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to an - update), the system may or may not try to eventually - evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - type: array - required: - - nodeSelectorTerms - type: object - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. - co-locate this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) with the - highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules - (e.g. avoid putting this pod in the same node, zone, etc. - as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the greatest - sum of weights, i.e. for each node that meets all - of the scheduling requirements (resource request, - requiredDuringScheduling anti-affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if the - node has pods which matches the corresponding podAffinityTerm; - the node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - annotations: - additionalProperties: - type: string - description: Annotations overrides labels for the deployment - and its template. - type: object - env: - description: Env overrides env vars for the containers. - items: - properties: - container: - description: The container name - type: string - envVars: - description: The desired EnvVarRequirements - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previously defined environment - variables in the container and any service environment - variables. 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 produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults - to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - required: - - container - type: object - type: array - hostNetwork: - description: Use the host's network namespace if true. Make - sure to understand the security implications if you want to - enable it. When hostNetwork is enabled, this will set dnsPolicy - to ClusterFirstWithHostNet automatically. - type: boolean - labels: - additionalProperties: - type: string - description: Labels overrides labels for the deployment and - its template. - type: object - livenessProbes: - description: LivenessProbes overrides liveness probes for the - containers. - items: - description: ProbesRequirementsOverride enables the user to - override any container's env vars. - properties: - container: - description: The container name - type: string - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided by - the pod spec. Value must be non-negative integer. The - value zero indicates stop immediately via the kill signal - (no opportunity to shut down). This is a beta field - and requires enabling ProbeTerminationGracePeriod feature - gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - required: - - container - type: object - type: array - name: - description: The name of the deployment - type: string - nodeSelector: - additionalProperties: - type: string - description: NodeSelector overrides nodeSelector for the deployment. - type: object - readinessProbes: - description: ReadinessProbes overrides readiness probes for - the containers. - items: - description: ProbesRequirementsOverride enables the user to - override any container's env vars. - properties: - container: - description: The container name - type: string - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided by - the pod spec. Value must be non-negative integer. The - value zero indicates stop immediately via the kill signal - (no opportunity to shut down). This is a beta field - and requires enabling ProbeTerminationGracePeriod feature - gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - required: - - container - type: object - type: array - replicas: - description: The number of replicas that HA parts of the control - plane will be scaled to - minimum: 0 - type: integer - resources: - description: If specified, the container's resources. - items: - description: The pod this Resource is used to specify the - requests and limits for a certain container based on the - name. - properties: - container: - description: The name of the container - type: string - limits: - properties: - cpu: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - memory: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - type: object - requests: - properties: - cpu: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - memory: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - type: object - type: object - type: array - tolerations: - description: If specified, the pod's tolerations. - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - topologySpreadConstraints: - description: If specified, the pod's topology spread constraints. - items: - description: TopologySpreadConstraint specifies how to spread - matching pods among the given topology. - properties: - labelSelector: - description: LabelSelector is used to find matching pods. - Pods that match this label selector are counted to determine - the number of pods in their corresponding topology domain. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - maxSkew: - description: 'MaxSkew describes the degree to which pods - may be unevenly distributed. It''s the maximum permitted - difference between the number of matching pods in any - two topology domains of a given topology type. For example, - in a 3-zone cluster, MaxSkew is set to 1, and pods with - the same labelSelector spread as 1/1/0: | zone1 | zone2 - | zone3 | | 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) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled onto - any zone. It''s a required field. Default value is 1 - and 0 is not allowed.' - format: int32 - type: integer - topologyKey: - description: TopologyKey is the key of node labels. Nodes - that have a label with this key and identical values - are considered to be in the same topology. We consider - each as a "bucket", and try to put balanced - number of pods into each bucket. It's a required field. - type: string - whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how to deal - with a pod if it doesn''t satisfy the spread constraint. - - DoNotSchedule (default) tells the scheduler not to - schedule it - ScheduleAnyway tells the scheduler to - still schedule it It''s considered as "Unsatisfiable" - if and only if placing incoming pod on any topology - violates "MaxSkew". For example, in a 3-zone cluster, - MaxSkew is set to 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, incoming - pod can only be scheduled to zone2(zone3) to become - 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies - MaxSkew(1). In other words, the cluster can still be - imbalanced, but scheduler won''t make it *more* imbalanced. - It''s a required field.' - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - type: object - type: array - high-availability: - description: Allows specification of HA control plane - properties: - replicas: - description: The number of replicas that HA parts of the control - plane will be scaled to - minimum: 0 - type: integer - type: object - ingress: - description: The ingress configuration for Knative Serving - properties: - istio: - description: Istio settings - properties: - enabled: - type: boolean - knative-local-gateway: - description: A means to override the knative-local-gateway - properties: - selector: - additionalProperties: - type: string - description: The selector for the ingress-gateway. - type: object - servers: - description: A list of server specifications. - items: - properties: - hosts: - description: One or more hosts exposed by this gateway. - items: - format: string - type: string - type: array - port: - properties: - name: - description: Label assigned to the port. - format: string - type: string - number: - description: A valid non-negative integer port - number. - type: integer - protocol: - description: The protocol exposed on the port. - format: string - type: string - target_port: - description: A valid non-negative integer target - port number. - type: integer - type: object - tls: - properties: - credentialName: - description: TLS certificate name. - format: string - type: string - mode: - description: TLS mode can be SIMPLE, MUTUAL, - ISTIO_MUTUAL. - format: string - type: string - type: object - type: object - type: array - type: object - type: object - kourier: - description: Kourier settings - properties: - bootstrap-configmap: - type: string - enabled: - type: boolean - http-port: - type: integer - https-port: - type: integer - service-load-balancer-ip: - type: string - service-type: - type: string - type: object - type: object - x-kubernetes-preserve-unknown-fields: true - podDisruptionBudgets: - description: A mapping of podDisruptionBudget name to override - items: - properties: - maxUnavailable: - anyOf: - - type: integer - - type: string - description: An eviction is allowed if at most "maxUnavailable" - pods selected by "selector" are unavailable after the eviction, - i.e. even in absence of the evicted pod. For example, one - can prevent all voluntary evictions by specifying 0. This - is a mutually exclusive setting with "minAvailable". - x-kubernetes-int-or-string: true - minAvailable: - anyOf: - - type: integer - - type: string - description: An eviction is allowed if at least "minAvailable" - pods selected by "selector" will still be available after - the eviction, i.e. even in the absence of the evicted pod. So - for example you can prevent all voluntary evictions by specifying - "100%". - x-kubernetes-int-or-string: true - name: - description: The name of the podDisruptionBudget - type: string - type: object - type: array - security: - description: The security configuration for Knative Serving - properties: - securityGuard: - description: Security Guard settings - properties: - enabled: - type: boolean - type: object - type: object - services: - description: A mapping of service name to override - items: - properties: - annotations: - additionalProperties: - type: string - description: Annotations overrides labels for the service - type: object - labels: - additionalProperties: - type: string - description: Labels overrides labels for the service - type: object - name: - description: The name of the service - type: string - selector: - additionalProperties: - type: string - description: Selector overrides selector for the service - type: object - type: object - type: array - workloads: - description: A mapping of deployment or statefulset name to override - items: - properties: - affinity: - description: If specified, the pod's scheduling constraints. - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for - the pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node matches the corresponding matchExpressions; - the node(s) with the highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a - no-op). A null preferred scheduling term matches - no objects (i.e. is also a no-op). - properties: - preference: - description: A node selector term, associated - with the corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - weight: - description: Weight associated with matching the - corresponding nodeSelectorTerm, in the range - 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to an - update), the system may or may not try to eventually - evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term - matches no objects. The requirements of them - are ANDed. The TopologySelectorTerm type implements - a subset of the NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: The label key that the - selector applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators - are In, NotIn, Exists, DoesNotExist. - Gt, and Lt. - type: string - values: - description: An array of string values. - If the operator is In or NotIn, the - values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. If - the operator is Gt or Lt, the values - array must have a single element, - which will be interpreted as an integer. - This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - type: array - required: - - nodeSelectorTerms - type: object - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. - co-locate this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the affinity expressions specified - by this field, but it may choose a node that violates - one or more of the expressions. The node that is most - preferred is the one with the greatest sum of weights, - i.e. for each node that meets all of the scheduling - requirements (resource request, requiredDuringScheduling - affinity expressions, etc.), compute a sum by iterating - through the elements of this field and adding "weight" - to the sum if the node has pods which matches the - corresponding podAffinityTerm; the node(s) with the - highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules - (e.g. avoid putting this pod in the same node, zone, etc. - as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods - to nodes that satisfy the anti-affinity expressions - specified by this field, but it may choose a node - that violates one or more of the expressions. The - node that is most preferred is the one with the greatest - sum of weights, i.e. for each node that meets all - of the scheduling requirements (resource request, - requiredDuringScheduling anti-affinity expressions, - etc.), compute a sum by iterating through the elements - of this field and adding "weight" to the sum if the - node has pods which matches the corresponding podAffinityTerm; - the node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred - node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents - a key's relationship to a set - of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array - of string values. If the operator - is In or NotIn, the values array - must be non-empty. If the operator - is Exists or DoesNotExist, the - values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located - (affinity) or not co-located (anti-affinity) - with the pods matching the labelSelector - in the specified namespaces, where co-located - is defined as running on a node whose value - of the label with key topologyKey matches - that of any node on which any of the selected - pods is running. Empty topologyKey is not - allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the - corresponding podAffinityTerm, in the range - 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified - by this field are not met at scheduling time, the - pod will not be scheduled onto the node. If the anti-affinity - requirements specified by this field cease to be met - at some point during pod execution (e.g. due to a - pod label update), the system may or may not try to - eventually evict the pod from its node. When there - are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all - terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or - not co-located (anti-affinity) with, where co-located - is defined as running on a node whose value of the - label with key matches that of any - node on which a pod of the set of pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of - label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, a - key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies which namespaces - the labelSelector applies to (matches against); - null or empty list means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified - namespaces, where co-located is defined as running - on a node whose value of the label with key - topologyKey matches that of any node on which - any of the selected pods is running. Empty topologyKey - is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - annotations: - additionalProperties: - type: string - description: Annotations overrides labels for the deployment - and its template. - type: object - env: - description: Env overrides env vars for the containers. - items: - properties: - container: - description: The container name - type: string - envVars: - description: The desired EnvVarRequirements - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previously defined environment - variables in the container and any service environment - variables. 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 produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults - to "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults to - "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More - info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret - or its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - required: - - container - type: object - type: array - hostNetwork: - description: Use the host's network namespace if true. Make - sure to understand the security implications if you want to - enable it. When hostNetwork is enabled, this will set dnsPolicy - to ClusterFirstWithHostNet automatically. - type: boolean - labels: - additionalProperties: - type: string - description: Labels overrides labels for the deployment and - its template. - type: object - livenessProbes: - description: LivenessProbes overrides liveness probes for the - containers. - items: - description: ProbesRequirementsOverride enables the user to - override any container's env vars. - properties: - container: - description: The container name - type: string - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided by - the pod spec. Value must be non-negative integer. The - value zero indicates stop immediately via the kill signal - (no opportunity to shut down). This is a beta field - and requires enabling ProbeTerminationGracePeriod feature - gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - required: - - container - type: object - type: array - name: - description: The name of the deployment - type: string - nodeSelector: - additionalProperties: - type: string - description: NodeSelector overrides nodeSelector for the deployment. - type: object - readinessProbes: - description: ReadinessProbes overrides readiness probes for - the containers. - items: - description: ProbesRequirementsOverride enables the user to - override any container's env vars. - properties: - container: - description: The container name - type: string - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided by - the pod spec. Value must be non-negative integer. The - value zero indicates stop immediately via the kill signal - (no opportunity to shut down). This is a beta field - and requires enabling ProbeTerminationGracePeriod feature - gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - required: - - container - type: object - type: array - replicas: - description: The number of replicas that HA parts of the control - plane will be scaled to - minimum: 0 - type: integer - resources: - description: If specified, the container's resources. - items: - description: The pod this Resource is used to specify the - requests and limits for a certain container based on the - name. - properties: - container: - description: The name of the container - type: string - limits: - properties: - cpu: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - memory: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - type: object - requests: - properties: - cpu: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - memory: - pattern: ^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$ - type: string - type: object - type: object - type: array - tolerations: - description: If specified, the pod's tolerations. - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, - allowed values are NoSchedule, PreferNoSchedule and - NoExecute. - type: string - key: - description: Key is the taint key that the toleration - applies to. Empty means match all taint keys. If the - key is empty, operator must be Exists; this combination - means to match all values and all keys. - type: string - operator: - description: Operator represents a key's relationship - to the value. Valid operators are Exists and Equal. - Defaults to Equal. Exists is equivalent to wildcard - for value, so that a pod can tolerate all taints of - a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the - taint forever (do not evict). Zero and negative values - will be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - topologySpreadConstraints: - description: If specified, the pod's topology spread constraints. - items: - description: TopologySpreadConstraint specifies how to spread - matching pods among the given topology. - properties: - labelSelector: - description: LabelSelector is used to find matching pods. - Pods that match this label selector are counted to determine - the number of pods in their corresponding topology domain. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - maxSkew: - description: 'MaxSkew describes the degree to which pods - may be unevenly distributed. It''s the maximum permitted - difference between the number of matching pods in any - two topology domains of a given topology type. For example, - in a 3-zone cluster, MaxSkew is set to 1, and pods with - the same labelSelector spread as 1/1/0: | zone1 | zone2 - | zone3 | | 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) violate MaxSkew(1). - - if MaxSkew is 2, incoming pod can be scheduled onto - any zone. It''s a required field. Default value is 1 - and 0 is not allowed.' - format: int32 - type: integer - topologyKey: - description: TopologyKey is the key of node labels. Nodes - that have a label with this key and identical values - are considered to be in the same topology. We consider - each as a "bucket", and try to put balanced - number of pods into each bucket. It's a required field. - type: string - whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how to deal - with a pod if it doesn''t satisfy the spread constraint. - - DoNotSchedule (default) tells the scheduler not to - schedule it - ScheduleAnyway tells the scheduler to - still schedule it It''s considered as "Unsatisfiable" - if and only if placing incoming pod on any topology - violates "MaxSkew". For example, in a 3-zone cluster, - MaxSkew is set to 1, and pods with the same labelSelector - spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | - If WhenUnsatisfiable is set to DoNotSchedule, incoming - pod can only be scheduled to zone2(zone3) to become - 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies - MaxSkew(1). In other words, the cluster can still be - imbalanced, but scheduler won''t make it *more* imbalanced. - It''s a required field.' - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - version: - description: Version the cluster should be on. - type: string - volumeMounts: - description: VolumeMounts allows configuration of additional - VolumeMounts on the output StatefulSet definition. VolumeMounts - specified will be appended to other VolumeMounts in the alertmanager - container, that are generated as a result of StorageSpec objects. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which the volume - should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts are - propagated from the host to container and the other - way around. When not set, MountPropagationNone is used. - This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write otherwise - (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the container's - volume should be mounted. Defaults to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from which - the container's volume should be mounted. Behaves similarly - to SubPath but environment variable references $(VAR_NAME) - are expanded using the container's environment. Defaults - to "" (volume's root). SubPathExpr and SubPath are mutually - exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - type: object - type: array - type: object - x-kubernetes-preserve-unknown-fields: true - status: - description: Status defines the observed state of KnativeServing - properties: - conditions: - description: The latest available observations of a resource's current - state. - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. We use VolatileTime - in place of metav1.Time to exclude this from creating equality.Semantic - differences (all other things held constant). - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - severity: - description: Severity with which to treat failures of this type - of condition. When this is not specified, it defaults to Error. - type: string - status: - description: Status of the condition, one of True, False, Unknown. - type: string - type: - description: Type of condition. - type: string - required: - - type - - status - type: object - type: array - manifests: - description: The list of serving manifests, which have been installed - by the operator - items: - type: string - type: array - observedGeneration: - description: The generation last processed by the controller - type: integer - version: - description: The version of the installed release - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: KnativeServing - listKind: KnativeServingList - plural: knativeservings - singular: knativeserving - conditions: - - lastTransitionTime: "2025-02-11T21:32:16Z" - message: no conflicts found - reason: NoConflicts - status: "True" - type: NamesAccepted - - lastTransitionTime: "2025-02-11T21:32:17Z" - message: the initial names have been accepted - reason: InitialNamesAccepted - status: "True" - type: Established - storedVersions: - - v1beta1