Change workload controller to use patch instead of update#286
Conversation
ec2f55d to
a05becd
Compare
a05becd to
41ab580
Compare
41ab580 to
c908c62
Compare
c908c62 to
ab5b7be
Compare
|
@PersistentJZH can you attend the community meeting this Thursday ? |
sure, will attend meeting. |
Signed-off-by: zhihao jian <zhihao.jian@shopee.com> fix test use MergeFrom func to patch data get latest rs fix unit test fix lint do not get latest status before patch
ed7e44b to
51cebc1
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #286 +/- ##
==========================================
+ Coverage 45.22% 45.68% +0.45%
==========================================
Files 61 61
Lines 7073 7083 +10
==========================================
+ Hits 3199 3236 +37
+ Misses 3324 3291 -33
- Partials 550 556 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
pkg/controller/deployment/sync.go
Outdated
| rsCopy.Spec.MinReadySeconds = d.Spec.MinReadySeconds | ||
| return dc.client.AppsV1().ReplicaSets(rsCopy.ObjectMeta.Namespace).Update(ctx, rsCopy, metav1.UpdateOptions{}) | ||
| // Use existing state directly for patching, let API Server handle conflicts | ||
| rsCopy = existingNewRS.DeepCopy() |
There was a problem hiding this comment.
shall we deepcopy and change the replicaset again ? it seems that L114-L119 already did these things
pkg/controller/deployment/sync.go
Outdated
| // Set the annotations that need to be updated | ||
| desiredReplicas := *(deployment.Spec.Replicas) | ||
| maxReplicas := *(deployment.Spec.Replicas) + deploymentutil.MaxSurge(deployment, &dc.strategy) | ||
| deploymentutil.SetReplicasAnnotations(rsCopy, desiredReplicas, maxReplicas) |
There was a problem hiding this comment.
is it possible to keep the code of L414-L416 as much as possible?
There was a problem hiding this comment.
sure, I have made corresponding adjustments.
6902031 to
ef47137
Compare
|
thanks @furykerry, according to the weekly meeting discussion, this PR made two adjustments:
|
|
|
||
| // List all ReplicaSets using runtimeClient | ||
| rsList := &apps.ReplicaSetList{} | ||
| err = dc.runtimeClient.List(ctx, rsList, client.InNamespace(d.Namespace), client.MatchingLabelsSelector{Selector: deploymentSelector}) |
There was a problem hiding this comment.
is it possible to list with UnsafeDisableDeepCopy option
There was a problem hiding this comment.
ok, will use UnsafeDisableDeepCopy to optimize performance.
| rolloutsv1alpha1.DeploymentExtraStatusAnnotation, | ||
| strings.Replace(extraStatusAnno, `"`, `\"`, -1)) | ||
| // Create a patch for the annotation | ||
| patch := client.MergeFrom(deployment.DeepCopy()) |
There was a problem hiding this comment.
is it necessary to deepcopy the deployment here ?
There was a problem hiding this comment.
yes, the deepCopy here is necessary.
Reasons:
- client.MergeFrom() requires a copy of the original state to calculate differences
- the MergeFrom() implementation doesn't perform DeepCopy - it just stores a reference to the provided object
There was a problem hiding this comment.
extra option (OptimisticLock) is required to enable patch that contains the resource version sigs.k8s.io/controller-runtimepkg/client/patch.go, and when OptimisticLock is set, deepcopy is used automatically during the Data() func of mergeFromPatch.
There was a problem hiding this comment.
yes, it seems that all patch operations need to turn on OptimisticLock right?
There was a problem hiding this comment.
yes, at least for the patch operation that is supposed to replace the original update operation
There was a problem hiding this comment.
thanks @furykerry, here are two points that need your attention:
-
client.MergeFromWithOptions() with MergeFromWithOptimisticLock also requires deepcopy. For details, see the implementation of mergeFromPatch sig.k8s.io/controller-runtime impl. Because deployment is a pointer type, the two objects here are the same, which will cause the patch to not take effect. I verified this in the local kind environment.
-
need to get the latest deployment here, because the previous step (probably here) always updates the condition lastTransitionTime and lastUpdateTime field of the deployment in one reconcile round, causing the resourceVersion to change, which will cause the patch extra status to fail (it will only fail in the last step of canary).
There was a problem hiding this comment.
need to get the latest deployment here, because the previous step (probably here) always updates the condition lastTransitionTime and lastUpdateTime field of the deployment in one reconcile round, causing the resourceVersion to change, which will cause the patch extra status to fail (it will only fail in the last step of canary).
thanks for your test, can you comment in the code why the latest deployment should be fetched? it is rather counter-intuitive.
6b51ecc to
c46aa99
Compare
Signed-off-by: zhihao jian <zhihao.jian@shopee.com> remove dupl SetNewReplicaSetAnnotations use UnsafeDisableDeepCopy to optimize performance use optimisticLock for patch fix patch extra status always failed fix unit test
c46aa99 to
20bc6e9
Compare
Signed-off-by: zhihao jian <zhihao.jian@shopee.com> remove dupl SetNewReplicaSetAnnotations use UnsafeDisableDeepCopy to optimize performance use optimisticLock for patch fix patch extra status always failed fix unit test add comment
20bc6e9 to
884be19
Compare
| // The deployment passed in here has an old resourceVersion, so we need to fetch the latest deployment | ||
| // to ensure patch success. | ||
| latestDeployment := &apps.Deployment{} | ||
| err := dc.runtimeClient.Get(context.TODO(), client.ObjectKeyFromObject(deployment), latestDeployment) |
There was a problem hiding this comment.
the runtimeClient here may read the cached deployment not the latest deployment. a better solution is to comine the patchExtraStatus func with syncDeploymentStatus, so that only one patch is required. Actually when update status of deployment, annotation can also be updated .
Signed-off-by: zhihao jian <zhihao.jian@shopee.com>
…tead-of-update' of github.com:PersistentJZH/rollouts into zhihao/feat/change-workload-controller-to-use-patch-instead-of-update # Conflicts: # pkg/controller/deployment/deployment_controller.go # pkg/controller/deployment/progress.go # pkg/controller/deployment/sync.go
|
@PersistentJZH Can dingding qun communicate? |
|
/lgtm |
…use-patch-instead-of-update
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: furykerry The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Ⅰ. Describe what this PR does
change workload controller to use patch instead of update
Ⅱ. Does this pull request fix one issue?
#273
Ⅲ. Special notes for reviews