Bootstrap

kubernetes & volcano 客户端

kubernetes 客户端

package main

import (
	"context"
	"fmt"
	"os"

	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

// https://www.cnblogs.com/guangdelw/p/17574575.html
func main() {
	clientset, error := GetK8sClient()
	if error != nil {
		os.Exit(-1)
	}
	//GetPods(clientset)

	//CreateNamespace(clientset, "test-namespace")

	// _, err := GetNamespace(clientset, "test-namespace")
	// if err != nil {
	// 	return
	// }

	// DeleteNamespace(clientset, "test-namespace")

	//GetAllNamespace(clientset)

	// GetSecret(clientset, "default", "ops-alert-bcm-config-d16")

	matchLabels := map[string]string{
		"app": "nginx",
	}

	objectMetaLabels := map[string]string{
		"app": "nginx",
	}

	var ports = []corev1.ContainerPort{
		{
			ContainerPort: 80,
		},
	}
	var image = "swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:alpine"
	CreateDeployment(clientset, "default", "nginx-web", matchLabels, objectMetaLabels, "nginx", image, ports)

	fmt.Println("===============================================")
	selector := map[string]string{
		"app": "nginx",
	}
	portsExt := []corev1.ServicePort{
		{
			Name:       "http",
			Port:       80,
			TargetPort: intstr.FromInt(80),
			Protocol:   corev1.ProtocolTCP,
			NodePort:   31111,
		},
	}
	CreateService(clientset, "default", "nginx-web", selector, portsExt)
}

// 获取 k8s apiServer 客户端
func GetK8sClient() (*kubernetes.Clientset, error) {
	kubeconfigPath := "./conf/local_k8s.config"
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
	if err != nil {
		fmt.Println("BuildConfigFromFlags error :", err.Error())
		return nil, err
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		fmt.Println("NewForConfig error :", err.Error())
		return nil, err
	}
	fmt.Printf("%#v\n", clientset)
	return clientset, nil
}

// 获取集群中所有pod
func GetPods(clientset *kubernetes.Clientset) (*corev1.PodList, error) {
	pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		fmt.Println("CoreV1 pod list error :", err.Error())
		return nil, err
	}
	for _, pod := range pods.Items {
		fmt.Printf("Pod Name: %-40s\tNamespace: %-10s\t%s\n", pod.Name, pod.Namespace, pod.Status.Phase)
	}
	return pods, nil
}

// 创建namespace
func CreateNamespace(clientset *kubernetes.Clientset, namespaceName string) (*corev1.Namespace, error) {
	// 创建一个namespace的客户端
	namespacesClient := clientset.CoreV1().Namespaces()
	// 构建一个namespace
	namespace := &corev1.Namespace{
		ObjectMeta: metav1.ObjectMeta{
			Name: namespaceName,
		},
		Status: corev1.NamespaceStatus{
			Phase: corev1.NamespaceActive,
		},
	}
	// 创建namespace
	res, err := namespacesClient.Create(context.Background(), namespace, metav1.CreateOptions{})
	if err != nil {
		fmt.Println("Create Namespace error :", err.Error())
		return nil, err
	}
	fmt.Printf("Created Namespace %s on %s\n", res.ObjectMeta.Name, res.ObjectMeta.CreationTimestamp)
	return res, nil
}

// 获取Namespace
func GetNamespace(clientset *kubernetes.Clientset, namespaceName string) (*corev1.Namespace, error) {
	// 创建namespace的客户端
	namespacesClient := clientset.CoreV1().Namespaces()
	// 用客户端来查询对应的namespace
	res, err := namespacesClient.Get(context.Background(), namespaceName, metav1.GetOptions{})
	if err != nil {
		fmt.Println("GetNamespace error :", err.Error())
		return nil, err
	}
	fmt.Printf("Get Namespace %s on %s\n", res.ObjectMeta.Name, res.ObjectMeta.CreationTimestamp)
	return res, nil
}

