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

Fix volume remount on reboot #51985

Merged

Conversation

chakri-nelluri
Copy link
Contributor

@chakri-nelluri chakri-nelluri commented Sep 5, 2017

What this PR does / why we need it:
Check the mount is actually attached & mounted before marking actual state of world of Kubelet reconciler.

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes #51982

Special notes for your reviewer:
Added explicit check to make sure volumes are attached and are mounted before marking the state in actual state of world.

Release note:

Fix Flexvolume/FC/ISCSI volumes not being mounted after Node reboot.

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Sep 5, 2017
@k8s-github-robot k8s-github-robot added the do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. label Sep 5, 2017
@chakri-nelluri
Copy link
Contributor Author

/cc @jingxu97 @saad-ali @rootfs

}

var getDeviceMountPathErr error
deviceMountPath, getDeviceMountPathErr = attacher.GetDeviceMountPath(volumeSpec)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For flex volume, what this will return?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It returns the mount path where the volume is expected to be mounted. It is static for a volume.

@mtaufen
Copy link
Contributor

mtaufen commented Sep 6, 2017

/unassign
/assign @jingxu97 @saad-ali

@k8s-ci-robot k8s-ci-robot assigned jingxu97 and saad-ali and unassigned mtaufen Sep 6, 2017
glog.Errorf("Could not mark device is mounted to actual state of world: %v", err)
continue
}
glog.Infof("Volume: %v is mounted", volume.volumeName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can put the check of mountpoint into reconstructVolume function. If it is not a mountpoint, fail to reconstruct volume directly. This way, no need to add deviceMountPath into the reconstructedVolume data structure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it a odd place for doing a mount check? mount check has nothing to do with reconstruction right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason for reconstruction is mainly because when kubelet restarts, we don't have the cached state information. If there are mounts left on the node, we should reconstruct it. But if we checked that the mounts no longer exist, we can ignore it without reconstructing the volume back to actual state, I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. It is infact then "reconstructActualStateofVolume". It would work, the only minor concern is failing reconstruction because a volume is not mounted. Volume is an object and mount is one of the intermediate states of volume. We are combining both.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, the function name is not very clear. I am fine with changing it to reconstuctActualStateofVolume. We have to reconstruct the spec because it is needed in the actual state.

@jingxu97
Copy link
Contributor

@chakri-nelluri After checking the code in other volume plugins for ConstructVolumeSpec, I am thinking we could follow the same way by calling mounter.GetDeviceNameFromMount(), if no device is returned, constructVolumeSpec failed because it shows that the global mount path is no longer here.
Does it make sense?

@chakri-nelluri
Copy link
Contributor Author

chakri-nelluri commented Sep 13, 2017

@jingxu97 IMHO it would make sense for this to be part of the infra, rather than having each plugin do the same logic. Also the constructVolumeSpec by the name goes, it just a helper function to reconstruct the spec. Other plugins, my assumption are working by chance as they require to check the mount to construct the volume spec.

@saad-ali @rootfs @childsb any preference?

@ailusazh
Copy link
Contributor

What about just comment out these lines of the code, as follows:

		//if volume.pluginIsAttachable {
		//	err = rc.actualStateOfWorld.MarkDeviceAsMounted(volume.volumeName)
		//	if err != nil {
		//		glog.Errorf("Could not mark device is mounted to actual state of world: %v", err)
		//		continue
		//	}
		//}

In this way, the reconciler in volumemanager will remount all the attachable volumes. And for the situation of just restart kubelet and didn't reboot the node , when reconciler try to remount, the method MountDevice in attacher and SetUp in mounter will check whether the dir is mounted, if already mounted, they will return nil and the mount volume operation will be succeed.

@dixudx
Copy link
Member

dixudx commented Sep 13, 2017

What about just comment out these lines of the code

@ailusazh They are useful. Just commenting out these lines will not help fix the remount issue, but may bring in other potential ones.

@ailusazh
Copy link
Contributor

chakri-nelluri's fixed way considered more, but this will cause the unmounted volumes reattached, what abount reattach failed?

@ailusazh
Copy link
Contributor

@dixudx, can you think of any specific potential problems?

@msau42
Copy link
Member

msau42 commented Sep 13, 2017

/cc @kubernetes/sig-storage-pr-reviews

@k8s-ci-robot k8s-ci-robot added the sig/storage Categorizes an issue or PR as relevant to SIG Storage. label Sep 13, 2017
@chakri-nelluri
Copy link
Contributor Author

@ailusazh Even, if we just comment out that code, it will not to remount the same volume, as attach & remount are always kicked from the same operation.

The initial PR has a check just about this code block to verify whether the volume was actually mounted or not, before marking it mounted. On @jingxu97 initial feedback, we decided to fail the actual reconstructVolume call, in case a volume is not mounted.

@chakri-nelluri
Copy link
Contributor Author

@ailusazh When attachdetach controller is enabled we would not reattach the volume. When attachdetach controller is disabled, volumes are reattached on node restart, which was always the case. The code does not change the behavior for Kubelet restart.

@jingxu97
Copy link
Contributor

The logic behind reconstructing desired and actual state supposed be to in the following sequence

  1. When controller starts, reconstruct the desired state first by listing all the pods and their volumes.
  2. After desired state is filled, reconstruct volume in actual state only if the volume is not in desired state, because controller might not have enough information to fully reconstruct the actual state. Only if the volume is no longer in desired state, reconstruct with partial information is ok because volume tear down does not really need the full information. The reconstruction process varies with different volume plugins, some might check mount points because they need this information, some don't.

But because of another race condition issue related to node status update, the current code is not really implemented as above design. In the first round of syncState, even if the volume is in desired state, reconciler still tries to reconstruct the actual state with partial information. see code https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/volumemanager/reconciler/reconciler.go#L394

I feel this is not good and cause the issue you are trying to fix here. I am thinking to use a separate cache to represent what is discovered from the disk instead of directly updating the actual state. I need to think through and have a proposal for it.

@chakri-nelluri Your approach checks the global device mount path, but it is also possible that global device path exists, but bind mount is gone, I think. To fully solve this issue, we might also need to check the bind mount.
For now I am ok with your change, just a small comment. Otherwise lgtm. It would be very nice if we could have an e2e test for it.

@@ -462,6 +462,42 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
newMounterErr)
}

