Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when creating Knative Service: Admission webhook denied request due to metadata.name change validation #15607

Open
helloxjade opened this issue Nov 8, 2024 · 3 comments
Labels
kind/question Further information is requested triage/needs-user-input Issues which are waiting on a response from the reporter

Comments

@helloxjade
Copy link

Description: I encountered an issue when trying to create a new Knative Service. Even though the service is newly created, I receive an error related to the validation of the metadata.name in spec.template. The error suggests that the service is attempting a change without a corresponding name update, which is unexpected for a newly created resource.

Error Message:


Failed to create Knative Service: admission webhook "validation.webhook.serving.knative.dev" denied the request: validation failed: Saw the following changes without a name change (-old +new): spec.template.metadata.name...

Expected Behavior: As this is a new service creation, there should be no conflict or validation errors on metadata.name in spec.template.

Steps to Reproduce:

"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
if _, err := controllerutil.CreateOrUpdate(ctx, ksb.KnativeClient, knservice, ksb.MutateKnServiceFn(knservice, sapp)); err != nil {
// 如果不是资源版本冲突错误,记录事件和日志
if !apierrors.IsConflict(err) {
ksb.EventRecorder.RecordEventf(sapp, corev1.EventTypeWarning, util.EventReasonFailedCreateKsvc, util.FailedCreateKsvcMsg, err.Error())
klog.Errorf("Failed to create or update knservice for app: %s, error: %v", sapp.Name, err)
}
// 返回错误,触发重试机制
return err
}
If applicable, mention whether CreateOrUpdate with mutate functions was used and if the mutation involved changes to metadata.
Environment:

Knative version: v1.11.4
Kubernetes version: Kubernetes v1.25.14
Client tools or libraries:

Any insight into this validation behavior or recommended configurations to avoid this error would be helpful. Thanks!

@helloxjade helloxjade added the kind/question Further information is requested label Nov 8, 2024
@skonto
Copy link
Contributor

skonto commented Nov 26, 2024

Hi @helloxjade, the Knative version referenced is not supported by the community any more. Could you try with some later version? I am not sure I understand the steps to reproduce this, could you clarify this?

Btw the error above usually happens when you want to update a knative service that has a user defined name as follows and then you update it but you forget to update the spec.template.metadata.name field as well:

kind: Service
metadata:
  name: helloworld-go
spec:
  template:
    metadata:
      name: helloworld-go-1
      labels:
        app: helloworld-go

If I update the above eg. add a new label test and leave the name as helloworld-go-1 this will fail:

ied the request: validation failed: Saw the following changes without a name change (-old +new): spec.template.metadata.name
{*v1.RevisionTemplateSpec}.ObjectMeta.Labels["test"]:
	+: "test"

The reason is that in the BYO mode revision names are left to the user to be managed (no auto-generation).
Could you verify that the resource is actually new and there are no relics around?

@skonto skonto added the triage/needs-user-input Issues which are waiting on a response from the reporter label Nov 26, 2024
@helloxjade
Copy link
Author

Hi @helloxjade, the Knative version referenced is not supported by the community any more. Could you try with some later version? I am not sure I understand the steps to reproduce this, could you clarify this?

Btw the error above usually happens when you want to update a knative service that has a user defined name as follows and then you update it but you forget to update the spec.template.metadata.name field as well:

kind: Service
metadata:
  name: helloworld-go
spec:
  template:
    metadata:
      name: helloworld-go-1
      labels:
        app: helloworld-go

If I update the above eg. add a new label test and leave the name as helloworld-go-1 this will fail:

ied the request: validation failed: Saw the following changes without a name change (-old +new): spec.template.metadata.name
{*v1.RevisionTemplateSpec}.ObjectMeta.Labels["test"]:
	+: "test"

The reason is that in the BYO mode revision names are left to the user to be managed (no auto-generation). Could you verify that the resource is actually new and there are no relics around?

Here is the error log I'm encountering:

