-
Notifications
You must be signed in to change notification settings - Fork 40.1k
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
Clients should not check conditions, UpdateStatus() is inconsistent #5738
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project, in which case you'll need to sign a Contributor License Agreement (CLA) at https://cla.developers.google.com/. If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check the information on your CLA or see this help article on setting the email on your git commits. Once you've done that, please reply here to let us know. If you signed the CLA as a corporation, please let us know the company's name. |
The integration test for mirror status pods is failing, waiting for @yujuhong to let this proceed |
ced1119
to
f1d272a
Compare
Thanks for fixing this! I will update once the refactoring is done. |
f1d272a
to
26d4a5d
Compare
As a note on this change - the server must be able to handle all of the errors that are not related to a client object properly querying the server for a request, so that clients in other languages do not also need to add these checks (namespace equality, validation of values, update consistency). Only checks required to build a proper URL (namespace, name, and type) should be checked, and they should be checked consistently. |
26d4a5d
to
54aa5a2
Compare
54aa5a2
to
0f0d93b
Compare
2bf5eef
to
ba1f581
Compare
I looked at the "Clients should not check conditions, UpdateStatus() is inconsistent" commit. LGTM. |
ba1f581
to
a09e4a4
Compare
Rebased |
Thanks, LGTM. |
That's fine - just let me know when you're ready.
|
Pod status update should include the ObjectMeta of the pod. This change is required for kubernetes#5738 to merge.
a09e4a4
to
740a6c7
Compare
Rebased on top of the latest code |
} | ||
// TODO: make me easier to express from client code | ||
// TODO: resource version on a pod should be saved when dealing with mirror pods so that | ||
// subsequent updates don't require a GET. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO can be removed. Mirror pod has already been passed as pod here.
There is also no need to GET pod below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Get is needed - update status should not be calling get (that was removed). You have to Get to get the latest version so you can overwrite.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand what makes mirror pods different from regular pods in this case...
Also, do we always want to overwrite the status even though kubelet was syncing to an older pod spec?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
----- Original Message -----
@@ -104,7 +104,22 @@ func (s *statusManager) SyncBatch() {
podFullName := kubecontainer.GetPodFullName(pod)
status := syncRequest.status
glog.V(3).Infof("Syncing status for %s", podFullName)
&status)_, err := s.kubeClient.Pods(pod.Namespace).UpdateStatus(pod.Name,
+var err error
statusPod := &api.Pod{
ObjectMeta: pod.ObjectMeta,
}
// TODO: make me easier to express from client code
mirror pods so that// TODO: resource version on a pod should be saved when dealing with
// subsequent updates don't require a GET.
I don't quite understand what makes mirror pods different from regular pods
in this case...
Regular pods are getting updates from other sources, so the Kubelet's watch on the master will report changes to them and fill an updated resource version, but it might lag (so the resource version the kubelet knows is less likely to be the most recent version). Mirror pods start from the Kubelet, so the resource version of a mirror pod update is known almost all the time. It's not a huge distinction.
In general, the resource version the kubelet has last seen should be used instead of doing the GET here. Done right, most status updates would be a single operation (a PUT) without conflict. However, if there is a race, the kubelet needs to retry the status update. We've discussed letting the server allow a server-overwrite for certain actions, which would put the logic on the server side, but that isn't implemented. In general, avoiding the GET would be ideal, but I'm not convinced the Kubelet will be the only client that is setting status either (network management plugins?). So we will eventually need to intelligently merge the status on the Kubelet side during an update.
Also, do we always want to overwrite the status even though kubelet was
syncing to an older pod spec?
I'm sure there's some unpleasant race conditions and timing problems here. The Kubelet may wish to delay updating status when its pod spec doesn't match the master's. Also, there is a general problem that a 409 should return the resource as it exists on the server so that a client doesn't need to re-get. That would reduce the complexity for clients that wish to implement overwrite or atomic retry. I have a todo to open an issue on it.
Reply to this email directly or view it on GitHub:
https://github.com/GoogleCloudPlatform/kubernetes/pull/5738/files#r27162095
740a6c7
to
8f3d913
Compare
Corrects some of the cargo culting that has crept into the API.
8f3d913
to
b1ab143
Compare
_, err := s.kubeClient.Pods(pod.Namespace).UpdateStatus(pod.Name, &status) | ||
|
||
var err error | ||
statusPod := &api.Pod{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
statusPod is always overwritten in line 115, what's the point of defining it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There has to be a scope variable for the pod that we read and then write. I'm fine with it being var statusPod *api.Pod
Ok. I think I may have misunderstood your original statement. If we just want to GET the pod from the apiserver before sending the update, there should not be any difference between regular and mirror pods. (and we don't need the actual pod passed the SetPodStatus() at all) |
Correct. But eventually having more info about the Kubelet's view of the world vs the master's would be good. ----- Original Message -----
|
LGTM. shippable is not happy, but tranvis passed. I think it's safe to merge. |
Clients should not check conditions, UpdateStatus() is inconsistent
Pod status update should include the ObjectMeta of the pod. This change is required for kubernetes#5738 to merge.
Corrects some of the cargo culting that has crept into the API.
Fixes some client issues that have crept in over time. Makes UpdateStatus
consistent with its intended use. Makes integration tests have a shorter sync
interval so they can be tested.
@yujuhong please comment here when you have fixed mirror pods status