deviceMountPath := ""
if attachablePlugin != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment for this part of checking?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also move this part above the defination of volumeMounter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

@ailusazh
Copy link
Contributor

Understand, thank you for your explanation.

@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 21, 2017
@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@k8s-github-robot
Copy link

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions here..

@k8s-github-robot k8s-github-robot merged commit a284c1e into kubernetes:master Sep 21, 2017
chakri-nelluri pushed a commit to diamanticom/kubernetes that referenced this pull request Sep 22, 2017
…reboot-pr

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>..

Fix volume remount on reboot

**What this PR does / why we need it**:
Check the mount is actually attached & mounted before marking actual state of world of Kubelet reconciler.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes kubernetes#51982  

**Special notes for your reviewer**:
Added explicit check to make sure volumes are attached and are mounted before marking the state in actual state of world.

**Release note**:
NONE
@chakri-nelluri
Copy link
Contributor Author

We should cherrypick the fix to 1.6 & 1.7 releases too.

@chakri-nelluri
Copy link
Contributor Author

@jingxu97 @saad-ali Please target it for 1.6 & 1.7 patch releases too. Thanks.

@saad-ali saad-ali modified the milestones: v1.8, v1.7 Sep 29, 2017
@saad-ali
Copy link
Member

Marked as 1.7 cherry pick candidate. Once that's done we can do the same for 1.6

@saad-ali
Copy link
Member

CC @wojtek-t, 1.7.x release manager for approval

@wojtek-t
Copy link
Member

wojtek-t commented Oct 3, 2017

Cherrypick approved - cherrypick in #53368

@wojtek-t wojtek-t added the cherry-pick-approved Indicates a cherry-pick PR into a release branch has been approved by the release branch manager. label Oct 3, 2017
k8s-github-robot pushed a commit that referenced this pull request Oct 9, 2017
…85-upstream-release-1.7

Automatic merge from submit-queue.

Automated cherry pick of #51985 upstream release 1.7 

Cherry pick of #51985 on release-1.7.

#51985: Fix volume remount on reboot
@k8s-cherrypick-bot
Copy link

Commit found in the "release-1.7" branch appears to be this PR. Removing the "cherrypick-candidate" label. If this is an error find help to get your PR picked.

@saad-ali saad-ali removed the cherry-pick-approved Indicates a cherry-pick PR into a release branch has been approved by the release branch manager. label Oct 16, 2017
@saad-ali saad-ali modified the milestones: v1.7, v1.6 Oct 16, 2017
@saad-ali
Copy link
Member

Marked as 1.6 cherry pick candidate.

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-none Denotes a PR that doesn't merit a release note. labels Oct 30, 2017
k8s-github-robot pushed a commit that referenced this pull request Nov 1, 2017
…f-#51985-upstream-release-1.6

Automatic merge from submit-queue.

Automated cherry pick of #51985

Cherry pick of #51985 on release-1.6.

#51985: Fix volume remount on reboot
@k8s-cherrypick-bot
Copy link

Commit found in the "release-1.6" branch appears to be this PR. Removing the "cherrypick-candidate" label. If this is an error find help to get your PR picked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/storage Categorizes an issue or PR as relevant to SIG Storage. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Volumes are not mounted after rebooting a node. (Effects Flexvolume/FC/ISCSI)