| | |
| | | ) |
| | | |
| | | 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 { |
| | |
| | | |
| | | // 创建多个 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) |
| | |
| | | } |
| | | |
| | | 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 |
| | |
| | | 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) |
| | |
| | | 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 |
| | |
| | | |
| | | 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") |
| | | } |
New file |
| | |
| | | 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") |
| | | } |
New file |
| | |
| | | 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") |
| | | } |
New file |
| | |
| | | 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") |
| | | } |
| | |
| | | ) |
| | | |
| | | func delete_test() { |
| | | var ( |
| | | namespaces = []string{"guangsheng", "geruimi", "tongsheng"} |
| | | ) |
| | | |
| | | // 配置 Kubernetes 集群的 kubeconfig 路径 |
| | | kubeconfig := flag.String("kubeconfig", filepath.Join(util.HomeDir(), ".kube", "config"), "kubeconfig file") |
| | |
| | | |
| | | // 删除多个 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) |
| | | } |
| | |
| | | ) |
| | | |
| | | 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) { |
| | |
| | | |
| | | 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") |
| | |
| | | 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, |
| | | } |
| | | |
| | |
| | | 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) |
| | | } |
| | |
| | | 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.") |
| | |
| | | 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 秒后删除创建的资源 |