zhangqian
2024-01-06 68c007e836384635d843bbc61174fae5b09ccd1c
增加对crm,wms,srm的部署支持
4个文件已添加
3个文件已修改
1206 ■■■■ 已修改文件
.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/k8s/create.go 467 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/k8s/create_crm.go 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/k8s/create_srm.go 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/k8s/create_wms.go 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/k8s/delete.go 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/main.go 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
New file
@@ -0,0 +1 @@
.idea
src/k8s/create.go
@@ -20,11 +20,19 @@
)
var (
    replicas      int32 = 3
    replicas      int32 = 1
    port          int32 = 9081
    rpcPort       int32 = 9091
    namespaces          = []string{"guangsheng", "geruimi", "tongsheng"}
    namespaces          = []string{"testFactory1", "testFactory2", "testFactory3"}
    usedNodePorts       = make(map[int32]bool)
    Projects            = []string{ProjectAps, ProjectCrm, ProjectSrm, ProjectWms}
)
const (
    ProjectAps = "aps"
    ProjectCrm = "crm"
    ProjectSrm = "srm"
    ProjectWms = "wms"
)
type Config struct {
@@ -60,9 +68,16 @@
    // 创建多个 Namespace 下的相同名称的 Deployment 和 Service
    for _, ns := range namespaces {
        err = CreateDeploymentAndService(Config{Client: clientset, NameSpace: ns, DeploymentName: ns, ServiceName: ns}, nil)
        err = CreateNamespace(clientset, ns)
        if err != nil {
            panic(err)
        }
        for _, proj := range Projects {
            obj := GetCreateObj(proj)
            err = obj.CreateDeploymentAndService(Config{Client: clientset, NameSpace: ns, DeploymentName: proj, ServiceName: proj}, nil)
            if err != nil {
                panic(err)
            }
        }
        nodeport, err := GetServiceNodePort(clientset, ns, ns)
@@ -71,7 +86,22 @@
        }
        log.Printf("Service NodePort: %d\n", nodeport)
    }
}
func GetCreateObj(proj string) Create {
    switch proj {
    case ProjectAps:
        return &ApsCreate{}
    case ProjectCrm:
        return &CrmCreate{}
    case ProjectSrm:
        return &SrmCreate{}
    case ProjectWms:
        return &WmsCreate{}
    }
    return nil
}
// CheckAndDeleteResources 检测并删除指定的 Namespace、Deployment 和 Service
@@ -129,36 +159,6 @@
    return nil
}
func CreateDeploymentAndService(config Config, extendEnvs map[string]string) error {
    fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
    // 检测并删除已存在的 Deployment 和 Service
    err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
    if err != nil {
        return err
    }
    config.HttpPort, config.RpcPort, err = getTwoNodePort(config.Client)
    if err != nil {
        return err
    }
    // 创建 Deployment
    err = createDeployment(config, extendEnvs)
    if err != nil {
        return err
    }
    log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
    // 创建 Service
    err = createService(config)
    if err != nil {
        return err
    }
    return nil
}
// CreateNamespace 创建指定的 Namespace
func CreateNamespace(clientset *kubernetes.Clientset, namespace string) error {
    log.Printf("Creating Namespace: %s\n", namespace)
@@ -177,184 +177,6 @@
        log.Printf("Namespace %s already exists\n", namespace)
    } else {
        log.Printf("Namespace %s created\n", namespace)
    }
    return nil
}
func createEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
    envs := []apiv1.EnvVar{
        {
            Name:  "GRPC_PORT",
            Value: fmt.Sprint(config.RpcPort),
        },
        {
            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:  "DB_NAME",
            Value: config.DBName,
        },
        {
            Name:  "DB_PORT",
            Value: strconv.Itoa(6446),
        },
        {
            Name:  "DB_USER",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PASSWD",
            Value: config.NameSpace + "@Basic2023",
        },
    }
    if config.ALHost != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "AL_HOST",
            Value: config.ALHost,
        })
    }
    if config.NodeID != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "NODE_ID",
            Value: config.NodeID,
        })
    }
    if len(pairs) > 0 {
        for name, value := range pairs {
            envs = append(envs, apiv1.EnvVar{
                Name:  name,
                Value: value,
            })
        }
    }
    for name, value := range pairs {
        envs = append(envs, apiv1.EnvVar{
            Name:  name,
            Value: value,
        })
    }
    return envs
}
func createDeployment(config Config, extendEnvs map[string]string) error {
    fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
    envs := createEnv(config, extendEnvs)
    deployment := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.DeploymentName,
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: &replicas,
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{
                    "cid": config.NameSpace,
                },
            },
            Template: apiv1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{
                        "cid": config.NameSpace,
                    },
                },
                Spec: apiv1.PodSpec{
                    TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
                        {
                            MaxSkew:           1,
                            TopologyKey:       "kubernetes.io/hostname",
                            WhenUnsatisfiable: apiv1.DoNotSchedule,
                            LabelSelector: &metav1.LabelSelector{
                                MatchLabels: map[string]string{
                                    "cid": config.NameSpace,
                                },
                            },
                        },
                    },
                    Containers: []apiv1.Container{
                        {
                            Name:            config.NameSpace,
                            Image:           config.Image,
                            Env:             envs,
                            ImagePullPolicy: apiv1.PullAlways, // 设置镜像拉取策略为 Always
                        },
                    },
                },
            },
        },
    }
    _, 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", config.DeploymentName, config.NameSpace)
    } else {
        fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
    }
    return nil
}
// createService 创建指定的 Service
func createService(config Config) error {
    fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
    service := &apiv1.Service{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.ServiceName,
        },
        Spec: apiv1.ServiceSpec{
            Selector: map[string]string{
                "cid": config.NameSpace,
            },
            Type: apiv1.ServiceTypeNodePort,
            Ports: []apiv1.ServicePort{
                {
                    Name:       "http",
                    Protocol:   apiv1.ProtocolTCP,
                    Port:       port,                      // 集群内部访问端口
                    TargetPort: intstr.FromInt(int(port)), // 容器对外端口
                    NodePort:   config.HttpPort,           // 外部访问端口
                },
                {
                    Name:       "tcp",
                    Protocol:   apiv1.ProtocolTCP,
                    Port:       rpcPort,
                    TargetPort: intstr.FromInt(int(rpcPort)),
                    NodePort:   config.RpcPort,
                },
            },
            SessionAffinity: apiv1.ServiceAffinityClientIP,
        },
    }
    _, 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", config.ServiceName, config.NameSpace)
    } else {
        log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
    }
    return nil
