Skip to content

Best practices for updating a CRD's spec #1128

@dprotaso

Description

@dprotaso

Once we transition to k8s 1.11 and merge the subresources PR #786 we need some best practices around updating the CRD spec.

The code below is problematic as it may trigger a generation bump when it doesn't need to

func (c *Controller) updateService(service *v1alpha1.Service) (*v1alpha1.Service, error) {
	serviceClient := c.ElaClientSet.ServingV1alpha1().Services(service.Namespace)
	existing, _ := serviceClient.Get(service.Name, metav1.GetOptions{})

	// Check if there is anything to update.
	if !reflect.DeepEqual(existing.Spec, service.Spec) {
		return serviceClient.Update(existing)
	}
	return existing, nil
}

Triggering a generation bump becomes inherently expensive for certain CRDs. For a Configuration this will trigger a new revision and it's subsequent pods, services etc. to be created.

Whether a generation bump occurs will depend on the CRD definition. In our case it's very likely as we have nested kubernetes core types which although maybe be semantically equivalent will not be considered equal when using reflect.DeepEqual

An approach to resolve this is to use k8s apimachinery pkg/api/equality for comparison when updating our CRD's spec

A second approach is to utilize the clientset's patch

Related:
Best practices for updating [CRD] status (#1107)
Best practices for updating a CRD's metadata (#1127)

Metadata

Metadata

Assignees

Labels

area/APIAPI objects and controllerskind/cleanupCategorizes issue or PR as related to cleaning up code, process, or technical debt.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions