Welcome to my GitHub

Github.com/zq2599/blog…

Content: all original article classification summary and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;

Links to articles

  1. Client-go: Preparation
  2. Client-go Actual combat 2 :RESTClient
  3. Client go: Clientset
  4. Client-go: dynamicClient
  5. Client-go Combat 5: Discover Client

This paper gives an overview of

  • This is the second part of the “Client-Go In Action” series. As mentioned earlier, there are four types of client-Go clients: RESTClient, ClientSet, DynamicClient, DiscoveryClient. RESTClient is the most basic version. The other three are based on RESTClient. Familiar with basic remote operation procedures;
  • This article is composed of the following parts:
  1. Brief introduction to the RESTClient
  2. Preparation before each coding
  3. Formal code
  4. validation
  5. Critical source code analysis

Introduction of the RESTClient

  • RESTClient is the most basic client of Client-Go. It encapsulates HTTP Reqeust and provides RESTful apis and rich apis for various Settings. Compared with other clients, RESTClient is more complex but more flexible.
  • The basic procedure for adding, deleting, modifying, and querying kubernetes resources using RESTClient is as follows:
  1. Determine the type of resource to operate on (e.g., look for deployment list), go to the official API documentation to find the appropriate path, data structure, etc., which will be used later;
  2. Load the kubernetes configuration file (exactly the same as kubeconfig used by Kubectl);
  3. Generate configuration objects from the configuration file and set them through the API (such as path, Group, Version, serialization deserialization tool, etc.);
  4. Create a RESTClient instance with configuration objects as input.
  5. Call the method of RESTClient instance to make a request to KUbernetes API Server, code in Fluent style to pass various parameters (such as specifying namespace, resources, etc.), if it is a query class request, also pass the pointer to the data structure instance. Change the data structure used to accept kubernetes returned query results;
  • The next coding actual combat is carried out in accordance with the above process;

Actual content

  • This practice content is very simple: query kube-system under the namespace of all pod, and then print several key fields of each POD on the console;
  • Thank you for your patience to listen to me a lot of wordy, next start actual combat;

Download the source code

  • The source code for this article can be downloaded on GitHub, with the address and link information shown in the following table (github.com/zq2599/blog…
The name of the link note
Project home page Github.com/zq2599/blog… The project’s home page on GitHub
Git repository address (HTTPS) Github.com/zq2599/blog… The project source warehouse address, HTTPS protocol
Git repository address (SSH) [email protected]:zq2599/blog_demos.git The project source warehouse address, SSH protocol
  • The Git project has multiple folders. Client-go related applications are in the client-go-tutorials folder, as shown in the red box below:

  • Client-go-tutorials have multiple sub-folders under the folder. The source code for this section is in the restClientdemo directory, as shown in the red box below:

Check the official documentation for the content required for coding

  • Browser to open the official API documentation, address: v1-19. Docs. Kubernetes. IO/docs/refere…

  • Find the POD API documentation, as shown below, and determine the path and namespace parameters:

  • Then you also have to focus on the data structure of the response, as shown in the red box below:

  • Click in the red box above to see the details of the PodList, which is the data structure we need to code:

  • With the details of the request and response, you can start coding;

coding

  • Create a new folder, RestclientDemo, and run the following command to create a new Module:
go mod init restclientdemo
Copy the code
  • Add k8s. IO/API and k8s. IO /client-go dependencies to kubernetes:
Go get k8s. IO /[email protected] go get k8s. IO /[email protected]Copy the code
  • Create a new main.go file and it will look like this.
package main

import (
	"context"
	"flag"
	"fmt"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"path/filepath"
)

func main(a) {
	var kubeconfig *string

	// home is the home directory. If you can get the value of the home directory, you can use it as the default value
	ifhome:=homedir.HomeDir(); home ! ="" {
		// Kubeconfig is the absolute path to the kubeconfig file.
		// If the kubeconfig parameter is not entered, the default path ~/.kube/config is used
		kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube"."config"), "(optional) absolute path to the kubeconfig file")}else {
		// If the current user's home directory is not available, there is no way to set the kubeconFig default directory, only from the input parameter
		kubeconfig = flag.String("kubeconfig".""."absolute path to the kubeconfig file")
	}

	flag.Parse()

	// Load the KubeconFig configuration file from native, so the first argument is an empty string
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)

	// Kubeconfig failed to load
	iferr ! =nil {
		panic(err.Error())
	}

	// see path: / API /v1/namespaces/{namespace}/ Pods
	config.APIPath = "api"
	// POD group is an empty string
	config.GroupVersion = &corev1.SchemeGroupVersion
	// Specify the serialization tool
	config.NegotiatedSerializer = scheme.Codecs

	// Build the restClient instance based on the configuration information
	restClient, err := rest.RESTClientFor(config)

	iferr! =nil {
		panic(err.Error())
	}

	// Save the pod result data structure instance
	result := &corev1.PodList{}

	/ / specify the namespace
	namespace := "kube-system"
	// Set the request parameters and initiate the request
	/ / GET request
	err = restClient.Get().
		// To specify a namespace, see path: / API /v1/namespaces/{namespace}/ Pods
		Namespace(namespace).
		// See path: / API /v1/namespaces/{namespace}/ Pods
		Resource("pods").
		// Specify size limits and serialization tools
		VersionedParams(&metav1.ListOptions{Limit:100}, scheme.ParameterCodec).
		/ / request
		Do(context.TODO()).
		// Save the result to result
		Into(result)

	iferr ! =nil {
		panic(err.Error())
	}

	/ / headers
	fmt.Printf("namespace\t status\t\t name\n")

	// Each pod prints the namespace, status.Phase, and name fields
	for _, d := range result.Items {
		fmt.Printf("%v\t %v\t %v\n",
			d.Namespace,
			d.Status.Phase,
			d.Name)
	}
}