1.7327580730319684e+09  DEBUG   events  Knative service Failed to create :admission webhook "validation.webhook.serving.knative.dev" denied the request: validation failed: Saw the following changes without a name change (-old +new): spec.template.metadata.name
{*v1.RevisionTemplateSpec}.Spec.PodSpec.Containers[0].ReadinessProbe:
        -: "&Probe{ProbeHandler:ProbeHandler{Exec:nil,HTTPGet:nil,TCPSocket:&TCPSocketAction{Port:{0 0 },Host:,},GRPC:nil,},InitialDelaySeconds:0,TimeoutSeconds:0,PeriodSeconds:0,SuccessThreshold:1,FailureThreshold:0,TerminationGracePeriodSeconds:nil,}"
        +: "nil"
{*v1.RevisionTemplateSpec}.Spec.PodSpec.EnableServiceLinks:
        -: "0xc000c648ea"
        +: "<nil>"

@helloxjade
Copy link
Author

helloxjade commented Nov 28, 2024

The issue seems to be related to the logic in the applyDefault function in the revision_defaults.go file. Here’s what happens in the code:

func (rs *RevisionSpec) applyDefault(ctx context.Context, container *corev1.Container, cfg *config.Config) {
	if container.Resources.Requests == nil {
		container.Resources.Requests = corev1.ResourceList{}
	}

	if container.Resources.Limits == nil {
		container.Resources.Limits = corev1.ResourceList{}
	}

	for _, r := range []struct {
		Name    corev1.ResourceName
		Request *resource.Quantity
		Limit   *resource.Quantity
	}{{
		Name:    corev1.ResourceCPU,
		Request: cfg.Defaults.RevisionCPURequest,
		Limit:   cfg.Defaults.RevisionCPULimit,
	}, {
		Name:    corev1.ResourceMemory,
		Request: cfg.Defaults.RevisionMemoryRequest,
		Limit:   cfg.Defaults.RevisionMemoryLimit,
	}, {
		Name:    corev1.ResourceEphemeralStorage,
		Request: cfg.Defaults.RevisionEphemeralStorageRequest,
		Limit:   cfg.Defaults.RevisionEphemeralStorageLimit,
	}} {
		if _, ok := container.Resources.Requests[r.Name]; !ok && r.Request != nil {
			container.Resources.Requests[r.Name] = *r.Request
		}
		if _, ok := container.Resources.Limits[r.Name]; !ok && r.Limit != nil {
			container.Resources.Limits[r.Name] = *r.Limit
		}
	}

	// If there are multiple containers then default probes will be applied to the container where user specified PORT
	// default probes will not be applied for non serving containers
	if len(rs.PodSpec.Containers) == 1 || len(container.Ports) != 0 {
		rs.applyProbes(container)
	}

	if rs.PodSpec.EnableServiceLinks == nil && apis.IsInCreate(ctx) {
		rs.PodSpec.EnableServiceLinks = cfg.Defaults.EnableServiceLinks
	}

	vNames := make(sets.String)
	for _, v := range rs.PodSpec.Volumes {
		if v.EmptyDir != nil || v.PersistentVolumeClaim != nil {
			vNames.Insert(v.Name)
		}
	}
	vms := container.VolumeMounts
	for i := range vms {
		if !vNames.Has(vms[i].Name) {
			vms[i].ReadOnly = true
		}
	}
}

func (*RevisionSpec) applyProbes(container *corev1.Container) {
	if container.ReadinessProbe == nil {
		container.ReadinessProbe = &corev1.Probe{}
	}
	if container.ReadinessProbe.TCPSocket == nil &&
		container.ReadinessProbe.HTTPGet == nil &&
		container.ReadinessProbe.Exec == nil {
		container.ReadinessProbe.TCPSocket = &corev1.TCPSocketAction{}
	}

	if container.ReadinessProbe.SuccessThreshold == 0 {
		container.ReadinessProbe.SuccessThreshold = 1
	}

	// Apply k8s defaults when ReadinessProbe.PeriodSeconds property is set
	if container.ReadinessProbe.PeriodSeconds != 0 {
		if container.ReadinessProbe.FailureThreshold == 0 {
			container.ReadinessProbe.FailureThreshold = 3
		}
		if container.ReadinessProbe.TimeoutSeconds == 0 {
			container.ReadinessProbe.TimeoutSeconds = 1
		}
	}
}`     

```
I don't set the value of ReadinessProbe and EnableServiceLinks when create knative service 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/question Further information is requested triage/needs-user-input Issues which are waiting on a response from the reporter
Projects
None yet
Development

No branches or pull requests

2 participants