前面我们已经基本了解cobra的使用方法,现在我们去简单做一个小工具加深印象

 构建命令kubectl

cobra init kubectl

修改配置

vi root.go

package cmd

import (
	"fmt"
	"github.com/spf13/cobra"
	"os"
	"path/filepath"
)



//定义一下主体命令变量
var rootCmd = &cobra.Command{
	Use:   "kubectl",
	Args:  cobra.MinimumNArgs(1), //防止用户只使用kubectl命令导致卡死,这里设置必须要设置一个参数才可使用
	Short: "",
	Long: ``,
	Run: func(cmd *cobra.Command, args []string) {

	},

}

//我们想要用kubectl 去调用K8S集群,需要携带集群的kubeconfig配置
var Kubeconfig string

func init() {
	//利用主体变量去全局接收 携带的kubeconfig配置
	rootCmd.PersistentFlags().StringVar(&Kubeconfig, "kubeconfig", "", "$HOME/.kube/config")
}

//接收上面获取参数的Kubeconfig变量,去判断是否有效
func Initnode() string {

	//下面的逻辑就是去查询用户有没有输入kubeconfig 的配置文件
	//如果没有输入,则默认去$HOME/.kube/config 去找认证文件,如果都没有则退出
	if Kubeconfig == "" {
		if home := os.Getenv("HOME"); home != ""{
			Kubeconfig = filepath.Join(home, ".kube", "config")  //如果为空则填入我们设置好的路径
			Kubeconfig = filepath.ToSlash(Kubeconfig)     //将路径里面的斜杠转为正斜杠
			_,err := filepath.EvalSymlinks(Kubeconfig)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}else {
				return Kubeconfig
			}
		}else {
			fmt.Println("没有找到kubeconfig文件、没有找到用户家目录,请确认操作系统是否为linux")
			os.Exit(1)
		}

	}else {
		//当判断用户输入文件路径后,查询该文件路径是否正确,如果不正确,则返回错误信息
		_,err := filepath.EvalSymlinks(Kubeconfig)
		if err != nil {
			fmt.Println("kubeconfig所指定的文件不存在,或格式有问题,程序退出")
			os.Exit(1)
		}else {
			return Kubeconfig
		}

	}
	return ""
}







func Execute() {
	cobra.CheckErr(rootCmd.Execute())  //入口
}

给kubectl命令 添加子命令

cobra add get -p rootCmd

vi get.go

package cmd

import (
	"github.com/spf13/cobra"
)

var getCmd = &cobra.Command{
	Use:   "get",
	Args:  cobra.MinimumNArgs(1),   //添加
	Short: "",
	Long: ``,
	Run: func(cmd *cobra.Command, args []string) {  //添加
		
	},

}

func init() {
	rootCmd.AddCommand(getCmd)

}

为get子命令添加node、pod、svc子命令

cobra add node -p getCmd 
cobra add svc -p getCmd 
cobra add pod -p getCmd 

1、添加node查询

vi node.go

package cmd

import (
	"context"
	"fmt"
	"github.com/spf13/cobra"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
)


var nodeCmd = &cobra.Command{
	Use:   "node",
	Short: "",
	Long: ``,
	Run: connectnode,  //当访问node资源时,直接调用connectnode函数即可
}



//获取集群node信息函数
func connectnode(cmd *cobra.Command, args []string){

	kubeconfig := Initnode()
	var Kconfig *string
	Kconfig = &kubeconfig


	//通过client-go包去链接K8集群
	//需要传入master地址或者kubeconfig的路径
	config, err := clientcmd.BuildConfigFromFlags("", *Kconfig)
	errorsf(err)


	//创建一个客户端链接
	clientset, err := kubernetes.NewForConfig(config)     //链接k8的rest接口后,我们会得到一个内存地址的切片
	errorsf(err)                                          //切片的每个数据都是一个接口


	//通过clientset去获取node信息
	nodes,err := clientset.CoreV1().Nodes().List(context.TODO(),v1.ListOptions{})

	//过滤Items下的数据,也就是3个节点的json信息
	nodess := nodes.Items

	fmt.Printf("\nThere are %d namespaces in cluster\n", len(nodess))

	for _, ns := range nodess {  //将3个node节点的json切片遍历出来
		                         //ns中存放的就是单个node的详细信息

		fmt.Printf(
			"Name: %s," +
				" Status: %s," +
				" CreateTime: %s" +
				"\n",

			ns.ObjectMeta.Name,           //将单个节点下的信息打印出来
			ns.Status.Addresses[0].Address,
			ns.CreationTimestamp)
	}
	if err != nil {
		log.Println("err ===> ", err)
	}

}


