From cd31c85ea7a6b13f8bb01abc0448a61f07ad5750 Mon Sep 17 00:00:00 2001 From: OrangeBao <baoyinghai_yewu@cmss.chinamobile.com> Date: Sun, 12 Nov 2023 21:55:25 +0800 Subject: [PATCH] feat: sync node status Signed-off-by: OrangeBao <baoyinghai_yewu@cmss.chinamobile.com> --- .../cluster-manager/cluster_controller.go | 46 +++++++++++++ .../controllers/node_resources_controller.go | 19 +++++- .../cluster-manager/utils/rootcluster.go | 66 ++++++++++++++++++- 3 files changed, 129 insertions(+), 2 deletions(-) diff --git a/pkg/clustertree/cluster-manager/cluster_controller.go b/pkg/clustertree/cluster-manager/cluster_controller.go index 8ac854ed1..f43004c8d 100644 --- a/pkg/clustertree/cluster-manager/cluster_controller.go +++ b/pkg/clustertree/cluster-manager/cluster_controller.go @@ -324,6 +324,46 @@ func (c *ClusterController) setupStorageControllers(mgr manager.Manager, nodes [ return nil } +func (c *ClusterController) setNodeStatus(ctx context.Context, nodeName string, leafClient kubernetes.Interface, node *corev1.Node, isNode2Node bool) error { + if isNode2Node { + if leafnode, err := leafClient.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}); err != nil { + klog.Errorf("create node %s failed, cannot get node from leaf cluster, err: %v", nodeName, err) + return err + } else { + node.Status = leafnode.Status + address, err := leafUtils.SortAddress(ctx, c.RootClient, nodeName, leafClient, node.Status.Addresses) + if err != nil { + return err + } + node.Status.Addresses = address + return nil + } + } + + leafnodes, err := leafClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{ + // TODO: LabelSelector + }) + if err != nil { + klog.Errorf("create node %s failed, cannot get node from leaf cluster, err: %v", nodeName, err) + return err + } + + if len(leafnodes.Items) == 0 { + klog.Errorf("create node %s failed, cannot get node from leaf cluster, len of leafnodes is 0", nodeName) + return err + } + + address, err := leafUtils.SortAddress(ctx, c.RootClient, nodeName, leafClient, leafnodes.Items[0].Status.Addresses) + + if err != nil { + return err + } + + node.Status.Addresses = address + + return nil +} + func (c *ClusterController) createNode(ctx context.Context, cluster *kosmosv1alpha1.Cluster, leafClient kubernetes.Interface) ([]*corev1.Node, error) { getNodeLen := func(cluster *kosmosv1alpha1.Cluster) int32 { if cluster.Spec.ClusterTreeOptions.Enable { @@ -351,12 +391,18 @@ func (c *ClusterController) createNode(ctx context.Context, cluster *kosmosv1alp nodeAnnotations[utils.KosmosNodeOwnedByClusterAnnotations] = clusterName node.SetAnnotations(nodeAnnotations) } + + if err := c.setNodeStatus(ctx, nodeName, leafClient, node, isNode2Node); err != nil { + return nil, err + } + node.Status.NodeInfo.KubeletVersion = serverVersion.GitVersion node.Status.DaemonEndpoints = corev1.NodeDaemonEndpoints{ KubeletEndpoint: corev1.DaemonEndpoint{ Port: c.Options.ListenPort, }, } + node, err = c.RootClient.CoreV1().Nodes().Create(ctx, node, metav1.CreateOptions{}) if err != nil { if !errors.IsAlreadyExists(err) { diff --git a/pkg/clustertree/cluster-manager/controllers/node_resources_controller.go b/pkg/clustertree/cluster-manager/controllers/node_resources_controller.go index 53de2cd7e..4172ecc86 100644 --- a/pkg/clustertree/cluster-manager/controllers/node_resources_controller.go +++ b/pkg/clustertree/cluster-manager/controllers/node_resources_controller.go @@ -128,7 +128,7 @@ func (c *NodeResourcesController) Reconcile(ctx context.Context, request reconci }, err } } else { - leafNodeName := fmt.Sprintf("%s%s", utils.KosmosNodePrefix, c.Cluster.Name) + leafNodeName := c.Cluster.Name leafResource, err := c.GlobalLeafManager.GetLeafResource(leafNodeName) if err != nil { klog.Errorf("Could not get leafResource,Error: %v", err) @@ -174,6 +174,23 @@ func (c *NodeResourcesController) Reconcile(ctx context.Context, request reconci clone.Labels = mergeMap(rootNode.GetLabels(), node.GetLabels()) clone.Annotations = mergeMap(rootNode.GetAnnotations(), node.GetAnnotations()) clone.Status = node.Status + // TODO: @duanmengkk + leafNodeName := c.Cluster.Name + leafResource, err := c.GlobalLeafManager.GetLeafResource(leafNodeName) + if err != nil { + klog.Errorf("Could not get leafResource,Error: %v", err) + return controllerruntime.Result{ + RequeueAfter: RequeueTime, + }, err + } + address, err := leafUtils.SortAddress(ctx, c.RootClientset, rootNode.Name, leafResource.Clientset, node.Status.Addresses) + if err != nil { + return controllerruntime.Result{ + RequeueAfter: RequeueTime, + }, err + } + + node.Status.Addresses = address } } diff --git a/pkg/clustertree/cluster-manager/utils/rootcluster.go b/pkg/clustertree/cluster-manager/utils/rootcluster.go index fc9286c68..7dcfae21d 100644 --- a/pkg/clustertree/cluster-manager/utils/rootcluster.go +++ b/pkg/clustertree/cluster-manager/utils/rootcluster.go @@ -1,6 +1,17 @@ package leafUtils -import kosmosv1alpha1 "github.com/kosmos.io/kosmos/pkg/apis/kosmos/v1alpha1" +import ( + "context" + "sort" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/klog" + + kosmosv1alpha1 "github.com/kosmos.io/kosmos/pkg/apis/kosmos/v1alpha1" + "github.com/kosmos.io/kosmos/pkg/utils" +) const ( RootClusterAnnotationKey = "kosmos.io/cluster-role" @@ -15,3 +26,56 @@ func IsRootCluster(cluster *kosmosv1alpha1.Cluster) bool { } return false } + +func SortAddress(ctx context.Context, rootClient kubernetes.Interface, nodeName string, leafClient kubernetes.Interface, originAddress []corev1.NodeAddress) ([]corev1.NodeAddress, error) { + rootnodes, err := rootClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) + if err != nil { + klog.Errorf("create node %s failed, cannot get node from root cluster, err: %v", nodeName, err) + return nil, err + } + + if len(rootnodes.Items) == 0 { + klog.Errorf("create node %s failed, cannot get node from root cluster, len of leafnodes is 0", nodeName) + return nil, err + } + + isIPv4First := true + for _, addr := range rootnodes.Items[0].Status.Addresses { + if addr.Type == corev1.NodeInternalIP { + if utils.IsIPv6(addr.Address) { + isIPv4First = false + } + break + } + } + + address := []corev1.NodeAddress{} + + for _, addr := range originAddress { + if addr.Type == corev1.NodeInternalIP { + address = append(address, corev1.NodeAddress{Type: corev1.NodeInternalIP, Address: addr.Address}) + } + } + + sort.Slice(address, func(i, j int) bool { + if isIPv4First { + if !utils.IsIPv6(address[i].Address) && utils.IsIPv6(address[j].Address) { + return true + } + if utils.IsIPv6(address[i].Address) && !utils.IsIPv6(address[j].Address) { + return false + } + return true + } else { + if !utils.IsIPv6(address[i].Address) && utils.IsIPv6(address[j].Address) { + return false + } + if utils.IsIPv6(address[i].Address) && !utils.IsIPv6(address[j].Address) { + return true + } + return true + } + }) + + return address, nil +}