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

Add aws-s3-csi-controller component #299

Merged
merged 15 commits into from
Dec 16, 2024
Merged

Conversation

unexge
Copy link
Contributor

@unexge unexge commented Nov 22, 2024

This is part of #279.

This new component, aws-s3-csi-controller, will be the entry point for our controller component. It's using controller-runtime, specifically, it implements Reconciler interface to reconcile Pods in the cluster. It schedules Mountpoint Pods in turn to cluster events such as a new workload Pod using a PV backed by S3 CSI Driver getting scheduled into the cluster. It'd then schedule a Mountpoint Pod for that workload Pod in the same node to provide volume for that Pod.

#279 is still WIP and this component contains some TODOs and it's not in use anywhere except in tests at the moment.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Makefile Outdated Show resolved Hide resolved
log.V(debugLevel).Info("Pod pending to be scheduled")
case corev1.PodRunning:
log.V(debugLevel).Info("Pod is running")
case corev1.PodSucceeded:
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to verify that MP exists with an error exit code on all crashes. I'm not sure it does right now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, depending on Mountpoint's exit code, non-zero for failures and zero for success, Mountpoint Pod will either restart (due to RestartPolicy: corev1.RestartPolicyOnFailure) or transition into PodSucceeded state respectively. This part deletes PodSucceeded Mountpoint Pods.

Copy link
Contributor

Choose a reason for hiding this comment

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

I know, we just need to ensure that Mountpoint exists with non-zero exit codes on failure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've manually verified while testing Mountpoint with incorrect credentials that this is the case. I think we also have some end-to-end tests where it tests failed mount, but I'm not sure if we also want to have a specific test case for exit code.

)

func TestGeneratingMountpointPodName(t *testing.T) {
t.Run("Consistency", func(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

These tests seem like they'd be better by being property based tests

pkg/podmounter/mppod/path.go Show resolved Hide resolved

expectNoMountpointPodFor(pod, vol)

vol.bind()
Copy link
Contributor

Choose a reason for hiding this comment

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

Semantically, what does this mean in terms of k8s runtime? Where the binding isn't explicit in the PV, but gets bound at pod schedule time?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is actually the default behavior if you don't pre-bind your PVC and PV. You specify a PVC in your Pod with some capacity, and once your Pod scheduled, Kubernetes tries to bind a PV for your PVC that fulfills your capacity requests. In case of static provisioning, cluster admin must pre-provision PVs for this to work, in case of dynamic provisioning another controller like external-provisioner sees that and dynamically creates a PV and binds that to that PVC. See for more detail https://kubernetes.io/docs/concepts/storage/persistent-volumes/#binding

tests/controller/controller_test.go Show resolved Hide resolved

var _ = Describe("Mountpoint Controller", func() {
Context("Static Provisioning", func() {
Context("Scheduled Pod with pre-bound PV and PVC", func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we effectively testing that if there's a volume with the S3 CSI Driver, and it is bound to a pod that is scheduled, waitAndVerifyMountpointPodFor, otherwise, expectNoMountpointPodFor?

Copy link
Contributor

Choose a reason for hiding this comment

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

If so, then a property based test using a state machine might be useful here to ensure all combinations are reached

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, those are the expectations we assert during the tests. I think we can look into using property tests, but I think I'd also like to keep these known/expected cases here

@unexge unexge force-pushed the unexge/podmounter-controller branch from 6fed7e3 to 0d2c5cb Compare December 10, 2024 11:28
@unexge unexge requested a review from muddyfish December 10, 2024 11:30

log.V(debugLevel).Info("Found bound PV for PVC", "pvc", pvc.Name, "volumeName", pv.Name)

err = r.spawnOrDeleteMountpointPodIfNeeded(ctx, pod, pvc, pv, csiSpec)
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be called multiple times for the same volume. I don't think this is a problem though, but is it worth migrating this outside the for loop and only calling if we have no requeue and no errors? That way we could call in parallel for each PVC, but that might just be premature optimisation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I'd like this to be called even some other volume for this Pod requires requeueing, so one poisonous volume won't block other volumes to progress. Yeah, I think calling this in parallel would be a pre-mature optimization and would also be problematic if we want to share Mountpoint instances between multiple volumes. They would be racing to spawn Mountpoint Pods and that might cause duplicate Pods.

@unexge unexge force-pushed the unexge/podmounter-controller branch from 0d2c5cb to 77c6842 Compare December 11, 2024 16:17
Signed-off-by: Burak Varlı <[email protected]>
@unexge unexge force-pushed the unexge/podmounter-controller branch from 77c6842 to 5303a67 Compare December 16, 2024 13:25
Copy link
Contributor

@muddyfish muddyfish left a comment

Choose a reason for hiding this comment

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

Taken notes for non-blocking things we still want to do, good to merge

@unexge unexge merged commit 0f2689b into main Dec 16, 2024
21 checks passed
@unexge unexge deleted the unexge/podmounter-controller branch December 16, 2024 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants