Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: enhance K8s cluster operational and observable capabilities #7

Merged
merged 30 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f6b0e36
文件处理部分,k8s部分代码
bearslyricattack Jul 18, 2024
29025cb
“完善文件处理 新增部分k8s代码
bearslyricattack Jul 21, 2024
ef16a53
kubernetes部分基本完成,提交prometheus部分demo
bearslyricattack Aug 12, 2024
f53552b
prometheus 部分完成
bearslyricattack Sep 1, 2024
6eee43c
prometheus部分
bearslyricattack Sep 1, 2024
76a2c9c
fix
bearslyricattack Sep 26, 2024
9583d22
fix
bearslyricattack Sep 26, 2024
e381f56
fix k8s part,this part is available.
bearslyricattack Sep 27, 2024
0586e5c
fix prometheus part,this part is available.
bearslyricattack Sep 27, 2024
d048565
es loki两部分测试与代码优化 当前为可用状态
bearslyricattack Oct 18, 2024
8654283
loki 常量修正
bearslyricattack Oct 18, 2024
c4cc56e
优化代码结构,统一错误处理
bearslyricattack Oct 19, 2024
785ff53
删除go2.sum
bearslyricattack Oct 22, 2024
d7a6545
fix code
bearslyricattack Oct 22, 2024
175bcd2
add local log system client and fix bug.
bearslyricattack Oct 25, 2024
1d4addf
fix bug.
bearslyricattack Oct 26, 2024
4c5e8b0
fix bug.
bearslyricattack Oct 26, 2024
cb6b1c6
fix bug.
bearslyricattack Oct 26, 2024
eb1051e
修正代码结构,整理常量与全局变量存放位置
bearslyricattack Oct 27, 2024
87082f4
优化代码结构,提升es-client可用性
bearslyricattack Oct 28, 2024
4928ec0
优化代码结构,提升es-client可用性
bearslyricattack Oct 28, 2024
c95fca7
修改login登陆逻辑 提升可拓展性
bearslyricattack Oct 28, 2024
cc784c4
修改login登陆逻辑 提升可拓展性
bearslyricattack Oct 28, 2024
e2ffae3
fix k8s part output and fix readme
bearslyricattack Oct 28, 2024
88e1219
fix readme and add prometheus part.
bearslyricattack Oct 28, 2024
215e9d8
fix readme ,fix code bug.
bearslyricattack Oct 28, 2024
bcb9f3e
fix readme ,fix code bug.
bearslyricattack Oct 28, 2024
19d2011
fix readme ,fix code bug.
bearslyricattack Oct 28, 2024
86bee63
fix readme ,fix code bug.
bearslyricattack Oct 28, 2024
dd4ea29
fix go.mod
bearslyricattack Oct 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
673 changes: 666 additions & 7 deletions README.md

Large diffs are not rendered by default.

112 changes: 112 additions & 0 deletions action/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package config

import (
"fmt"
"github.com/seata/seata-ctl/model"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"log"
"os"
)

var Path string

var ConfigCmd = &cobra.Command{
Use: "config",
Short: "Set config path",
Run: func(cmd *cobra.Command, args []string) {
err := createYMLFile(Path)
if err != nil {
println("Error creating config:", err.Error())
log.Fatal(err)
}
},
}

func init() {
ConfigCmd.PersistentFlags().StringVar(&Path, "path", "", "Set config path")
}

func createSampleConfig() model.Config {
return model.Config{
Kubernetes: model.Kubernetes{
Cluster: []model.KubernetesCluster{
{
Name: "",
KubeConfigPath: "",
YmlPath: "",
},
},
},
Prometheus: model.Prometheus{
Servers: []model.Server{
{
Name: "",
Address: "",
Auth: "",
},
},
},
Log: model.Log{
Clusters: []model.Cluster{
{
Name: "",
Types: "",
Address: "",
Source: "",
Username: "",
Password: "",
},
},
},
Context: model.Context{
Kubernetes: "",
Prometheus: "",
Log: "",
},
}
}

// Create a YAML file
func createYMLFile(path string) error {
// Check if the path exists
//if _, err := os.Stat(path); os.IsNotExist(err) {
// return fmt.Errorf("path does not exist: %s", path)
//}

// Check if the file already exists
ymlFilePath := "config.yml"
if _, err := os.Stat(ymlFilePath); err == nil {
fmt.Println("Config file already exists!")
return nil
}

// Create a sample config object
config := createSampleConfig()

// Marshal the config object into YAML format
data, err := yaml.Marshal(&config)
if err != nil {
log.Fatalf("Failed to marshal config to YAML: %v", err)
}

// Write the YAML data to a file
file, err := os.Create("config.yml")
if err != nil {
log.Fatalf("Failed to create YAML config: %v", err)
}
defer func() {
if err := file.Close(); err != nil {
log.Fatalf("Failed to close config file: %v", err)
}
}()

_, err = file.Write(data)
if err != nil {
log.Fatalf("Failed to write to YAML config: %v", err)
}
fmt.Println("Config created successfully!")
// Update the path variable
Path = path
return nil
}
27 changes: 27 additions & 0 deletions action/k8s/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package k8s

const (
DefaultCRName = "example-seataserver"
DefaultServerImage = "apache/seata-server:latest"
DefaultNamespace = "default"
DefaultDeployName = "seata-k8s-controller-manager"
DefaultControllerImage = "apache/seata-controller:latest"
DefaultReplicas = 1

Label = "cr_name"
CreateCrdPath = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions"
FilePath = "seata.yaml"
CRDname = "seataservers.operator.seata.apache.org"
ServiceName = "seata-server-cluster"
RequestStorage = "1Gi"
LimitStorage = "1Gi"
)

var (
Name string
Replicas int32
Namespace string
Image string
ControllerImage string
DeployName string
)
80 changes: 80 additions & 0 deletions action/k8s/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package k8s

import (
"context"
"fmt"
"github.com/seata/seata-ctl/action/k8s/utils"
"github.com/seata/seata-ctl/tool"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)

var DeployCmd = &cobra.Command{
Use: "deploy",
Short: "deploy seata in k8s",
Run: func(cmd *cobra.Command, args []string) {
err := deploy()
if err != nil {
tool.Logger.Errorf("deploy err:%v", err)
}
},
}

func init() {
DeployCmd.PersistentFlags().StringVar(&Name, "name", DefaultCRName, "Seataserver name")
DeployCmd.PersistentFlags().Int32Var(&Replicas, "replicas", 1, "Replicas number")
DeployCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name")
DeployCmd.PersistentFlags().StringVar(&Image, "image", DefaultServerImage, "Seata server image")
}

func deploy() error {
client, err := utils.GetDynamicClient()
if err != nil {
return err
}
namespace := Namespace
gvr := schema.GroupVersionResource{
Group: "operator.seata.apache.org",
Version: "v1alpha1",
Resource: "seataservers",
}

var seataServer *unstructured.Unstructured
seataServer, err = client.Resource(gvr).Namespace(namespace).Get(context.TODO(), Name, metav1.GetOptions{})
if seataServer != nil {
return fmt.Errorf("seata server already exist! name:" + Name)
}
seataServer = &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "operator.seata.apache.org/v1alpha1",
"kind": "SeataServer",
"metadata": map[string]interface{}{
"name": Name,
"namespace": Namespace,
},
"spec": map[string]interface{}{
"serviceName": ServiceName,
"replicas": Replicas,
"image": Image,
"store": map[string]interface{}{
"resources": map[string]interface{}{
"requests": map[string]interface{}{
"storage": RequestStorage,
},
"limits": map[string]interface{}{
"storage": LimitStorage,
},
},
},
},
},
}
_, err = client.Resource(gvr).Namespace(namespace).Create(context.TODO(), seataServer, metav1.CreateOptions{})
if err != nil {
return err
}
tool.Logger.Infof("CR install success,name: %s\n", Name)
return nil
}
120 changes: 120 additions & 0 deletions action/k8s/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package k8s

import (
"context"
"fmt"
"github.com/seata/seata-ctl/action/k8s/utils"
"github.com/seata/seata-ctl/tool"
"github.com/spf13/cobra"
_ "gopkg.in/yaml.v3"
_ "io/ioutil"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
_ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors"
_ "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
_ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
_ "k8s.io/apimachinery/pkg/runtime/schema"
_ "k8s.io/client-go/applyconfigurations/meta/v1"
)

var InstallCmd = &cobra.Command{
Use: "install",
Short: "Install Kubernetes CRD controller",
Run: func(cmd *cobra.Command, args []string) {
err := DeployCRD()
if err != nil {
tool.Logger.Errorf("install CRD err: %v", err)
}
err = DeployController()
if err != nil {
tool.Logger.Errorf("install Controller err: %v", err)
}
},
}

func init() {
InstallCmd.PersistentFlags().StringVar(&Namespace, "namespace", DefaultNamespace, "Namespace name")
InstallCmd.PersistentFlags().StringVar(&ControllerImage, "image", DefaultControllerImage, "Namespace name")
InstallCmd.PersistentFlags().StringVar(&DeployName, "name", DefaultDeployName, "Deployment name")
}

// DeployCRD deploys the custom resource definition.
func DeployCRD() error {
_, err := utils.CreateRequest(CreateCrdPath, FilePath)
if err != nil {
return err
}
return nil
}

// DeployController deploys the controller for the custom resource.
func DeployController() error {
// Get Kubernetes client
client, err := utils.GetClient()
if err != nil {
return fmt.Errorf("get client err: %v", err)
}

// Define the Deployment name and namespace
deploymentName := DeployName
namespace := Namespace

// Check if the Deployment already exists
_, err = client.AppsV1().Deployments(namespace).Get(context.TODO(), deploymentName, metav1.GetOptions{})
if err == nil {
// If the Deployment exists, output a message and return
return fmt.Errorf("Deployment '%s' already exists in the '%s' namespace\n", deploymentName, Namespace)
} else if !errors.IsNotFound(err) {
// If there is an error other than "not found", return it
return fmt.Errorf("error checking for existing deployment: %v", err)
}

// Create Deployment object if it does not exist
deployment := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: deploymentName,
},
Spec: appsv1.DeploymentSpec{
Replicas: func(i int32) *int32 { return &i }(1),
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": deploymentName,
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": deploymentName,
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: deploymentName,
Image: ControllerImage,
Ports: []corev1.ContainerPort{
{
ContainerPort: 80,
},
},
},
},
},
},
},
}

// Create the Deployment
_, err = client.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("error creating deployment: %v", err)
}
tool.Logger.Infof("Deployment created successfully")
return nil
}
Loading