@@ -456,3 +278,226 @@
    return 0, fmt.Errorf("no ports defined for Service %s", serviceName)
}
type Create interface {
    CreateDeploymentAndService(config Config, extendEnv map[string]string) error
    CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar
    CreateDeployment(config Config, extendEnv map[string]string) error
    CreateService(config Config) error
    GetCid(config Config) string
}
type ApsCreate struct{}
func (c *ApsCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
    // 检测并删除已存在的 Deployment 和 Service
    err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
    if err != nil {
        return err
    }
    config.HttpPort, config.RpcPort, err = getTwoNodePort(config.Client)
    if err != nil {
        return err
    }
    // 创建 Deployment
    err = c.CreateDeployment(config, extendEnv)
    if err != nil {
        return err
    }
    log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
    // 创建 Service
    err = c.CreateService(config)
    if err != nil {
        return err
    }
    return nil
}
func (c *ApsCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
    envs := []apiv1.EnvVar{
        {
            Name:  "GRPC_PORT",
            Value: fmt.Sprint(config.RpcPort),
        },
        {
            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:  "DB_NAME",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PORT",
            Value: strconv.Itoa(6446),
        },
        {
            Name:  "DB_USER",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PASSWD",
            Value: config.NameSpace + "@Basic2023",
        },
    }
    if config.ALHost != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "AL_HOST",
            Value: config.ALHost,
        })
    }
    if config.NodeID != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "NODE_ID",
            Value: config.NodeID,
        })
    }
    if len(pairs) > 0 {
        for name, value := range pairs {
            envs = append(envs, apiv1.EnvVar{
                Name:  name,
                Value: value,
            })
        }
    }
    for name, value := range pairs {
        envs = append(envs, apiv1.EnvVar{
            Name:  name,
            Value: value,
        })
    }
    return envs
}
func (c *ApsCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
    log.Printf("Aps CreateDeployment config:%+v\n", config)
    envs := c.CreateEnv(config, extendEnv)
    deployment := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.DeploymentName,
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: &replicas,
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{
                    "cid": c.GetCid(config),
                },
            },
            Template: apiv1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{
                        "cid": c.GetCid(config),
                    },
                },
                Spec: apiv1.PodSpec{
                    TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
                        {
                            MaxSkew:           1,
                            TopologyKey:       "kubernetes.io/hostname",
                            WhenUnsatisfiable: apiv1.DoNotSchedule,
                            LabelSelector: &metav1.LabelSelector{
                                MatchLabels: map[string]string{
                                    "cid": c.GetCid(config),
                                },
                            },
                        },
                    },
                    Containers: []apiv1.Container{
                        {
                            Name:            config.NameSpace,
                            Image:           config.Image,
                            Env:             envs,
                            ImagePullPolicy: apiv1.PullIfNotPresent, // 设置镜像拉取策略为 Always
                        },
                    },
                },
            },
        },
    }
    _, err := config.Client.AppsV1().Deployments(config.NameSpace).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", config.DeploymentName, config.NameSpace)
    } else {
        fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
    }
    return nil
}
// createService 创建指定的 Service
func (c *ApsCreate) CreateService(config Config) error {
    fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
    service := &apiv1.Service{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.ServiceName,
        },
        Spec: apiv1.ServiceSpec{
            Selector: map[string]string{
                "cid": c.GetCid(config),
            },
            Type: apiv1.ServiceTypeNodePort,
            Ports: []apiv1.ServicePort{
                {
                    Name:       "http",
                    Protocol:   apiv1.ProtocolTCP,
                    Port:       port,                      // 集群内部访问端口
                    TargetPort: intstr.FromInt(int(port)), // 容器对外端口
                    NodePort:   config.HttpPort,           // 外部访问端口
                },
                {
                    Name:       "tcp",
                    Protocol:   apiv1.ProtocolTCP,
                    Port:       rpcPort,
                    TargetPort: intstr.FromInt(int(rpcPort)),
                    NodePort:   config.RpcPort,
                },
            },
            SessionAffinity: apiv1.ServiceAffinityClientIP,
        },
    }
    _, err := config.Client.CoreV1().Services(config.NameSpace).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", config.ServiceName, config.NameSpace)
    } else {
        log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
    }
    return nil
}
func (c *ApsCreate) GetCid(config Config) string {
    return fmt.Sprintf("%v-%v", config.NameSpace, "aps")
}
src/k8s/create_crm.go
New file
@@ -0,0 +1,208 @@
package k8s
import (
    "context"
    "fmt"
    appsv1 "k8s.io/api/apps/v1"
    apiv1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/errors"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/intstr"
    "log"
    "strconv"
)
type CrmCreate struct{}
func (c *CrmCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
    fmt.Printf("Crm CreateDeployment config:%+v\n", config)
    // 检测并删除已存在的 Deployment 和 Service
    err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
    if err != nil {
        return err
    }
    config.HttpPort, err = getRandomNodePort(config.Client)
    if err != nil {
        return err
    }
    // 创建 Deployment
    err = c.CreateDeployment(config, extendEnv)
    if err != nil {
        return err
    }
    log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
    // 创建 Service
    err = c.CreateService(config)
    if err != nil {
        return err
    }
    return nil
}
func (c *CrmCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
    envs := []apiv1.EnvVar{
        {
            Name: "DB_HOST",
            ValueFrom: &apiv1.EnvVarSource{
                FieldRef: &apiv1.ObjectFieldSelector{
                    APIVersion: "v1",
                    FieldPath:  "status.hostIP",
                },
            },
        },
        {
            Name:  "DB_PORT",
            Value: strconv.Itoa(6446),
        },
        {
            Name:  "DB_NAME",
            Value: config.NameSpace + "_crm",
        },
        {
            Name:  "DB_USER",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PASSWD",
            Value: config.NameSpace + "@Basic2023",
        },
    }
    if config.ALHost != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "AL_HOST",
            Value: config.ALHost,
        })
    }
    if config.NodeID != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "NODE_ID",
            Value: config.NodeID,
        })
    }
    if len(pairs) > 0 {
        for name, value := range pairs {
            envs = append(envs, apiv1.EnvVar{
                Name:  name,
                Value: value,
            })
        }
    }
    for name, value := range pairs {
        envs = append(envs, apiv1.EnvVar{
            Name:  name,
            Value: value,
        })
    }
    return envs
}
func (c *CrmCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
    envs := c.CreateEnv(config, extendEnv)
    deployment := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.DeploymentName,
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: &replicas,
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{
                    "cid": c.GetCid(config),
                },
            },
            Template: apiv1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{
                        "cid": c.GetCid(config),
                    },
                },
                Spec: apiv1.PodSpec{
                    TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
                        {
                            MaxSkew:           1,
                            TopologyKey:       "kubernetes.io/hostname",
                            WhenUnsatisfiable: apiv1.DoNotSchedule,
                            LabelSelector: &metav1.LabelSelector{
                                MatchLabels: map[string]string{
                                    "cid": c.GetCid(config),
                                },
                            },
                        },
                    },
                    Containers: []apiv1.Container{
                        {
                            Name:            config.DeploymentName,
                            Image:           config.Image,
                            Env:             envs,
                            ImagePullPolicy: apiv1.PullIfNotPresent, // 设置镜像拉取策略为 Always
                        },
                    },
                },
            },
        },
    }
    _, err := config.Client.AppsV1().Deployments(config.NameSpace).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", config.DeploymentName, config.NameSpace)
    } else {
        fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
    }
    return nil
}
// createService 创建指定的 Service
func (c *CrmCreate) CreateService(config Config) error {
    fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
    service := &apiv1.Service{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.ServiceName,
        },
        Spec: apiv1.ServiceSpec{
            Selector: map[string]string{
                "cid": c.GetCid(config),
            },
            Type: apiv1.ServiceTypeNodePort,
            Ports: []apiv1.ServicePort{
                {
                    Name:       "http",
                    Protocol:   apiv1.ProtocolTCP,
                    Port:       port,                      // 集群内部访问端口
                    TargetPort: intstr.FromInt(int(port)), // 容器对外端口
                    NodePort:   config.HttpPort,           // 外部访问端口
                },
            },
            SessionAffinity: apiv1.ServiceAffinityClientIP,
        },
    }
    _, err := config.Client.CoreV1().Services(config.NameSpace).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", config.ServiceName, config.NameSpace)
    } else {
        log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
    }
    return nil
}
func (c *CrmCreate) GetCid(config Config) string {
    return fmt.Sprintf("%v-%v", config.NameSpace, "crm")
}
src/k8s/create_srm.go
New file
@@ -0,0 +1,208 @@
package k8s
import (
    "context"
    "fmt"
    appsv1 "k8s.io/api/apps/v1"
    apiv1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/errors"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/intstr"
    "log"
    "strconv"
)
type SrmCreate struct{}
func (c *SrmCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
    // 检测并删除已存在的 Deployment 和 Service
    err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
    if err != nil {
        return err
    }
    config.HttpPort, err = getRandomNodePort(config.Client)
    if err != nil {
        return err
    }
    // 创建 Deployment
    err = c.CreateDeployment(config, extendEnv)
    if err != nil {
        return err
    }
    log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
    // 创建 Service
    err = c.CreateService(config)
    if err != nil {
        return err
    }
    return nil
}
func (c *SrmCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
    envs := []apiv1.EnvVar{
        {
            Name: "DB_HOST",
            ValueFrom: &apiv1.EnvVarSource{
                FieldRef: &apiv1.ObjectFieldSelector{
                    APIVersion: "v1",
                    FieldPath:  "status.hostIP",
                },
            },
        },
        {
            Name:  "DB_NAME",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PORT",
            Value: strconv.Itoa(6446),
        },
        {
            Name:  "DB_USER",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PASSWD",
            Value: config.NameSpace + "@Basic2023",
        },
    }
    if config.ALHost != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "AL_HOST",
            Value: config.ALHost,
        })
    }
    if config.NodeID != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "NODE_ID",
            Value: config.NodeID,
        })
    }
    if len(pairs) > 0 {
        for name, value := range pairs {
            envs = append(envs, apiv1.EnvVar{
                Name:  name,
                Value: value,
            })
        }
    }
    for name, value := range pairs {
        envs = append(envs, apiv1.EnvVar{
            Name:  name,
            Value: value,
        })
    }
    return envs
}
func (c *SrmCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
    fmt.Printf("Srm CreateDeployment config:%+v\n", config)
    envs := c.CreateEnv(config, extendEnv)
    deployment := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.DeploymentName,
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: &replicas,
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{
                    "cid": c.GetCid(config),
                },
            },
            Template: apiv1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{
                        "cid": c.GetCid(config),
                    },
                },
                Spec: apiv1.PodSpec{
                    TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
                        {
                            MaxSkew:           1,
                            TopologyKey:       "kubernetes.io/hostname",
                            WhenUnsatisfiable: apiv1.DoNotSchedule,
                            LabelSelector: &metav1.LabelSelector{
                                MatchLabels: map[string]string{
                                    "cid": c.GetCid(config),
                                },
                            },
                        },
                    },
                    Containers: []apiv1.Container{
                        {
                            Name:            config.DeploymentName,
                            Image:           config.Image,
                            Env:             envs,
                            ImagePullPolicy: apiv1.PullIfNotPresent, // 设置镜像拉取策略为 Always
                        },
                    },
                },
            },
        },
    }
    _, err := config.Client.AppsV1().Deployments(config.NameSpace).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", config.DeploymentName, config.NameSpace)
    } else {
        fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
    }
    return nil
}
// createService 创建指定的 Service
func (c *SrmCreate) CreateService(config Config) error {
    fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
    service := &apiv1.Service{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.ServiceName,
        },
        Spec: apiv1.ServiceSpec{
            Selector: map[string]string{
                "cid": c.GetCid(config),
            },
            Type: apiv1.ServiceTypeNodePort,
            Ports: []apiv1.ServicePort{
                {
                    Name:       "http",
                    Protocol:   apiv1.ProtocolTCP,
                    Port:       port,                      // 集群内部访问端口
                    TargetPort: intstr.FromInt(int(port)), // 容器对外端口
                    NodePort:   config.HttpPort,           // 外部访问端口
                },
            },
            SessionAffinity: apiv1.ServiceAffinityClientIP,
        },
    }
    _, err := config.Client.CoreV1().Services(config.NameSpace).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", config.ServiceName, config.NameSpace)
    } else {
        log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
    }
    return nil
}
func (c *SrmCreate) GetCid(config Config) string {
    return fmt.Sprintf("%v-%v", config.NameSpace, "srm")
}
src/k8s/create_wms.go
New file
@@ -0,0 +1,212 @@
package k8s
import (
    "context"
    "fmt"
    appsv1 "k8s.io/api/apps/v1"
    apiv1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/errors"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/intstr"
    "log"
    "strconv"
)
type WmsCreate struct{}
func (c *WmsCreate) CreateDeploymentAndService(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating resources in Namespace:", config.NameSpace, "\033[0m")
    fmt.Printf("Wms CreateDeployment config:%+v\n", config)
    // 检测并删除已存在的 Deployment 和 Service
    err := CheckAndDeleteResources(config.Client, config.NameSpace, config.DeploymentName, config.ServiceName)
    if err != nil {
        return err
    }
    config.HttpPort, err = getRandomNodePort(config.Client)
    if err != nil {
        return err
    }
    // 创建 Deployment
    err = c.CreateDeployment(config, extendEnv)
    if err != nil {
        return err
    }
    log.Printf("Waiting for Deployment %s to be ready...\n", config.DeploymentName)
    // 创建 Service
    err = c.CreateService(config)
    if err != nil {
        return err
    }
    return nil
}
func (c *WmsCreate) CreateEnv(config Config, pairs map[string]string) []apiv1.EnvVar {
    envs := []apiv1.EnvVar{
        {
            Name:  "GRPC_PORT",
            Value: fmt.Sprint(config.RpcPort),
        },
        {
            Name: "DB_HOST",
            ValueFrom: &apiv1.EnvVarSource{
                FieldRef: &apiv1.ObjectFieldSelector{
                    APIVersion: "v1",
                    FieldPath:  "status.hostIP",
                },
            },
        },
        {
            Name:  "DB_NAME",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PORT",
            Value: strconv.Itoa(6446),
        },
        {
            Name:  "DB_USER",
            Value: config.NameSpace,
        },
        {
            Name:  "DB_PASSWD",
            Value: config.NameSpace + "@Basic2023",
        },
    }
    if config.ALHost != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "AL_HOST",
            Value: config.ALHost,
        })
    }
    if config.NodeID != "" {
        envs = append(envs, apiv1.EnvVar{
            Name:  "NODE_ID",
            Value: config.NodeID,
        })
    }
    if len(pairs) > 0 {
        for name, value := range pairs {
            envs = append(envs, apiv1.EnvVar{
                Name:  name,
                Value: value,
            })
        }
    }
    for name, value := range pairs {
        envs = append(envs, apiv1.EnvVar{
            Name:  name,
            Value: value,
        })
    }
    return envs
}
func (c *WmsCreate) CreateDeployment(config Config, extendEnv map[string]string) error {
    fmt.Println("\033[1;37;40mCreating Deployment:", config.DeploymentName, "\033[0m")
    envs := c.CreateEnv(config, extendEnv)
    deployment := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.DeploymentName,
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: &replicas,
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{
                    "cid": c.GetCid(config),
                },
            },
            Template: apiv1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{
                        "cid": c.GetCid(config),
                    },
                },
                Spec: apiv1.PodSpec{
                    TopologySpreadConstraints: []apiv1.TopologySpreadConstraint{
                        {
                            MaxSkew:           1,
                            TopologyKey:       "kubernetes.io/hostname",
                            WhenUnsatisfiable: apiv1.DoNotSchedule,
                            LabelSelector: &metav1.LabelSelector{
                                MatchLabels: map[string]string{
                                    "cid": c.GetCid(config),
                                },
                            },
                        },
                    },
                    Containers: []apiv1.Container{
                        {
                            Name:            config.DeploymentName,
                            Image:           config.Image,
                            Env:             envs,
                            ImagePullPolicy: apiv1.PullIfNotPresent, // 设置镜像拉取策略为 Always
                        },
                    },
                },
            },
        },
    }
    _, err := config.Client.AppsV1().Deployments(config.NameSpace).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", config.DeploymentName, config.NameSpace)
    } else {
        fmt.Printf("Deployment %s created in Namespace %s\n", config.DeploymentName, config.NameSpace)
    }
    return nil
}
// createService 创建指定的 Service
func (c *WmsCreate) CreateService(config Config) error {
    fmt.Println("\033[1;37;40mCreating Service:", config.ServiceName, "\033[0m")
    service := &apiv1.Service{
        ObjectMeta: metav1.ObjectMeta{
            Name: config.ServiceName,
        },
        Spec: apiv1.ServiceSpec{
            Selector: map[string]string{
                "cid": c.GetCid(config),
            },
            Type: apiv1.ServiceTypeNodePort,
            Ports: []apiv1.ServicePort{
                {
                    Name:       "http",
                    Protocol:   apiv1.ProtocolTCP,
                    Port:       port,                      // 集群内部访问端口
                    TargetPort: intstr.FromInt(int(port)), // 容器对外端口
                    NodePort:   config.HttpPort,           // 外部访问端口
                },
            },
            SessionAffinity: apiv1.ServiceAffinityClientIP,
        },
    }
    _, err := config.Client.CoreV1().Services(config.NameSpace).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", config.ServiceName, config.NameSpace)
    } else {
        log.Printf("Service %s created in Namespace %s\n", config.ServiceName, config.NameSpace)
    }
    return nil
}
func (c *WmsCreate) GetCid(config Config) string {
    return fmt.Sprintf("%v-%v", config.NameSpace, "wms")
}
src/k8s/delete.go
@@ -14,9 +14,6 @@
)
func delete_test() {
    var (
        namespaces = []string{"guangsheng", "geruimi", "tongsheng"}
    )
    // 配置 Kubernetes 集群的 kubeconfig 路径
    kubeconfig := flag.String("kubeconfig", filepath.Join(util.HomeDir(), ".kube", "config"), "kubeconfig file")
@@ -35,7 +32,32 @@
    // 删除多个 Namespace 下的相同名称的 Deployment 和 Service
    for _, ns := range namespaces {
        err = DeleteResources(clientset, ns, ns, ns)
        for _, proj := range Projects {
            if proj == ProjectAps {
                err := deleteDeployment(clientset, ns, ns)
                if err != nil {
                    panic(err)
                }
                // 删除 Service
                err = deleteService(clientset, ns, ns)
                if err != nil {
                    panic(err)
                }
            } else {
                err := deleteDeployment(clientset, ns, proj)
                if err != nil {
                    panic(err)
                }
                // 删除 Service
                err = deleteService(clientset, ns, proj)
                if err != nil {
                    panic(err)
                }
            }
        }
        // 删除 Namespace
        err = DeleteNamespace(Config{Client: clientset, NameSpace: ns})
        if err != nil {
            panic(err)
        }
src/main/main.go
@@ -20,10 +20,10 @@
)
var (
    replicas      int32 = 3
    replicas      int32 = 1
    port          int32 = 9081
    usedNodePorts       = make(map[int32]bool)
    namespaces          = []string{"guangsheng", "geruimi", "tongsheng"}
    namespaces          = []string{"testFactory1", "testFactory2", "testFactory3"}
)
func rancher_install_test(node rancher.Node) {
@@ -127,8 +127,9 @@
    createNamespace := createCmd.String("ns", "", "Namespace name")
    createDeployment := createCmd.String("deployment", "", "Deployment name")
    fmt.Println(createDeployment)
    createService := createCmd.String("service", "", "Service name")
    fmt.Println(createService)
    deleteNamespace := deleteCmd.String("ns", "", "Namespace name")
    deleteDeployment := deleteCmd.String("deployment", "", "Deployment name")
    deleteService := deleteCmd.String("service", "", "Service name")
@@ -176,9 +177,9 @@
        rancherClusterConfig.Nodes = make([]rancher.Node, 3)
        rancherClusterConfig.Nodes[0] = rancher.Node{
            Roles:       []string{"worker"},
            IP:          "192.168.20.189",
            SSHUsername: "basic",
            SSHPassword: "123",
            IP:          "192.168.49.1",
            SSHUsername: "me",
            SSHPassword: "123456",
            SSHPort:     22,
        }
@@ -208,23 +209,31 @@
            panic(err.Error())
        }
        if *createNamespace == "" || *createDeployment == "" || *createService == "" {
        if *createNamespace == "" {
            fmt.Println("Namespace, Deployment, and Service names are required")
            createCmd.PrintDefaults()
            os.Exit(1)
        }
        err = k8s.CreateDeploymentAndService(k8s.Config{
            Client:         clientset,
            NameSpace:      *createNamespace,
            DeploymentName: *createDeployment,
            ServiceName:    *createService,
        }, nil)
        err = k8s.CreateNamespace(clientset, *createNamespace)
        if err != nil {
            panic(err)
        }
        for _, proj := range k8s.Projects {
            obj := k8s.GetCreateObj(proj)
            err = obj.CreateDeploymentAndService(k8s.Config{
                Client:         clientset,
                NameSpace:      *createNamespace,
                DeploymentName: proj,
                ServiceName:    proj,
                Image:          "fai365.com:9088/aps/aps",
            }, nil)
            if err != nil {
                panic(err)
            }
        }
        nodeport, err := k8s.GetServiceNodePort(clientset, *createNamespace, *createService)
        nodeport, err := k8s.GetServiceNodePort(clientset, *createNamespace, "aps")
        if err != nil {
            panic(err)
        }
@@ -255,9 +264,14 @@
            os.Exit(1)
        }
        err = k8s.DeleteResources(clientset, *deleteNamespace, *deleteDeployment, *deleteService)
        if err != nil {
            panic(err)
        for _, proj := range k8s.Projects {
            err = k8s.DeleteResources(clientset, *deleteNamespace, proj, proj)
            if err != nil {
                panic(err)
            }
            if err != nil {
                panic(err)
            }
        }
        fmt.Println("Resources deleted.")
@@ -287,23 +301,27 @@
        for _, ns := range namespaces {
            deploymentName := ns
            serviceName := ns
            err := k8s.CreateDeploymentAndService(k8s.Config{
                Client:         clientset,
                NameSpace:      ns,
                DeploymentName: deploymentName,
                ServiceName:    serviceName,
            }, nil)
            if err != nil {
                log.Printf("\033[97;41mFailed to create resources in namespace %s: %v\033[0m\n", ns, err)
            } else {
                nodeport, err := k8s.GetServiceNodePort(clientset, ns, ns)
            for _, proj := range k8s.Projects {
                obj := k8s.GetCreateObj(proj)
                err = obj.CreateDeploymentAndService(k8s.Config{
                    Client:         clientset,
                    NameSpace:      ns,
                    DeploymentName: deploymentName,
                    ServiceName:    serviceName,
                }, nil)
                if err != nil {
                    panic(err)
                }
                    log.Printf("\033[97;41mFailed to create resources in namespace %s: %v\033[0m\n", ns, err)
                } else {
                    nodeport, err := k8s.GetServiceNodePort(clientset, ns, ns)
                    if err != nil {
                        panic(err)
                    }
                log.Printf("Service NodePort: %d\n", nodeport)
                log.Printf("\033[97;42mSuccessfully created resources in namespace %s\033[0m\n", ns)
                    log.Printf("Service NodePort: %d\n", nodeport)
                    log.Printf("\033[97;42mSuccessfully created resources in namespace %s\033[0m\n", ns)
                }
            }
        }
        // 延迟 1000 秒后删除创建的资源