“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

A background

When we use Kubectl to view K8S resources, want to directly view the corresponding resource container name and image name, currently Kubectl does not support the selection, we need to describe and then to view, for the cluster itself is more, not very convenient, so I developed my own Kubectl plug-in to achieve this function.

Two correlation technology

2.1 Cobra

Cobra is a command-line library, which is an artifact for writing command lines and provides a scaffolding for quickly generating Cobra based application frameworks. We can use Cobra to quickly develop the command-line tools we want, very quickly.

For more information, please refer to: Golang’s Initial Cobra study

2.2 the Client – go

In K8s operations, we can access the K8s API using Kubectl, client libraries, or REST requests. In fact, both Kubectl and the client libraries are tools that encapsulate REST requests. As a client library, client-go can invoke THE K8S API to add, delete, modify, and check resource objects (including Deployment, service, Ingress, replicaSet, POD, Namespace, and node) in the K8S cluster.

Detailed reference: K8s two open client-GO preliminary study

2.3 K8S plug-in krew

Krew is a kubectl plug-in package management tool similar to system APT, DNF or BREW, which can easily complete the whole cycle management of Kubectl plug-ins, including search, download, uninstall and so on.

Kubectl’s tools have been perfected, but for some personalized commands, the goal is to allow developers to publish custom Kubectl subcommands in a stand-alone, intense form. The plug-in is developed in any language, and the final step or binary executable needs to be named with the prefix kubectl-. You can use the Kubectl Plugin list to view the plugins that have been installed.

Detailed reference: K8S plug-in management tool kreW use

Three plug-in planning

  • The plug-in is named kubeimg.
  • Only a simple implementation of a image command, to see different resource objects (deployments/daemonsets/statefulsets/jobs/cronjobs) name, and the corresponding container name, the name of the mirror.
  • Supports output in JSON format.
  • Finally, use it as a Krew plug-in.
  • Resources can be viewed directly by their namespaces.

Four actual combat development

4.1 Project Initialization

  • Install the cobra
go get -v github.com/spf13/cobra/cobra 
Copy the code
  • Initialize the project
 $~ / workspace/goworkspace/src/github.com/kaliarch/kubeimg  / Users/xuel/workspace/goworkspace/bin/cobra init - PKG - name kubeimg
Your Cobra application is ready at
/Users/xuel/workspace/goworkspace/src/github.com/kaliarch/kubeimg
$~ / workspace/goworkspace/src/github.com/kaliarch/kubeimg  ls
LICENSE cmd     main.go
$~ / workspace/goworkspace/src/github.com/kaliarch/kubeimg  tree├── CMD │ ├─ class.go ├─ key.go 1 file, 3 filesCopy the code
  • Create the Go mod and download the package
go mod init kubeimg
Copy the code

4.2 Adding subcommands

Add a subcommand image.

$ /Users/xuel/workspace/goworkspace/bin/cobra add image
image created at /Users/xuel/workspace/goworkspace/src/github.com/kaliarch/kubeimg
Copy the code

4.3 Adding Parameters


// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(a) {
	cobra.CheckErr(rootCmd.Execute())
}

func init(a) {
	KubernetesConfigFlags = genericclioptions.NewConfigFlags(true)
	imageCmd.Flags().BoolP("deployments"."d".false."show deployments image")
	imageCmd.Flags().BoolP("daemonsets"."e".false."show daemonsets image")
	imageCmd.Flags().BoolP("statefulsets"."f".false."show statefulsets image")
	imageCmd.Flags().BoolP("jobs"."o".false."show jobs image")
	imageCmd.Flags().BoolP("cronjobs"."b".false."show cronjobs image")
	imageCmd.Flags().BoolP("json"."j".false."show json format")
	KubernetesConfigFlags.AddFlags(rootCmd.PersistentFlags())
}
Copy the code

4.4 Implementing the image command

var imageCmd = &cobra.Command{
	Use:   "image",
	Short: "show resource image",
	Long:  `show k8s resource image`,
	RunE:  image,
}

func init(a) {
	rootCmd.AddCommand(imageCmd)
}
Copy the code

4.5 Initializing a ClientSet

// ClientSet k8s clientset
func ClientSet(configFlags *genericclioptions.ConfigFlags) *kubernetes.Clientset {
	config, err := configFlags.ToRESTConfig()
	iferr ! =nil {
		panic("kube config load error")
	}
	clientSet, err := kubernetes.NewForConfig(config)
	iferr ! =nil {

		panic("gen kube config error")}return clientSet
}