//处理上面的一堆错误检查
func errorsf(err error)  {
	if err != nil {
		panic(err.Error())
	}
}



func init() {
	getCmd.AddCommand(nodeCmd)
}

测试

go run main.go get node --kubeconfig=D:\go_setup\go1.17\src\go_code\kubectl\config

//这里我把虚拟机的kubeconfig文件拷贝下来了

返回

There are 3 namespaces in cluster
Name: k8s-master01, Status: 192.168.1.20, CreateTime: 2020-03-21 10:41:36 +0800 CST
Name: k8s-node01, Status: 192.168.1.21, CreateTime: 2020-03-21 11:03:35 +0800 CST
Name: k8s-node02, Status: 192.168.1.22, CreateTime: 2020-03-21 11:03:38 +0800 CST

2、添加pod查询

pod.go

/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
	"context"
	"fmt"
	"github.com/spf13/cobra"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
)

// podCmd represents the pod command
var podCmd = &cobra.Command{
	Use:   "pod",
	Short: "",
	Long: ``,
	Run: connectPod ,
}


//获取集群node信息函数
func connectPod(cmd *cobra.Command, args []string){

	//前面链接的语法是相同的,后面可以把这些放在一个函数中
	kubeconfig := Initnode()
	var Kconfig *string
	Kconfig = &kubeconfig

	config, err := clientcmd.BuildConfigFromFlags("", *Kconfig)
	errorsf(err)
	clientset, err := kubernetes.NewForConfig(config)
	errorsf(err)


	//通过clientset去获取default 下的pod信息
	pod,err := clientset.CoreV1().Pods("default").List(context.TODO(),v1.ListOptions{})



    //抄作业
    pods := pod.Items


    //遍历所有的pod信息
	for _, ns := range pods {

		fmt.Println(ns.ObjectMeta.Name,  //pod名称
			ns.ObjectMeta.Labels,        //pod标签
			ns.ObjectMeta.Namespace,     //命名空间
			ns.Spec.Containers[0].Name,  //控制器名称
			ns.Spec.Containers[0].ImagePullPolicy,  //镜像拉取策略
			ns.Spec.Containers[0].Image,      //镜像名称
			)

	}

	if err != nil {
		log.Println("err ===> ", err)
	}

}



func init() {
	getCmd.AddCommand(podCmd)

}

测试

go run main.go get pod --kubeconfig=D:\go_setup\go1.17\src\go_code\kubectl\config

3、编写svc

vi svc.go

package cmd

import (
	"context"
	"fmt"
	"github.com/spf13/cobra"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"log"
)


var svcCmd = &cobra.Command{
	Use:   "svc",
	Short: "",
	Long: ``,
	Run: connectSvc ,
}

func init() {
	getCmd.AddCommand(svcCmd)
}



//定义svc查询
func connectSvc(cmd *cobra.Command, args []string){

	//前面链接的语法是相同的,后面可以把这些放在一个函数中
	kubeconfig := Initnode()
	var Kconfig *string
	Kconfig = &kubeconfig
	config, err := clientcmd.BuildConfigFromFlags("", *Kconfig)
	errorsf(err)
	clientset, err := kubernetes.NewForConfig(config)
	errorsf(err)




	//通过clientset去获取default 下的pod信息
	svc,err := clientset.CoreV1().Services("default").List(context.TODO(),v1.ListOptions{})



	//抄作业
	svcs := svc.Items

	//fmt.Println(svcs)


	//遍历所有的pod信息
	for _, ns := range svcs {

		fmt.Println(ns.ObjectMeta.Name,  //svc名称
			ns.ObjectMeta.Labels,        //svc标签
			ns.Spec.Type,          //svc类型
			ns.Spec.Ports[0].NodePort,
			ns.Spec.Ports[0].Port,

		)

	}

	if err != nil {
		log.Println("err ===> ", err)
	}

}

打包文件linux运行

SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64

#打包
go build -o kubectl .

上传K8集群测试

K8集群上$HOME/.kube/config 有配置默认会读取,无需手动配置

 自制工具查看

 感觉一对比我的好丑555(っ °Д °;)っ

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