zhangqian
2023-12-26 84458b6618e9a5ee3c2c446ff87739582b356713
src/k8s/create.go
@@ -22,10 +22,23 @@
var (
   replicas      int32 = 3
   port          int32 = 9081
   rpcPort       int32 = 9082
   rpcPort       int32 = 9091
   namespaces          = []string{"guangsheng", "geruimi", "tongsheng"}
   usedNodePorts       = make(map[int32]bool)
)
type Config struct {
   Client         *kubernetes.Clientset // Kubernetes 客户端
   Image          string                // 镜像名称
   DBHost         string                // 数据库地址
   HttpPort       int32                 // HTTP 端口
   RpcPort        int32                 // RPC 端口
   NameSpace      string                // Namespace
   DeploymentName string                // Deployment 名称
   ServiceName    string                // Service 名称
   ALHost         string                // 算法Host
   Host           string                // 服务Host
}
func create_test() {
   // 配置 Kubernetes 集群的 kubeconfig 路径
@@ -45,7 +58,7 @@
   // 创建多个 Namespace 下的相同名称的 Deployment 和 Service
   for _, ns := range namespaces {
      err = CreateDeploymentAndService(clientset, ns, ns, ns)
      err = CreateDeploymentAndService(Config{Client: clientset, NameSpace: ns, DeploymentName: ns, ServiceName: ns})
      if err != nil {
         panic(err)
      }
@@ -114,30 +127,29 @@
   return nil
}
func CreateDeploymentAndService(clientset *kubernetes.Clientset, namespace, deploymentName, serviceName string) error {
   fmt.Println("\033[1;37;40mCreating resources in Namespace:", namespace, "\033[0m")
func CreateDeploymentAndService(config Config) error {
   fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
   // 检测并删除已存在的 Deployment 和 Service
   err := CheckAndDeleteResources(clientset, namespace, deploymentName, serviceName)
   err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
   if err != nil {
      return err
   }
   // 创建 Namespace
   err = createNamespace(clientset, namespace)
   config.HttpPort, config.RpcPort, err = getTwoNodePort(config.Client)
   if err != nil {
      return err
   }
   // 创建 Deployment
   err = createDeployment(clientset, namespace, deploymentName)
   err = createDeployment(config)
   if err != nil {
      return err
   }
   log.Printf("Waiting for Deployment %s to be ready...\n", deploymentName)
   log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
   // 创建 Service
   err = createService(clientset, namespace, serviceName)
   err = createService(config)
   if err != nil {
      return err
   }
@@ -168,24 +180,24 @@
   return nil
}
func createDeployment(clientset *kubernetes.Clientset, namespace, deploymentName string) error {
   fmt.Println("\033[1;37;40mCreating Deployment:", deploymentName, "\033[0m")
func createDeployment(config Config) error {
   fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
   deployment := &appsv1.Deployment{
      ObjectMeta: metav1.ObjectMeta{
         Name: deploymentName,
         Name: config.DeploymentName,
      },
      Spec: appsv1.DeploymentSpec{
         Replicas: &replicas,
         Selector: &metav1.LabelSelector{
            MatchLabels: map[string]string{
               "cid": namespace,
               "cid": config.NameSpace,
            },
         },
         Template: apiv1.PodTemplateSpec{
            ObjectMeta: metav1.ObjectMeta{
               Labels: map[string]string{
                  "cid": namespace,
                  "cid": config.NameSpace,
               },
            },
            Spec: apiv1.PodSpec{
@@ -196,41 +208,60 @@
                     WhenUnsatisfiable: apiv1.DoNotSchedule,
                     LabelSelector: &metav1.LabelSelector{
                        MatchLabels: map[string]string{
                           "cid": namespace,
                           "cid": config.NameSpace,
                        },
                     },
                  },
               },
               Containers: []apiv1.Container{
                  {
                     Name:  namespace,
                     Image: "192.168.20.119/apsserver/apsserver:v0.5",
                     Name:  config.NameSpace,
                     Image: config.Image,
                     Env: []apiv1.EnvVar{
                        {
                           Name:  "NODE_ID",
                           Value: namespace,
                           Name:  "GRPC_PORT",
                           Value: fmt.Sprint(config.RpcPort),
                        },
                        {
                           Name:  "DB_HOST",
                           Value: namespace,
                           Name: "DB_HOST",
                           ValueFrom: &apiv1.EnvVarSource{
                              FieldRef: &apiv1.ObjectFieldSelector{
                                 APIVersion: "v1",
                                 FieldPath:  "status.hostIP",
                              },
                           },
                        },
                        {
                           Name: "HOST",
                           ValueFrom: &apiv1.EnvVarSource{
                              FieldRef: &apiv1.ObjectFieldSelector{
                                 APIVersion: "v1",
                                 FieldPath:  "status.hostIP",
                              },
                           },
                        },
                        {
                           Name:  "AL_HOST",
                           Value: config.ALHost,
                        },
                        {
                           Name:  "DB_NAME",
                           Value: namespace,
                           Value: config.NameSpace,
                        },
                        {
                           Name:  "DB_PORT",
                           Value: strconv.Itoa(3306),
                           Value: strconv.Itoa(6446),
                        },
                        {
                           Name:  "DB_USER",
                           Value: namespace,
                           Value: config.NameSpace,
                        },
                        {
                           Name:  "DB_PASSWD",
                           Value: namespace + "@Basic2023",
                           Value: config.NameSpace + "@Basic2023",
                        },
                     },
                     ImagePullPolicy: apiv1.PullAlways, // 设置镜像拉取策略为 Always
                  },
               },
            },
@@ -238,35 +269,30 @@
      },
   }
   _, err := clientset.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})
   _, err := config.Client.AppsV1().Deployments(config.DeploymentName).Create(context.TODO(), deployment, metav1.CreateOptions{})
   if err != nil {
      if !errors.IsAlreadyExists(err) {
         return fmt.Errorf("failed to create Deployment: %v", err)
      }
      fmt.Printf("Deployment %s already exists in Namespace %s\n", deploymentName, namespace)
      fmt.Printf("Deployment %s already exists in Namespace %s\n", config.DeploymentName, config.NameSpace)
   } else {
      fmt.Printf("Deployment %s created in Namespace %s\n", deploymentName, namespace)
      fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
   }
   return nil
}
// createService 创建指定的 Service
func createService(clientset *kubernetes.Clientset, namespace, serviceName string) error {
   fmt.Println("\033[1;37;40mCreating Service:", serviceName, "\033[0m")
   //nodePort, err := getRandomNodePort(clientset)
   //if err != nil {
   //   return err
   //}
func createService(config Config) error {
   fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
   service := &apiv1.Service{
      ObjectMeta: metav1.ObjectMeta{
         Name: serviceName,
         Name: config.ServiceName,
      },
      Spec: apiv1.ServiceSpec{
         Selector: map[string]string{
            "cid": namespace,
            "cid": config.NameSpace,
         },
         Type: apiv1.ServiceTypeNodePort,
         Ports: []apiv1.ServicePort{
@@ -275,31 +301,53 @@
               Protocol:   apiv1.ProtocolTCP,
               Port:       port,                      // 集群内部访问端口
               TargetPort: intstr.FromInt(int(port)), // 容器对外端口
               NodePort:   0,                         // 外部访问端口
               NodePort:   config.HttpPort,           // 外部访问端口
            },
            {
               Name:       "tcp",
               Protocol:   apiv1.ProtocolTCP,
               Port:       rpcPort,
               TargetPort: intstr.FromInt(int(rpcPort)),
               NodePort:   0,
               NodePort:   config.RpcPort,
            },
         },
         SessionAffinity: apiv1.ServiceAffinityClientIP,
      },
   }
   _, err := clientset.CoreV1().Services(namespace).Create(context.TODO(), service, metav1.CreateOptions{})
   _, err := config.Client.CoreV1().Services(config.ServiceName).Create(context.TODO(), service, metav1.CreateOptions{})
   if err != nil {
      if !errors.IsAlreadyExists(err) {
         return fmt.Errorf("failed to create Service: %v", err)
      }
      log.Printf("Service %s already exists in Namespace %s\n", serviceName, namespace)
      log.Printf("Service %s already exists in Namespace %s\n", config.ServiceName, config.NameSpace)
   } else {
      log.Printf("Service %s created in Namespace %s\n", serviceName, namespace)
      log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
   }
   return nil
}
func getTwoNodePort(client *kubernetes.Clientset) (nodePort1, nodePort2 int32, err error) {
   nodePort1, err = getRandomNodePort(client)
   if err != nil {
      return 0, 0, err
   }
   for {
      nodePort2, err = getRandomNodePort(client)
      if err != nil {
         return 0, 0, err
      }
      if nodePort2 != nodePort1 {
         break
      }
   }
   return nodePort1, nodePort2, nil
}
// getRandomNodePort 获取一个未使用的随机 NodePort
@@ -369,7 +417,7 @@
   if len(svc.Spec.Ports) > 0 {
      for _, p := range svc.Spec.Ports {
         // return tcp port
         if p.Name == "tcp" {
         if p.Name == "http" {
            return p.NodePort, nil
         }
      }