// 删除 Namespace
func DeleteNamespace(clientset *kubernetes.Clientset, namespaceName string) error {
	namespacesClient := clientset.CoreV1().Namespaces()
	var err = namespacesClient.Delete(context.Background(), namespaceName, metav1.DeleteOptions{})
	if err != nil {
		fmt.Println("Delete Namespace error :", err.Error())
		return err
	}
	fmt.Printf("删除成功")
	return nil
}

// 获取所有的 Namespace
func GetAllNamespace(clientset *kubernetes.Clientset) (*corev1.NamespaceList, error) {
	namespacesClient := clientset.CoreV1().Namespaces()
	res, err := namespacesClient.List(context.Background(), metav1.ListOptions{})
	if err != nil {
		fmt.Println("Get All Namespace error :", err.Error())
		return nil, err
	}
	fmt.Println("==========================================")
	for _, v := range res.Items {
		fmt.Printf("%s\t%s\n", v.Name, v.CreationTimestamp)
	}
	fmt.Println("==========================================")
	return res, nil
}

// 获取 Secret
func GetSecret(clientset *kubernetes.Clientset, namespaceName string, secretName string) (*corev1.Secret, error) {
	secretClient := clientset.CoreV1().Secrets(namespaceName)
	res, err := secretClient.Get(context.Background(), secretName, metav1.GetOptions{})
	if err != nil {
		fmt.Println("Get Secret error :", err.Error())
		return nil, err
	}
	fmt.Printf("%#v\n", res)
	fmt.Printf("data : %s\n", res.Data["KUBE_CONFIG"])
	return res, nil
}

// 创建Deployment
func CreateDeployment(clientset *kubernetes.Clientset, namespaceName string, objectMateName string, matchLabels map[string]string, objectMetaLabels map[string]string, containerName string, image string, ports []corev1.ContainerPort) (*appsv1.Deployment, error) {
	var replicas int32 = 3
	deployment := &appsv1.Deployment{
		ObjectMeta: metav1.ObjectMeta{
			Name: objectMateName,
		},
		Spec: appsv1.DeploymentSpec{
			Replicas: &replicas,
			Selector: &metav1.LabelSelector{
				MatchLabels: matchLabels,
			},
			Template: corev1.PodTemplateSpec{
				ObjectMeta: metav1.ObjectMeta{
					Labels: objectMetaLabels,
				},
				Spec: corev1.PodSpec{
					Containers: []corev1.Container{
						{
							Name:  containerName,
							Image: image,
							Ports: ports,
						},
					},
				},
			},
		},
	}
	// 创建Deployment资源
	res, err := clientset.AppsV1().Deployments(namespaceName).Create(context.TODO(), deployment, metav1.CreateOptions{})
	if err != nil {
		fmt.Println("Create Deployment error :", err.Error())
		return nil, err
	}
	fmt.Printf("Deployment created successfully %#v\n", res)
	return res, nil
}

// 创建Service
func CreateService(clientset *kubernetes.Clientset, namespaceName string, objectMetaName string, selector map[string]string, ports []corev1.ServicePort) (*corev1.Service, error) {
	service := &corev1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Name: objectMetaName,
		},
		Spec: corev1.ServiceSpec{
			Selector: selector,
			Ports:    ports,
			Type:     corev1.ServiceTypeNodePort,
		},
	}
	// 创建Service资源
	res, err := clientset.CoreV1().Services(namespaceName).Create(context.TODO(), service, metav1.CreateOptions{})
	if err != nil {
		fmt.Println("Create Service error :", err.Error())
		return nil, err
	}
	fmt.Printf("Create Service successfully %#v\n", res)
	return res, nil
}

volcano 客户端

package myvolcano

import (
	"context"
	"fmt"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/tools/clientcmd"
	"volcano.sh/apis/pkg/apis/scheduling/v1beta1"
	volcanov1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1"
	volcanoclient "volcano.sh/apis/pkg/client/clientset/versioned"
)

