A client – go
Recently, there is a need to carry out custom integration of some data of K8S. Client-go can be used to realize the demand quickly and conveniently. In K8S operation and maintenance, we can use Kubectl, client library or REST request to access K8S API. 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.
The introduction of
Chart 2.1
As can be seen from the figure above, there are four types of clients in client-GO, ClientSet, DynamicClient and DiscoveryClient, which are all concrete implementations of RestClient.
2.2 Directory Structure
# tree client-go/ -L 1
client-go/
├ ─ ─ discovery
├ ─ ─ dynamic
├ ─ ─ informers
├ ─ ─ kubernetes
├ ─ ─ listers
├ ─ ─ plugin
├ ─ ─ rest
├ ─ ─ scale
├ ─ ─ tools
├ ─ ─ transport
└ ─ ─ util
Copy the code
discovery
: provideDiscoveryClient
Discovering clientsdynamic
: provideDynamicClient
Dynamic clientinformers
: Informer implementation of each Kubernetes resourcekubernetes
: provideClientSet
The clientlisters
: Provides Lister functionality for each Kubernetes resource, which provides read-only cached data for Get and List requestsplugin
: Provides plug-ins for OpenStack, GCP, and Azurerest
: provideRESTClient
On the client, RESTful operations are performed on the Kubernetes API Serverscale
: provideScaleClient
The client is used to expand or shrink Deployment, ReplicaSet, and RelasController resource objectstools
: Provides common tools such as SharedInformer, Reflector, DealtFIFO, and Indexers. Provide Client query and caching mechanism to reduce the number of requests to kube-Apiserver, etctransport
: Provides secure TCP connections and supports Http Stream. Some operations require transferring binary streams between the client and the container, such as exec and ATTACH. This functionality is supported by the internal SPDY packageutil
: Provides common methods, such as WorkQueue and Certificate management
Three certification
It is worth mentioning here that there is a small hole when go mod connects to K8S through go Client. That is, we need to specify the K8S version in the Go mod file, otherwise the latest K8S version package will be pulled by default. We also know that the API of different K8S versions will be different
3.1 certified
3.1.1 token
# APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
# TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o # jsonpath='{.data.token}' | base64 --decode )
# curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
Copy the code
Four types of client-go
4.1 the RestClient
RestClient is the most basic client. RestClient is encapsulated based on HTTP Request and implements restful API. You can directly pass the restful methods provided by RestClient, such as Get(), Put(), Post(), Delete() interacts with Json and Protobuf, supports all native resources and CRDs, but generally, for more elegant processing, you need to further encapsulate RESTClient through Clientset, and then provide interfaces and services externally.
package main
import (
"fmt"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
var configFile = ".. /config"
var ApiPath = "api"
var nameSpace = "kube-system"
var resouce = "pods"
func main(a) {
/ / generated config
config, err := clientcmd.BuildConfigFromFlags("", configFile)
iferr ! =nil {
panic(err)
}
config.APIPath = ApiPath
config.GroupVersion = &corev1.SchemeGroupVersion
config.NegotiatedSerializer = scheme.Codecs
/ / generated restClient
restClient, err := rest.RESTClientFor(config)
iferr ! =nil {
panic(err)
}
// Declare an empty structure
rest := &corev1.PodList{}
if err = restClient.Get().Namespace(nameSpace).Resource("pods").VersionedParams(&metav1.ListOptions{Limit: 500}, scheme.ParameterCodec).Do().Into(rest); err ! =nil {
panic(err)
}
for _, v := range rest.Items {
fmt.Printf("NameSpace: %v Name: %v Status: %v \n", v.Namespace, v.Name, v.Status.Phase)
}
}
Copy the code
4.2 ClientSet
A Resource can be understood as a client, while a ClientSet is a collection of multiple clients
To operate a Resource object, clientSet needs to specify a Group, specify a Version, and then obtain it based on the Resource. However, ClientSet does not support custom CRDS.
package main
import (
"flag"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
)
// ~/.kube/config
func ParseConfig(configPath string) (*kubernetes.Clientset, error) {
var kubeconfigPath *string
ifhome := homedir.HomeDir(); home ! ="" {
kubeconfigPath = flag.String("kubeconfig", filepath.Join(home, ".kube"."config"), "(optional) absolute path to the kubeconfig file")}else {
kubeconfigPath = flag.String("kubeconfig", configPath, "absolute path to the kubeconfig file")
}
flag.Parse()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfigPath)
iferr ! =nil {
return nil, err
}
/ / generated clientSet
clientSet, err := kubernetes.NewForConfig(config)
iferr ! =nil {
return clientSet, err
}
return clientSet, nil
}
func ListCm(c *kubernetes.Clientset, ns string) error {
configMaps, err := c.CoreV1().ConfigMaps(ns).List(metav1.ListOptions{})
iferr ! =nil {
return err
}
for _, cm := range configMaps.Items {
fmt.Printf("configName: %v, configData: %v \n", cm.Name, cm.Data)
}
return nil
}
func ListNodes(c *kubernetes.Clientset) error {
nodeList, err := c.CoreV1().Nodes().List(metav1.ListOptions{})
iferr ! =nil {
return err
}
for _, node := range nodeList.Items {
fmt.Printf("nodeName: %v, status: %v", node.GetName(), node.GetCreationTimestamp())
}
return nil
}
func ListPods(c *kubernetes.Clientset, ns string) {
pods, err := c.CoreV1().Pods(ns).List(metav1.ListOptions{})
iferr ! =nil {
panic(err)
}
for _, v := range pods.Items {
fmt.Printf("namespace: %v podname: %v podstatus: %v \n", v.Namespace, v.Name, v.Status.Phase)
}
}
func ListDeployment(c *kubernetes.Clientset, ns string) error {
deployments, err := c.AppsV1().Deployments(ns).List(metav1.ListOptions{})
iferr ! =nil {
return err
}
for _, v := range deployments.Items {
fmt.Printf("deploymentname: %v, available: %v, ready: %v", v.GetName(), v.Status.AvailableReplicas, v.Status.ReadyReplicas)
}
return nil
}
func main(a) {
var namespace = "kube-system"
configPath := ".. /config"
config, err := ParseConfig(configPath)
iferr ! =nil {
fmt.Printf("load config error: %v\n", err)
}
fmt.Println("list pods")
ListPods(config, namespace)
fmt.Println("list cm")
iferr = ListCm(config, namespace); err ! =nil {
fmt.Printf("list cm error: %v", err)
}
fmt.Println("list nodes")
iferr = ListNodes(config); err ! =nil {
fmt.Printf("list nodes error: %v", err)
}
fmt.Println("list deployment")
iferr = ListDeployment(config, namespace); err ! =nil {
fmt.Printf("list deployment error: %v", err)
}
}
Copy the code
4.3 DynamicClient
DynamicClient is a dynamic client that can perform restful operations on any resource including CRD custom resources. Unlike clientset, dynamic Client returns a map[string]interface{}. If you need to control all the apis in one controller, you can use the Dynamic Client, which is currently used in the Garbage Collector and namespace Controller. DynamicClient converts a Resource, such as a Podlist, to an unstructured type. All resources in k8s can be converted to this type and then converted to a Podlist. The entire transformation process is similar to the interface transformation through the assertion of interface{}.
Dynamic Client is a Dynamic client, which can handle all kubernetes resources, only support JSON.
package main
import (
"fmt"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/tools/clientcmd"
)
var namespace = "kube-system"
func main(a) {
config, err := clientcmd.BuildConfigFromFlags("".".. /config")
iferr ! =nil {
panic(err)
}
dynamicClient, err := dynamic.NewForConfig(config)
iferr ! =nil {
panic(err)
}
// Define group version resources
gvr := schema.GroupVersionResource{Version: "v1", Resource: "pods"}
unStructObj, err := dynamicClient.Resource(gvr).Namespace(namespace).List(metav1.ListOptions{})
iferr ! =nil {
panic(err)
}
podList := &apiv1.PodList{}
iferr = runtime.DefaultUnstructuredConverter.FromUnstructured(unStructObj.UnstructuredContent(), podList); err ! =nil {
panic(err)
}
for _, v := range podList.Items {
fmt.Printf("namespaces:%v name:%v status:%v \n", v.Namespace, v.Name, v.Status.Phase)
}
}
Copy the code
4.4 DiscoveryClient
The DiscoveryClient is used to discover resource groups and resource versions supported by the API Server. The K8S API Server supports many resource groups and resource versions. In this case, you can use the DiscoveryClient to view resource information
Kubectl api-version and api-resource are also implemented through the DiscoveryClient, and the information can be cached in the local cache to reduce the API access pressure. The default values are./kube/cache and./kube/http-cache.
package main
import (
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/clientcmd"
)
func main(a) {
config, err := clientcmd.BuildConfigFromFlags("".".. /config")
iferr ! =nil {
panic(err)
}
discoverClient, err := discovery.NewDiscoveryClientForConfig(config)
iferr ! =nil {
panic(err)
}
_, apiResourceList, err := discoverClient.ServerGroupsAndResources()
for _, v := range apiResourceList {
gv, err := schema.ParseGroupVersion(v.GroupVersion)
iferr ! =nil {
panic(err)
}
for _, resource := range v.APIResources {
fmt.Println("name:", resource.Name, ""."group:", gv.Group, ""."version:", gv.Version)
}
}
}
Copy the code
Five other
Learn client-GO, which can be used to operate k8S cluster resources conveniently. Kubeconfig →rest.config→clientset→ specific client(CoreV1Client)→ specific resource object (POD)→RESTClient→ HTTP.Client→HTTP request sending and response
Through the clientset of different clients and different resource objects in the client method to achieve kubernetes resource objects in the addition, deletion, change and query operations, Common clients include CoreV1Client, AppsV1beta1Client, ExtensionsV1beta1Client and so on.
In this paper, simple use of client-Go to achieve simple K8S resource operations, later use such as KubeBuilder and operator-SDK to write operator also needs in-depth understanding and learning of client-go. In the later stage, I will continue to study in depth.
Refer to the link
- www.voidking.com/dev-k8s-cli…
- Godoc.org/k8s.io/clie…
- Github.com/kubernetes/…
- PKG. Go. Dev/k8s. IO/clie…
- Zhuanlan.zhihu.com/p/202611841…