Copy the code
  • After the coding is complete, run go run main.go to obtain the information of all pods under the specified namespace. The console output is as follows:
(base) zhaoqindeMBP:restclientdemo zhaoqin$ go run main.go
namespace	 status		 name
kube-system	 Running	 coredns-7f89b7bc75-5pdwc
kube-system	 Running	 coredns-7f89b7bc75-nvbvm
kube-system	 Running	 etcd-hedy
kube-system	 Running	 kube-apiserver-hedy
kube-system	 Running	 kube-controller-manager-hedy
kube-system	 Running	 kube-flannel-ds-v84vc
kube-system	 Running	 kube-proxy-hlppx
kube-system	 Running	 kube-scheduler-hedy
Copy the code
  • At this point, the RESTClient client is complete from coding to validation;

How do I deserialize received data into a PodList object?

  • The previous code is fairly simple, but there is one thing that interests me: As shown in the red box below, result is a pointer to a structure of type corev1.PodList, and restClient receives the data from Kubernetes, How do I know to deserialize data to corev1.PodList (Into has runtime.object)?

  • Before the code set up a line of decoding tools: config. NegotiatedSerializer = scheme. Codecs, expand the scheme, Codecs, visible Settings determine the serialization tool to the runtime. Serializer:

  • The typer field type for Serializer is Runtime. ObjectTyper. PodList: PodList: PodList:

  • With this GVK will determine the type of data returned, the final call caseSensitiveJSONIterator. Unmarshal (data, obj) to complete the byte array object deserialization operation:

  • Finally, there is a key line of code that writes the contents of data to the outermost input parameter of the Into method:

  • Source code analysis completed, in simple terms, in addition to the use of reflection to obtain the actual type, there is Scheme internal maintenance of data types and GVK relational mapping table;
  • At this point, you’re done with RESTClient. Hopefully, this article will help you lay the groundwork so that you know the underlying implementation principles when you experience the other three clients.

You are not alone, Xinchen original accompany all the way

  1. Java series
  2. Spring series
  3. The Docker series
  4. Kubernetes series
  5. Database + middleware series
  6. The conversation series

You are not alone, Xinchen original accompany all the way

  1. Java series
  2. Spring series
  3. The Docker series
  4. Kubernetes series
  5. Database + middleware series
  6. The conversation series

Welcome to pay attention to the public number: programmer Xin Chen

Wechat search “programmer Xin Chen”, I am Xin Chen, looking forward to enjoying the Java world with you…

Github.com/zq2599/blog…