karmada-io / karmada

Open, Multi-Cloud, Multi-Cluster Kubernetes Orchestration
https://karmada.io
Apache License 2.0
4.12k stars 807 forks source link

Karmada customresourceinterpreter Webhook, is there a way to obtain the corresponding member cluster name in InterpreterOperationReviseReplica function #4845

Open weidalin opened 2 weeks ago

weidalin commented 2 weeks ago

Please provide an in-depth description of the question you have: Karmada custom interpreter Webhook( https://github.com/karmada-io/karmada/tree/master/examples/customresourceinterpreter ) After executing configv1alpha1. InterpreterOperationReviseReplica, the number of replicas will be automatically written to the resources in the corresponding cluster. If I want to fill in the number of replicas while writing the cluster name when executing configv1alpha1. InterpreterOperationReviseReplica in webhook, is there a way to obtain the corresponding member cluster name in the function?

func (e *workloadInterpreter) Handle(_ context.Context, req interpreter.Request) interpreter.Response {
    workload := &workloadv1alpha1.Workload{}
    err := e.decoder.Decode(req, workload)
    if err != nil {
        return interpreter.Errored(http.StatusBadRequest, err)
    }
    klog.Infof("Explore workload(%s/%s) for request: %s", workload.GetNamespace(), workload.GetName(), req.Operation)

    switch req.Operation {
    case configv1alpha1.InterpreterOperationInterpretReplica:
        return e.responseWithExploreReplica(workload)
    case configv1alpha1.InterpreterOperationReviseReplica:
        return e.responseWithExploreReviseReplica(workload, req)
    case configv1alpha1.InterpreterOperationRetain:
        return e.responseWithExploreRetaining(workload, req)
    case configv1alpha1.InterpreterOperationAggregateStatus:
        return e.responseWithExploreAggregateStatus(workload, req)
    case configv1alpha1.InterpreterOperationInterpretHealth:
        return e.responseWithExploreInterpretHealth(workload)
    case configv1alpha1.InterpreterOperationInterpretStatus:
        return e.responseWithExploreInterpretStatus(workload)
    case configv1alpha1.InterpreterOperationInterpretDependency:
        return e.responseWithExploreDependency(workload)
    default:
        return interpreter.Errored(http.StatusBadRequest, fmt.Errorf("wrong request operation type: %s", req.Operation))
    }
}

What do you think about this question?:

Environment:

weidalin commented 2 weeks ago

@XiShanYongYe-Chang

XiShanYongYe-Chang commented 2 weeks ago

Hi @weidalin, thanks for your feedback. May I know why you need the cluster information?

weidalin commented 1 week ago

Because during my Karmada propagation process, I need to modify two or more replica count variables, such as modifying replicas and traffic. In the Karmada layer, replicas=3 and traffic=100, propagate to two Woker clusters with a cluster weight of 3:2. I am currently returning 100 through a fixed responseWithExploreReplica, Member1: When executing InterpreterOperaonReviseReplica, req DesiredReplicas=60, with replicates=3 60%=1.8 Menber2: Req when executing InterpreterOperationReviseReplica DesiredReplicas=40, with replicas=3 40%=1.2. And because the number of replicas needs to be an integer, rounding up yields Member1 replicas=2, Member2 replicas=2, However, the number of replicas in the Karmada layer is 3 and the total number of replicas in the Worker layer is 4, so I hope to know which Woker the current calculated result will be distributed to when executing InterpreterOperation ReviseReplica. If it is Menber1, set replicas to 2, and if it is Menber2, set replicas to 1 to ensure that the number of Karmada and Woker layers is consistent.

Is there a way to obtain cluster information in the InterpreterOperationReviseReplica parameter?

@XiShanYongYe-Chang

XiShanYongYe-Chang commented 1 week ago

I need to modify two or more replica count variables, such as modifying replicas and traffic.

Can different variables be judged by cluster information? I want to make sure that the cluster information is sufficient enough to make a determination.

Sorry, I don't fully understand the calculation in this example. I don't understand why the number of replicas can be set based on the cluster information.

Is there a way to obtain cluster information in the InterpreterOperationReviseReplica parameter?

Currently, it is not supported. We need to extend the API. If we can find typical application scenarios of users, I believe we can quickly promote this requirement.

If it's convenient for you, we can talk about this at the community meeting.

weidalin commented 1 week ago

Sorry, I don't fully understand the calculation in this example. I don't understand why the number of replicas can be set based on the cluster information.

I obtained the current propagation object through the karmada clientset based on the crd's clusterpropagationpolicy. karmada.io/name label, which contains the cluster weight corresponding to the cluster name.

WeightPreference:
StaticWeightList:
-TargetCluster:
ClusterNames:
-Member1
Weight: 6
-TargetCluster:
ClusterNames:
-Member2
Weight: 4

By calculating, I can know that for example, the cluster weight percentage corresponding to menber1 is 60%.

I want to make sure that the cluster information is sufficient enough to make a determination.

I can sort member1 and member2, Member1 replicas1=round (2 60%)=1, Member2 replicates2=round (3 40%)=1, The sum of the number of replicas for Member1 and Member2 is replicates1+replicates2=2, while for the Karmada layer replicates=3, there is still a difference of 1. I sorted the differences by cluster name in a dictionary, and used a for loop to allocate the difference of 1 to Member1 and Member2 in sequence until the allocation was completed. Finally, replicates1=2, replicates2=1

weidalin commented 1 week ago

Another solution would be to modify the values of two fields in the CRD. In the Karmada layer, the first field in the CRD is replicas=1, and the second field is traffic=100. It will be distributed to member1 and member2 in a 1:1 cluster ratio, requiring the sum of the replicas and traffic of the two members to be the Karmada layer. How can I implement this in InterpreterOperationReviseReplica?@XiShanYongYe-Chang

yike21 commented 1 week ago

It appears that replicas are dynamically distributed to the cluster and the total number of replicas is kept consistent. ref This test case indicates that the total number of copies is consistent, even if they cannot be divided proportionally into integers.

XiShanYongYe-Chang commented 1 week ago

Hi @weidalin you can add an agenda in the community meeting. Looking forward to a more in-depth conversation.

XiShanYongYe-Chang commented 1 week ago

Hi @weidalin, can you check whether #4440 is related to the problem described in the issue?

weidalin commented 1 week ago

Hi @weidalin, can you check whether #4440 is related to the problem described in the issue?

yes

XiShanYongYe-Chang commented 1 week ago

@weidalin Thanks for your reply.

I'm still a bit behind your use case, so I'm not sure if the solution described in #4440 will meet your needs. Can you help to confirm?

weidalin commented 1 week ago

@weidalin Thanks for your reply.

I'm still a bit behind your use case, so I'm not sure if the solution described in #4440 will meet your needs. Can you help to confirm?

during InterpreterOperationReviseReplica , if can provide below annotation can solve my problem.

cluster.karmada.io/name: ClusterA

Alternatively, providing the target cluster name in the ctx context can also solve my problem

func (e *atmscmInterpreter) Handle(ctx context.Context, req interpreter.Request) interpreter.Response {
   targetCluster:= ctx.Value("targetCluster").(string)
   ...
}

Or provide target cluster name in interpreter.Request