Copy the code

4.6 Viewing resource Objects

You can use reflection to view resource mirrors and mirror names based on different resource types.

func image(cmd *cobra.Command, args []string) error {

	clientSet := kube.ClientSet(KubernetesConfigFlags)
	ns, _ := rootCmd.Flags().GetString("namespace")
	// Live a list of global resources
	var rList []interface{}

	if flag, _ := cmd.Flags().GetBool("deployments"); flag {
		deployList, err := clientSet.AppsV1().Deployments(ns).List(context.Background(), v1.ListOptions{})
		iferr ! =nil {
			fmt.Printf("list deployments error: %s", err.Error())
		}
		rList = append(rList, deployList)
	}
  ...
  	deployMapList := make([]map[string]string.0)
	for i := 0; i < len(rList); i++ {
		switch t := rList[i].(type) {
		case *kv1.DeploymentList:
			for k := 0; k < len(t.Items); k++ {
				for j := 0; j < len(t.Items[k].Spec.Template.Spec.Containers); j++ {
					deployMap := make(map[string]string)
					deployMap["NAMESPACE"] = ns
					deployMap["TYPE"] = "deployment"
					deployMap["RESOURCE_NAME"] = t.Items[k].GetName()
					deployMap["CONTAINER_NAME"] = t.Items[k].Spec.Template.Spec.Containers[j].Name
					deployMap["IMAGE"] = t.Items[k].Spec.Template.Spec.Containers[j].Image
					deployMapList = append(deployMapList, deployMap)
				}
			}
Copy the code

4.6 Output

Use tabel to output the results


func GenTable(mapList []map[string]string) *table.Table {
	t, err := gotable.Create(title...)
	iferr ! =nil {
		fmt.Printf("create table error: %s", err.Error())
		return nil
	}
	t.AddRows(mapList)
	return t
}

Copy the code

Final Project structure:

Five test

Test the completed plug-in and compile the Go build to generate the Kubeimg binary executable.

5.1 Viewing Help information

  • See all help

You can see that Cobra automatically generates help and Completion commands to quickly complete the table, and supports bash/fish/ ZSH/Powershell

./kubeimg --help
Copy the code

  • View the image command flags
./kubeimg image --help
Copy the code

5.1 Viewing Deployment Resources

Unknowingly ing namespaces, default view all resources under namespaces

./kubeimg image -d
Copy the code

5.2 Viewing resources in a Namespace

./kubeimg image -d -n kube-system
Copy the code

5.3 Viewing All Resources

You can see that imlc-operator-controller-Manager has two containers in a pod.

./kubeimg image -b -e -d -o -f
Copy the code

5.4 Output in JSON format

./kubeimg image -o -j
Copy the code

Use as a KREw plug-in

You need to name the final footstep or binary executable with the prefix kubectl- and place it in the PATH. You can use the Kubectl Plugin list to see what plugins have been installed so far.

$ kubectl plugin listThe following compatible plugins are available:= /usr/local/bin/kubectl-debug - warning: kubectl-debug overwrites existing command: "Kubectl debug"/usr/local/bin/kubectl v1.10.11 / usr/local/bin/kubectl - v1.20.0 / Users/xuel /. Krew/bin/kubectl - df_pv /Users/xuel/.krew/bin/kubectl-krew
#Rename your plug-in to Kubectl-img and place it under the executable roadbed
$ cp kubeimg /Users/xuel/.krew/bin/kubectl-img

$ kubectl plugin listThe following compatible plugins are available:= /usr/local/bin/kubectl-debug - warning: kubectl-debug overwrites existing command: "Kubectl debug"/usr/local/bin/kubectl v1.10.11 / usr/local/bin/kubectl - v1.20.0 / Users/xuel /. Krew/bin/kubectl - df_pv /Users/xuel/.krew/bin/kubectl-krew /Users/xuel/.krew/bin/kubectl-img
$ cp kubeimg /Users/xuel/.krew/bin/kubectl-img

Copy the code

Then you can use it as you would the Kubectl plug-in.

other

At present, the implementation is relatively simple, in order to throw a brick to attract jade function, later can carry out more functions or other plug-in development, their own hands have plenty of food and clothing.

After looking forward to improving the open source to Github, personal homepage: Github, for everyone to learn and communicate.

Refer to the link

  • Juejin. Cn/post / 696918…
  • Juejin. Cn/post / 696286…
  • github.com/spf13/cobra