-
Notifications
You must be signed in to change notification settings - Fork 28.9k
[SPARK-22953][K8S] Avoids adding duplicated secret volumes when init-container is used #20148
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
Conversation
…container is used
| * | ||
| * @param pod the pod into which the secret volumes are being added. | ||
| * @param container the container into which the secret volumes are being mounted. | ||
| * @param addNewVolumes whether to add new secret volumes for the secrets. |
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 think this problem arose because we're conflating two things here - adding secret volumes (which are pod-scoped) and adding volume-mounts (which are container-scoped). I think we should separate these out. The branching may work for now, but we should have a future work item to separate these out.
cc/ @mccheah
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.
Agreed. I didn't separate it out because we will touch this code as part of refactoring the steps code anyway as planned in https://issues.apache.org/jira/browse/SPARK-22839.
|
Test build #85664 has finished for PR 20148 at commit
|
| * @return the updated pod and container with the secrets mounted. | ||
| */ | ||
| def mountSecrets(pod: Pod, container: Container): (Pod, Container) = { | ||
| def mountSecrets( |
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.
Can we separate this method into addSecretVolumes and mountSecrets? The former would just need the pod argument, and the latter would take the container as argument. That way, we could probably separate this out better and it would make it more readable than the branching. WDYT?
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.
Good point. Done.
| === "secret1-volume") | ||
| assert(executor.getSpec.getInitContainers.get(0).getVolumeMounts.get(0) | ||
| .getMountPath === "/var/secret1") | ||
| assert(SecretVolumeUtils.containerHasVolume( |
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.
It might be better to change None at line 168 to Some(secretBootstrap) and check volumes' number to avoid regression.
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.
Done.
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.
Thanks! We also need check volumes' num in pod spec.
// check volume mounted.
assert(executor.getSpec.getVolumes.size() === 1)
assert(executor.getSpec.getVolumes.get(0).getSecret.getSecretName === "secret1")
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.
Done. 93e1d64.
|
Test build #85667 has finished for PR 20148 at commit
|
|
Test build #85668 has finished for PR 20148 at commit
|
|
Test build #85669 has finished for PR 20148 at commit
|
|
LGTM, please also update the PR description. |
|
@jiangxb1987 Updated PR description. |
| def podHasVolume(driverPod: Pod, volumeName: String): Boolean = { | ||
| driverPod.getSpec.getVolumes.asScala.exists(volume => volume.getName == volumeName) | ||
| def podHasVolume(pod: Pod, volumeName: String): Boolean = { | ||
| pod.getSpec.getVolumes.asScala.exists(volume => volume.getName == volumeName) |
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.
Since you're touching this, the style is always .exists { foo => ... }.
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.
Done.
| mountPath: String): Boolean = { | ||
| driverContainer.getVolumeMounts.asScala.exists(volumeMount => | ||
| def containerHasVolume(container: Container, volumeName: String, mountPath: String): Boolean = { | ||
| container.getVolumeMounts.asScala.exists(volumeMount => |
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.
Same 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.
Done.
|
Test build #85690 has finished for PR 20148 at commit
|
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.
A note on this change: it seems double quotes get literally added. With the double quotes appended explicitly here, when running SparkPi with an argument 5, an NumberFormatException will be thrown complaining that ""5"" is not parsable. So the explicit double quotes are not really needed.
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.
Thanks for calling this out - let's try and test this using an integration test as well in https://github.com/apache-spark-on-k8s/spark-integration/. Would be good to put in manual integration testing results here until we have the PRB automation figured out.
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.
Sure, I will add one to the PR under review.
|
Test build #85693 has finished for PR 20148 at commit
|
|
Test build #85694 has finished for PR 20148 at commit
|
|
Test build #85695 has finished for PR 20148 at commit
|
|
@vanzin Can this be merged? |
|
Merging to master / 2.3. |
|
Actually no. Please open the PR against master instead. |
|
Why master? |
|
Because all changes go to master first. |
…container is used ## What changes were proposed in this pull request? User-specified secrets are mounted into both the main container and init-container (when it is used) in a Spark driver/executor pod, using the `MountSecretsBootstrap`. Because `MountSecretsBootstrap` always adds new secret volumes for the secrets to the pod, the same secret volumes get added twice, one when mounting the secrets to the main container, and the other when mounting the secrets to the init-container. This PR fixes the issue by separating `MountSecretsBootstrap.mountSecrets` out into two methods: `addSecretVolumes` for adding secret volumes to a pod and `mountSecrets` for mounting secret volumes to a container, respectively. `addSecretVolumes` is only called once for each pod, whereas `mountSecrets` is called individually for the main container and the init-container (if it is used). Ref: apache-spark-on-k8s#594. ## How was this patch tested? Unit tested and manually tested. vanzin This replaces #20148. hex108 foxish kimoonkim Author: Yinan Li <[email protected]> Closes #20159 from liyinan926/master. (cherry picked from commit e288fc8) Signed-off-by: Marcelo Vanzin <[email protected]>
…container is used ## What changes were proposed in this pull request? User-specified secrets are mounted into both the main container and init-container (when it is used) in a Spark driver/executor pod, using the `MountSecretsBootstrap`. Because `MountSecretsBootstrap` always adds new secret volumes for the secrets to the pod, the same secret volumes get added twice, one when mounting the secrets to the main container, and the other when mounting the secrets to the init-container. This PR fixes the issue by separating `MountSecretsBootstrap.mountSecrets` out into two methods: `addSecretVolumes` for adding secret volumes to a pod and `mountSecrets` for mounting secret volumes to a container, respectively. `addSecretVolumes` is only called once for each pod, whereas `mountSecrets` is called individually for the main container and the init-container (if it is used). Ref: apache-spark-on-k8s#594. ## How was this patch tested? Unit tested and manually tested. vanzin This replaces #20148. hex108 foxish kimoonkim Author: Yinan Li <[email protected]> Closes #20159 from liyinan926/master.
…597) * Avoids adding duplicated secret volumes when init-container is used Cherry-picked from apache#20148. * Added the missing commit from upstream
What changes were proposed in this pull request?
User-specified secrets are mounted into both the main container and init-container (when it is used) in a Spark driver/executor pod, using the
MountSecretsBootstrap. BecauseMountSecretsBootstrapalways adds new secret volumes for the secrets to the pod, the same secret volumes get added twice, one when mounting the secrets to the main container, and the other when mounting the secrets to the init-container. This PR fixes the issue by separatingMountSecretsBootstrap.mountSecretsout into two methods:addSecretVolumesfor adding secret volumes to a pod andmountSecretsfor mounting secret volumes to a container, respectively.addSecretVolumesis only called once for each pod, whereasmountSecretsis called individually for the main container and the init-container (if it is used).Ref: apache-spark-on-k8s#594.
How was this patch tested?
Unit tested.
@vanzin @jiangxb1987 @ueshin This is to fix a critical bug in 2.3. PTAL. Thanks!
@hex108 @foxish @kimoonkim