Skip to content

Commit 5284147

Browse files
claudioloradamjensenbot
authored andcommitted
fix: bug causing the virtual kubelet not to be deleted on unpeer
This patch fixes a bug that caused the VirtualKubelet not to be deleted when the Node resource was missing. The deletion routine now always removes the VK deployment and double checks whether there are Node resources to delete them. Additionally a check on the VK arguments on deletion has been removed, as when the deployment is deleted we make sure that there are no more pods running of that deployment, only once the deployment is deleted the Node is deleted, so there is no risk of a VK pod to recreate the node after its deletion.
1 parent d03e24a commit 5284147

File tree

2 files changed

+43
-67
lines changed

2 files changed

+43
-67
lines changed

pkg/liqo-controller-manager/offloading/virtualnode-controller/deletion-routine.go

+43-36
Original file line numberDiff line numberDiff line change
@@ -137,33 +137,11 @@ func (dr *DeletionRoutine) handle(ctx context.Context, key string) (err error) {
137137
Status: offloadingv1beta1.DrainingConditionStatusType,
138138
}})
139139

140-
var node *corev1.Node
141-
node, err = getters.GetNodeFromVirtualNode(ctx, dr.vnr.Client, vn)
142-
if client.IgnoreNotFound(err) != nil {
143-
err = fmt.Errorf("error getting node: %w", err)
140+
if err = dr.deleteVirtualKubelet(ctx, vn); err != nil {
141+
err = fmt.Errorf("error deleting node and Virtual Kubelet: %w", err)
144142
return err
145143
}
146144

147-
if node != nil {
148-
if !*vn.Spec.CreateNode {
149-
// We need to ensure that the current pods will no recreate the node after deleting it.
150-
var found bool
151-
if found, err = vkutils.CheckVirtualKubeletFlagsConsistence(
152-
ctx, dr.vnr.Client, vn, createNodeFalseFlag); err != nil || !found {
153-
if err == nil {
154-
err = fmt.Errorf("virtual kubelet pods are still running with arg %s", createNodeFalseFlag.String())
155-
return err
156-
}
157-
err = fmt.Errorf("error checking virtual kubelet pods: %w", err)
158-
return err
159-
}
160-
}
161-
if err = dr.deleteNode(ctx, node, vn); err != nil {
162-
err = fmt.Errorf("error deleting node: %w", err)
163-
return err
164-
}
165-
}
166-
167145
if !vn.DeletionTimestamp.IsZero() {
168146
// VirtualNode resource is being deleted.
169147
if err = dr.vnr.ensureNamespaceMapAbsence(ctx, vn); err != nil {
@@ -188,19 +166,28 @@ func (dr *DeletionRoutine) handle(ctx context.Context, key string) (err error) {
188166
return nil
189167
}
190168

191-
// deleteNode deletes the Node created by VirtualNode.
192-
func (dr *DeletionRoutine) deleteNode(ctx context.Context, node *corev1.Node, vn *offloadingv1beta1.VirtualNode) error {
193-
if err := cordonNode(ctx, dr.vnr.Client, node); err != nil {
194-
return fmt.Errorf("error cordoning node: %w", err)
169+
// deleteVirtualKubelet deletes the Node and the VirtualKubelet deployment related to the given VirtualNode.
170+
func (dr *DeletionRoutine) deleteVirtualKubelet(ctx context.Context, vn *offloadingv1beta1.VirtualNode) error {
171+
// Check if the Node resource exists to make sure that we are not in a case in which it should not exist.
172+
node, err := getters.GetNodeFromVirtualNode(ctx, dr.vnr.Client, vn)
173+
if client.IgnoreNotFound(err) != nil {
174+
err = fmt.Errorf("error getting node: %w", err)
175+
return err
195176
}
196177

197-
klog.Infof("Node %s cordoned", node.Name)
178+
if node != nil {
179+
if err := cordonNode(ctx, dr.vnr.Client, node); err != nil {
180+
return fmt.Errorf("error cordoning node: %w", err)
181+
}
198182

199-
if err := client.IgnoreNotFound(drainNode(ctx, dr.vnr.Client, vn)); err != nil {
200-
return fmt.Errorf("error draining node: %w", err)
201-
}
183+
klog.Infof("Node %s cordoned", node.Name)
202184

203-
klog.Infof("Node %s drained", node.Name)
185+
if err := client.IgnoreNotFound(drainNode(ctx, dr.vnr.Client, vn)); err != nil {
186+
return fmt.Errorf("error draining node: %w", err)
187+
}
188+
189+
klog.Infof("Node %s drained", node.Name)
190+
}
204191

205192
if !vn.DeletionTimestamp.IsZero() {
206193
ForgeCondition(vn,
@@ -214,18 +201,38 @@ func (dr *DeletionRoutine) deleteNode(ctx context.Context, node *corev1.Node, vn
214201
return fmt.Errorf("error deleting virtual kubelet deployment: %w", err)
215202
}
216203
}
204+
205+
// Even node is nil we make sure that no Node resource has been created before the deletion of the VK deployment.
217206
klog.Infof("VirtualKubelet deployment %s deleted", vn.Name)
218207

208+
var nodeToDelete *corev1.Node
209+
210+
if node != nil {
211+
nodeToDelete = node
212+
} else {
213+
nodeToDelete, err = getters.GetNodeFromVirtualNode(ctx, dr.vnr.Client, vn)
214+
if client.IgnoreNotFound(err) != nil {
215+
err = fmt.Errorf("error getting node before deletion: %w", err)
216+
return err
217+
}
218+
}
219+
219220
ForgeCondition(vn,
220221
VnConditionMap{
221222
offloadingv1beta1.NodeConditionType: VnCondition{
222223
Status: offloadingv1beta1.DeletingConditionStatusType,
223224
},
224225
})
225-
if err := client.IgnoreNotFound(dr.vnr.Client.Delete(ctx, node, &client.DeleteOptions{})); err != nil {
226-
return fmt.Errorf("error deleting node: %w", err)
226+
227+
if nodeToDelete != nil {
228+
if err := client.IgnoreNotFound(dr.vnr.Client.Delete(ctx, nodeToDelete, &client.DeleteOptions{})); err != nil {
229+
return fmt.Errorf("error deleting node: %w", err)
230+
}
231+
232+
klog.Infof("Node %s deleted", node.Name)
233+
} else {
234+
klog.Infof("Node of VirtualNode %s already deleted", vn.Name)
227235
}
228236

229-
klog.Infof("Node %s deleted", node.Name)
230237
return nil
231238
}

pkg/vkMachinery/utils/utils.go

-31
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,13 @@ package utils
1717
import (
1818
"context"
1919
"fmt"
20-
"strings"
2120

2221
appsv1 "k8s.io/api/apps/v1"
2322
"k8s.io/klog/v2"
2423
"sigs.k8s.io/controller-runtime/pkg/client"
2524

2625
offloadingv1beta1 "github.com/liqotech/liqo/apis/offloading/v1beta1"
2726
"github.com/liqotech/liqo/pkg/utils/getters"
28-
"github.com/liqotech/liqo/pkg/vkMachinery"
2927
vkforge "github.com/liqotech/liqo/pkg/vkMachinery/forge"
3028
)
3129

@@ -76,32 +74,3 @@ type Flag struct {
7674
func (f Flag) String() string {
7775
return fmt.Sprintf("%s=%s", f.Name, f.Value)
7876
}
79-
80-
// CheckVirtualKubeletFlagsConsistence checks if the VirtualKubelet args are consistent with the flag list provided.
81-
// It returns true if all the flags are consistent, false otherwise.
82-
// A flag is not consistent if it is present in the VirtualKubelet args with a different value.
83-
func CheckVirtualKubeletFlagsConsistence(
84-
ctx context.Context, cl client.Client, vn *offloadingv1beta1.VirtualNode, flags ...Flag) (bool, error) {
85-
list, err := getters.ListVirtualKubeletPodsFromVirtualNode(ctx, cl, vn)
86-
if err != nil {
87-
return false, err
88-
}
89-
for i := range list.Items {
90-
for j := range list.Items[i].Spec.Containers {
91-
if list.Items[i].Spec.Containers[j].Name != vkMachinery.ContainerName {
92-
continue
93-
}
94-
for _, arg := range list.Items[i].Spec.Containers[j].Args {
95-
for _, flag := range flags {
96-
if strings.HasPrefix(arg, flag.Name) {
97-
if flag.String() != arg {
98-
return false, nil
99-
}
100-
break
101-
}
102-
}
103-
}
104-
}
105-
}
106-
return true, nil
107-
}

0 commit comments

Comments
 (0)