Skip to content

Commit 0086d5a

Browse files
Attach creation of Pseudo PV to the PVC instead of the pods (#577)
* Change creation of pseudo PV to PVC instead of pods Signed-off-by: galal-hussein <[email protected]> * Ignore not found pvs when deleting the pvc Signed-off-by: galal-hussein <[email protected]> * fixes Signed-off-by: galal-hussein <[email protected]> * Avoid returning when the PV already exists Signed-off-by: galal-hussein <[email protected]> --------- Signed-off-by: galal-hussein <[email protected]>
1 parent c9bb1bc commit 0086d5a

File tree

4 files changed

+102
-223
lines changed

4 files changed

+102
-223
lines changed

k3k-kubelet/controller/syncer/persistentvolumeclaims.go

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import (
55

66
"k8s.io/apimachinery/pkg/labels"
77
"k8s.io/apimachinery/pkg/types"
8+
"k8s.io/component-helpers/storage/volume"
89
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
910
"sigs.k8s.io/controller-runtime/pkg/manager"
1011
"sigs.k8s.io/controller-runtime/pkg/predicate"
1112
"sigs.k8s.io/controller-runtime/pkg/reconcile"
1213

1314
v1 "k8s.io/api/core/v1"
1415
apierrors "k8s.io/apimachinery/pkg/api/errors"
16+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1517
ctrl "sigs.k8s.io/controller-runtime"
1618
ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client"
1719

@@ -22,6 +24,7 @@ import (
2224
const (
2325
pvcControllerName = "pvc-syncer-controller"
2426
pvcFinalizerName = "pvc.k3k.io/finalizer"
27+
pseudoPVLabel = "pod.k3k.io/pseudoPV"
2528
)
2629

2730
type PVCReconciler struct {
@@ -105,6 +108,12 @@ func (r *PVCReconciler) Reconcile(ctx context.Context, req reconcile.Request) (r
105108
if err := r.HostClient.Delete(ctx, syncedPVC); err != nil && !apierrors.IsNotFound(err) {
106109
return reconcile.Result{}, err
107110
}
111+
112+
// delete the synced virtual PV
113+
if err := r.VirtualClient.Delete(ctx, newPersistentVolume(&virtPVC)); err != nil && !apierrors.IsNotFound(err) {
114+
return reconcile.Result{}, err
115+
}
116+
108117
// remove the finalizer after cleaning up the synced pvc
109118
if controllerutil.RemoveFinalizer(&virtPVC, pvcFinalizerName) {
110119
if err := r.VirtualClient.Update(ctx, &virtPVC); err != nil {
@@ -127,7 +136,13 @@ func (r *PVCReconciler) Reconcile(ctx context.Context, req reconcile.Request) (r
127136

128137
// note that we dont need to update the PVC on the host cluster, only syncing the PVC to allow being
129138
// handled by the host cluster.
130-
return reconcile.Result{}, ctrlruntimeclient.IgnoreAlreadyExists(r.HostClient.Create(ctx, syncedPVC))
139+
if err := r.HostClient.Create(ctx, syncedPVC); err != nil && !apierrors.IsAlreadyExists(err) {
140+
return reconcile.Result{}, err
141+
}
142+
143+
// Creating a virtual PV to bound the existing PVC in the virtual cluster - needed for scheduling of
144+
// the consumer pods
145+
return reconcile.Result{}, r.createVirtualPersistentVolume(ctx, virtPVC)
131146
}
132147

133148
func (r *PVCReconciler) pvc(obj *v1.PersistentVolumeClaim) *v1.PersistentVolumeClaim {
@@ -136,3 +151,82 @@ func (r *PVCReconciler) pvc(obj *v1.PersistentVolumeClaim) *v1.PersistentVolumeC
136151

137152
return hostPVC
138153
}
154+
155+
func (r *PVCReconciler) createVirtualPersistentVolume(ctx context.Context, pvc v1.PersistentVolumeClaim) error {
156+
log := ctrl.LoggerFrom(ctx)
157+
log.V(1).Info("Creating virtual PersistentVolume")
158+
159+
pv := newPersistentVolume(&pvc)
160+
161+
if err := r.VirtualClient.Create(ctx, pv); err != nil && !apierrors.IsAlreadyExists(err) {
162+
return err
163+
}
164+
165+
orig := pv.DeepCopy()
166+
pv.Status = v1.PersistentVolumeStatus{
167+
Phase: v1.VolumeBound,
168+
}
169+
170+
if err := r.VirtualClient.Status().Patch(ctx, pv, ctrlruntimeclient.MergeFrom(orig)); err != nil {
171+
return err
172+
}
173+
174+
log.V(1).Info("Patch the status of PersistentVolumeClaim to Bound")
175+
176+
pvcPatch := pvc.DeepCopy()
177+
if pvcPatch.Annotations == nil {
178+
pvcPatch.Annotations = make(map[string]string)
179+
}
180+
181+
pvcPatch.Annotations[volume.AnnBoundByController] = "yes"
182+
pvcPatch.Annotations[volume.AnnBindCompleted] = "yes"
183+
pvcPatch.Status.Phase = v1.ClaimBound
184+
pvcPatch.Status.AccessModes = pvcPatch.Spec.AccessModes
185+
186+
return r.VirtualClient.Status().Update(ctx, pvcPatch)
187+
}
188+
189+
func newPersistentVolume(obj *v1.PersistentVolumeClaim) *v1.PersistentVolume {
190+
var storageClass string
191+
192+
if obj.Spec.StorageClassName != nil {
193+
storageClass = *obj.Spec.StorageClassName
194+
}
195+
196+
return &v1.PersistentVolume{
197+
ObjectMeta: metav1.ObjectMeta{
198+
Name: obj.Name,
199+
Labels: map[string]string{
200+
pseudoPVLabel: "true",
201+
},
202+
Annotations: map[string]string{
203+
volume.AnnBoundByController: "true",
204+
volume.AnnDynamicallyProvisioned: "k3k-kubelet",
205+
},
206+
},
207+
TypeMeta: metav1.TypeMeta{
208+
Kind: "PersistentVolume",
209+
APIVersion: "v1",
210+
},
211+
Spec: v1.PersistentVolumeSpec{
212+
PersistentVolumeSource: v1.PersistentVolumeSource{
213+
FlexVolume: &v1.FlexPersistentVolumeSource{
214+
Driver: "pseudopv",
215+
},
216+
},
217+
StorageClassName: storageClass,
218+
VolumeMode: obj.Spec.VolumeMode,
219+
PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete,
220+
AccessModes: obj.Spec.AccessModes,
221+
Capacity: obj.Spec.Resources.Requests,
222+
ClaimRef: &v1.ObjectReference{
223+
APIVersion: obj.APIVersion,
224+
UID: obj.UID,
225+
ResourceVersion: obj.ResourceVersion,
226+
Kind: obj.Kind,
227+
Namespace: obj.Namespace,
228+
Name: obj.Name,
229+
},
230+
},
231+
}
232+
}

k3k-kubelet/controller/syncer/persistentvolumeclaims_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ var PVCTests = func() {
5555
Expect(err).NotTo(HaveOccurred())
5656
})
5757

58-
It("creates a pvc on the host cluster", func() {
58+
It("creates a pvc on the host cluster and virtual pv in virtual cluster", func() {
5959
ctx := context.Background()
6060

6161
pvc := &v1.PersistentVolumeClaim{
@@ -100,5 +100,11 @@ var PVCTests = func() {
100100
Expect(*hostPVC.Spec.StorageClassName).To(Equal("test-sc"))
101101

102102
GinkgoWriter.Printf("labels: %v\n", hostPVC.Labels)
103+
104+
var virtualPV v1.PersistentVolume
105+
key := client.ObjectKey{Name: pvc.Name}
106+
107+
err = virtTestEnv.k8sClient.Get(ctx, key, &virtualPV)
108+
Expect(err).NotTo(HaveOccurred())
103109
})
104110
}

k3k-kubelet/controller/syncer/pod.go

Lines changed: 0 additions & 215 deletions
This file was deleted.

k3k-kubelet/kubelet.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -458,12 +458,6 @@ func addControllers(ctx context.Context, hostMgr, virtualMgr manager.Manager, c
458458
return errors.New("failed to add pvc syncer controller: " + err.Error())
459459
}
460460

461-
logger.Info("adding pod pvc controller")
462-
463-
if err := syncer.AddPodPVCController(ctx, virtualMgr, hostMgr, c.ClusterName, c.ClusterNamespace); err != nil {
464-
return errors.New("failed to add pod pvc controller: " + err.Error())
465-
}
466-
467461
logger.Info("adding priorityclass controller")
468462

469463
if err := syncer.AddPriorityClassSyncer(ctx, virtualMgr, hostMgr, c.ClusterName, c.ClusterNamespace); err != nil {

0 commit comments

Comments
 (0)