Skip to content

Commit

Permalink
fix inplace update failed due to virtual kubelet
Browse files Browse the repository at this point in the history
skip inPlaceUpdateState check when pod is running on vk node

Signed-off-by: joey <zchengjoey@gmail.com>
  • Loading branch information
chengjoey committed Aug 4, 2023
1 parent a44ca54 commit 9dc5214
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 1 deletion.
3 changes: 2 additions & 1 deletion pkg/control/pubcontrol/pub_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ func (c *commonControl) IsPodStateConsistent(pod *corev1.Pod) bool {
}

// whether other containers is consistent
if err := inplaceupdate.DefaultCheckInPlaceUpdateCompleted(pod); err != nil {
// if the pod is running on a virtual kubelet node, do not check inplace update state
if err := inplaceupdate.DefaultCheckInPlaceUpdateCompleted(pod); err != nil && !isVirtualKubeletNode(c.Client, pod.Spec.NodeName) {
klog.V(5).Infof("check pod(%s/%s) InPlaceUpdate failed: %s", pod.Namespace, pod.Name, err.Error())
return false
}
Expand Down
29 changes: 29 additions & 0 deletions pkg/control/pubcontrol/pub_control_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/util/taints"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand All @@ -43,6 +44,21 @@ const (
MaxUnavailablePodSize = 2000
)

var (
labelNodeTypeKey = "type"
)

var (
virtualNodeType = "virtual-kubelet"
)

var (
taintVirtualToFind = &corev1.Taint{
Key: "virtual-kubelet.io/provider",
Effect: corev1.TaintEffectNoSchedule,
}
)

var ConflictRetry = wait.Backoff{
Steps: 4,
Duration: 500 * time.Millisecond,
Expand Down Expand Up @@ -175,6 +191,19 @@ func PodUnavailableBudgetValidatePod(client client.Client, control PubControl, p
return true, "", nil
}

// isVirtualKubeletNode Determine whether the node is virtual kubelet
func isVirtualKubeletNode(cli client.Client, nodeName string) bool {
if len(nodeName) == 0 {
return false
}
node := &corev1.Node{}
if err := cli.Get(context.Background(), client.ObjectKey{Name: nodeName}, node); err != nil {
klog.Errorf("get node(%s) failed: %s", nodeName, err.Error())
return false
}
return node.Labels[labelNodeTypeKey] == virtualNodeType && taints.TaintExists(node.Spec.Taints, taintVirtualToFind)
}

func checkAndDecrement(podName string, pub *policyv1alpha1.PodUnavailableBudget, operation policyv1alpha1.PubOperation) error {
if pub.Status.UnavailableAllowed <= 0 {
return errors.NewForbidden(policyv1alpha1.Resource("podunavailablebudget"), pub.Name, fmt.Errorf("pub unavailable allowed is negative"))
Expand Down
53 changes: 53 additions & 0 deletions pkg/control/pubcontrol/pub_control_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,56 @@ func TestGetPodUnavailableBudgetForPod(t *testing.T) {
})
}
}

func Test_isVirtualKubeletNode(t *testing.T) {
cases := []struct {
name string
node *corev1.Node
want bool
}{
{
name: "virtual kubelet node",
node: &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "virtual-kubelet",
Labels: map[string]string{
"type": "virtual-kubelet",
},
},
Spec: corev1.NodeSpec{
Taints: []corev1.Taint{
{
Key: "virtual-kubelet.io/provider",
Effect: corev1.TaintEffectNoSchedule,
Value: "mock",
},
},
},
},
want: true,
},
{
name: "not virtual kubelet node",
node: &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "not-virtual-kubelet",
Labels: map[string]string{
"ack.aliyun.com": "xxx",
},
},
Spec: corev1.NodeSpec{},
},
want: false,
},
}

for _, cs := range cases {
t.Run(cs.name, func(t *testing.T) {
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(cs.node).Build()
got := isVirtualKubeletNode(fakeClient, cs.node.Name)
if got != cs.want {
t.Fatalf("isVirtualKubeletNode failed")
}
})
}
}

0 comments on commit 9dc5214

Please sign in to comment.