145 lines
3.8 KiB
Go
145 lines
3.8 KiB
Go
package kubernetes
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"k8s.io/klog/v2"
|
|
|
|
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
|
|
)
|
|
|
|
var (
|
|
etcdNodeName string
|
|
etcdSelectorLabels map[string]string
|
|
)
|
|
|
|
func (i *CommandInitOption) getKarmadaAPIServerIP() error {
|
|
if i.KarmadaAPIServerAdvertiseAddress != "" {
|
|
i.KarmadaAPIServerIP = append(i.KarmadaAPIServerIP, utils.StringToNetIP(i.KarmadaAPIServerAdvertiseAddress))
|
|
return nil
|
|
}
|
|
|
|
nodeClient := i.KubeClientSet.CoreV1().Nodes()
|
|
masterNodes, err := nodeClient.List(context.TODO(), metav1.ListOptions{LabelSelector: "node-role.kubernetes.io/master"})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(masterNodes.Items) == 0 {
|
|
masterNodes, err = nodeClient.List(context.TODO(), metav1.ListOptions{LabelSelector: "node-role.kubernetes.io/control-plane"})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if len(masterNodes.Items) == 0 {
|
|
klog.Warning("The kubernetes cluster does not have a Master role.")
|
|
} else {
|
|
for _, v := range masterNodes.Items {
|
|
i.KarmadaAPIServerIP = append(i.KarmadaAPIServerIP, utils.StringToNetIP(v.Status.Addresses[0].Address))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
klog.Info("Randomly select 3 Node IPs in the kubernetes cluster.")
|
|
nodes, err := nodeClient.List(context.TODO(), metav1.ListOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for number := 0; number < 3; number++ {
|
|
if number >= len(nodes.Items) {
|
|
break
|
|
}
|
|
i.KarmadaAPIServerIP = append(i.KarmadaAPIServerIP, utils.StringToNetIP(nodes.Items[number].Status.Addresses[0].Address))
|
|
}
|
|
|
|
if len(i.KarmadaAPIServerIP) == 0 {
|
|
return fmt.Errorf("karmada apiserver ip is empty")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// nodeStatus Check the node status, if it is an unhealthy node, return false.
|
|
func nodeStatus(node []corev1.NodeCondition) bool {
|
|
for _, v := range node {
|
|
switch v.Type {
|
|
case corev1.NodeReady:
|
|
if v.Status != corev1.ConditionTrue {
|
|
return false
|
|
}
|
|
case corev1.NodeMemoryPressure:
|
|
if v.Status != corev1.ConditionFalse {
|
|
return false
|
|
}
|
|
case corev1.NodeDiskPressure:
|
|
if v.Status != corev1.ConditionFalse {
|
|
return false
|
|
}
|
|
case corev1.NodeNetworkUnavailable:
|
|
if v.Status != corev1.ConditionFalse {
|
|
return false
|
|
}
|
|
case corev1.NodePIDPressure:
|
|
if v.Status != corev1.ConditionFalse {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// AddNodeSelectorLabels When EtcdStorageMode is hostPath, and EtcdNodeSelectorLabels is empty.
|
|
// Select a healthy node to add labels, and schedule etcd to that node
|
|
func (i *CommandInitOption) AddNodeSelectorLabels() error {
|
|
nodes, err := i.KubeClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, v := range nodes.Items {
|
|
if v.Spec.Taints != nil {
|
|
continue
|
|
}
|
|
|
|
if nodeStatus(v.Status.Conditions) {
|
|
etcdNodeName = v.Name
|
|
etcdSelectorLabels = v.Labels
|
|
break
|
|
}
|
|
}
|
|
|
|
if etcdSelectorLabels == nil {
|
|
return errors.New("failed to find a healthy node for karmada-etcd")
|
|
}
|
|
|
|
etcdSelectorLabels["karmada.io/etcd"] = ""
|
|
patchData := map[string]interface{}{"metadata": map[string]map[string]string{"labels": etcdSelectorLabels}}
|
|
playLoadBytes, _ := json.Marshal(patchData)
|
|
if _, err := i.KubeClientSet.CoreV1().Nodes().Patch(context.TODO(), etcdNodeName, types.StrategicMergePatchType, playLoadBytes, metav1.PatchOptions{}); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (i *CommandInitOption) isNodeExist(labels string) bool {
|
|
l := strings.Split(labels, "=")
|
|
node, err := i.KubeClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{LabelSelector: l[0]})
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
if len(node.Items) == 0 {
|
|
return false
|
|
}
|
|
klog.Infof("Find the node [ %s ] by label %s", node.Items[0].Name, labels)
|
|
return true
|
|
}
|