// https://blog.51cto.com/u_16099347/11106753
// https://zhuanlan.zhihu.com/p/903166664
// 获取 volcano 客户端
func GetVolcanoClient() (*volcanoclient.Clientset, error) {
	kubeconfigPath := "./conf/local_k8s.config"
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
	if err != nil {
		fmt.Printf("Failed to BuildConfigFromFlags from kubeconfig file. filePath: %s, err: %s", kubeconfigPath, err.Error())
		return nil, err
	}
	volcanoClientset, err := volcanoclient.NewForConfig(config)
	if err != nil {
		fmt.Printf("Unable to create a volcano client from kubeconfig file. filePath: %s, err: %s", kubeconfigPath, err.Error())
		return nil, err
	}
	return volcanoClientset, nil
}

const (
	RECLAIMABLE = true // 该queue是否可回收的默认值
	WEIGHT      = 1    // 该queue的默认权重
)

// type VolcanoManager struct {
// 	context context.Context
// }

// func NewVolanoManager(ctx context.Context) *VolcanoManager {
// 	return &VolcanoManager{
// 		context: ctx,
// 	}
// }

// 创建队列
func newQueue(queueName string, reclaimable *bool, weight int32) *volcanov1beta1.Queue {
	queue := &volcanov1beta1.Queue{
		ObjectMeta: metav1.ObjectMeta{
			Name: queueName,
		},
		Spec: volcanov1beta1.QueueSpec{
			Reclaimable: reclaimable,
			Weight:      weight,
			Capability:  v1.ResourceList{},
			Affinity:    &volcanov1beta1.Affinity{},
		},
	}
	return queue
}

// Queue的详情
func GetQueue(volcanoClient *volcanoclient.Clientset, queueName string) (*volcanov1beta1.Queue, error) {
	queue, err := volcanoClient.SchedulingV1beta1().Queues().Get(context.TODO(), queueName, metav1.GetOptions{})
	if err != nil {
		fmt.Println("Get Queue error :", err.Error())
		return nil, err
	}
	fmt.Printf("Get Queue %#v\n", queue)
	return queue, nil
}

// Queue列表
func ListQueue(volcanoClient *volcanoclient.Clientset) (queues []volcanov1beta1.Queue, err error) {
	queueList, err := volcanoClient.SchedulingV1beta1().Queues().List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		fmt.Println("List Queue error :", err.Error())
		return nil, err
	}
	fmt.Printf("Create Queue %#v\n", queueList)
	return queueList.Items, nil
}

// 创建Queue
func CreateQueue(volcanoClient *volcanoclient.Clientset, queueName string, reclaimable *bool, weight int) (*v1beta1.Queue, error) {
	if weight <= 0 {
		weight = WEIGHT
	}
	var tempReclaimable = RECLAIMABLE
	if reclaimable == nil {
		reclaimable = &tempReclaimable
	}
	var queue *volcanov1beta1.Queue = newQueue(queueName, reclaimable, int32(weight))
	res, err := volcanoClient.SchedulingV1beta1().Queues().Create(context.TODO(), queue, metav1.CreateOptions{})
	if err != nil {
		fmt.Println("Create Queue error :", err.Error())
		return nil, err
	}
	fmt.Printf("Create Queue %s on %s\n", res.ObjectMeta.Name, res.ObjectMeta.CreationTimestamp)
	return res, nil
}

// 删除Queue
func DeleteQueue(volcanoClient *volcanoclient.Clientset, queueName string) (err error) {
	err = volcanoClient.SchedulingV1beta1().Queues().Delete(context.TODO(), queueName, metav1.DeleteOptions{})
	if err != nil {
		fmt.Println("Delete Queue error :", err.Error())
		return err
	}
	fmt.Print("删除成功")
	return nil
}


;