client go for k8s

master
dustoair 3 years ago
commit 8936876cee

3
.gitignore vendored

@ -0,0 +1,3 @@
.idea
go.sum
nogit.*

@ -0,0 +1,117 @@
package ClientSet
import (
"ClientGo/utils"
"context"
"fmt"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"log"
"reflect"
)
/**
@author: sre
@date: 2022/8/10 0010
@desc: RESTClient Kubernetes 使便 Kubernetes APIServer
ClientSet RESTClient ClientSet 使 API APIServer 便
ClientSet PodsServices CoreV1Client DeploymentsDaemonSets AppsV1Client Kubernetes CreateUpdateGetListDelete
**/
// GetClientSet ClientSet 是一组资源对象客户端的集合,例如负责操作 Pods、Services 等资源的 CoreV1Client负责操作 Deployments、DaemonSets 等资源的 AppsV1Client 等。
// 通过这些资源对象客户端提供的操作方法,即可对 Kubernetes 内置的资源对象进行 Create、Update、Get、List、Delete 等操作。
func GetClientSet() (*kubernetes.Clientset, error) {
config, err := utils.GetConfig()
if err != nil {
log.Println("GetConfig 失败: ", err.Error())
return nil, err
}
// 实例化 ClientSet
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Println("实例化 ClientSet 失败: ", err.Error())
return nil, err
}
return clientset, nil
}
// ListCms 列出所有的 ConfigMap
func ListCms(namespace string) (*v1.ConfigMapList, error) {
clientSet, err := GetClientSet()
if err != nil {
log.Println("GetClientSet 失败: ", err.Error())
return nil, err
}
configMaps, err := clientSet.CoreV1().ConfigMaps(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
return configMaps, err
//for _, cm := range configMaps.Items {
// fmt.Printf("configName: %v, configData: %v \n", cm.Name, cm.Data)
//}
//return nil
}
func ListNodes() (*v1.NodeList, error) {
clientSet, err := GetClientSet()
if err != nil {
log.Println("GetClientSet 失败: ", err.Error())
return nil, err
}
nodeList, err := clientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
return nodeList, err
//for _, node := range nodeList.Items {
// fmt.Printf("nodeName: %v, status: %v", node.GetName(), node.GetCreationTimestamp())
//}
//return nil
}
func ListPods(namespace string) (*v1.PodList, error) {
clientSet, err := GetClientSet()
if err != nil {
log.Println("GetClientSet 失败: ", err.Error())
return nil, err
}
pods, err := clientSet.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
return pods, nil
//for _, v := range pods.Items {
// fmt.Printf("namespace: %v podname: %v podstatus: %v \n", v.Namespace, v.Name, v.Status.Phase)
//}
}
func ListDeployment(namespace string) error {
clientSet, err := GetClientSet()
if err != nil {
log.Println("GetClientSet 失败: ", err.Error())
return err
}
deployments, err := clientSet.AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
fmt.Println(reflect.TypeOf(deployments))
for index, deployment := range deployments.Items {
//fmt.Println(reflect.TypeOf(deployment))
fmt.Printf("deployment %v: %v \n", index, deployment)
}
//fmt.Println("deployments: ", deployments)
//for _, v := range deployments.Items {
// fmt.Printf("deploymentname: %v, available: %v, ready: %v", v.GetName(), v.Status.AvailableReplicas, v.Status.ReadyReplicas)
//}
return nil
}

@ -0,0 +1,34 @@
package ClientSet
import (
"fmt"
"testing"
)
/*
*
@author: sre
@date: 2022/8/10 0010
@desc: todo
*
*/
func TestListDeployment(t *testing.T) {
err := ListDeployment("sre")
if err != nil {
fmt.Println(err)
}
}
func TestListCms(t *testing.T) {
cms, err := ListCms("sre")
if err != nil {
fmt.Println(err)
}
fmt.Println(cms)
}
func TestGetClientSetRes(t *testing.T) {
ListPods("sre")
}

@ -0,0 +1,56 @@
package main
import (
"ClientGo/utils"
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"log"
)
/*
*
@author: sre
@date: 2022/8/10 0010
@desc: DiscoveryClient Kubernetes
*
*/
func GetDiscoveryClient() (*discovery.DiscoveryClient, error) {
config, err := utils.GetConfig()
if err != nil {
log.Println("GetConfig 失败: ", err.Error())
return nil, err
}
// 实例化 DiscoveryClient
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
log.Println("NewDiscoveryClientForConfig 失败: ", err.Error())
return nil, err
}
return discoveryClient, nil
}
func GetDiscoveryClientRes() {
discoveryClient, err := GetDiscoveryClient()
if err != nil {
log.Println("GetDiscoveryClient 失败: ", err.Error())
return
}
_, apiResources, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
panic(err.Error())
}
for _, list := range apiResources {
gv, err := schema.ParseGroupVersion(list.GroupVersion)
if err != nil {
panic(err.Error())
}
for _, resource := range list.APIResources {
fmt.Printf("name: %v, group: %v, version: %v\n", resource.Name, gv.Group, gv.Version)
}
}
}

@ -0,0 +1,80 @@
package main
import (
"ClientGo/utils"
"context"
"fmt"
corev1 "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"
"log"
)
/**
@author: sre
@date: 2022/8/10 0010
@desc: DynamicClient Kubernetes
Kubernetes CRD ClientSet
使 ClientSet
DynamicClient 使 map[string]interface{} Kubernetes APIServer 使
DynamicClient Object.runtime Unstructured
Object.runtimeKubernetes DeepCopyObject GetObjectKind
Unstructured map[string]interface{} interface{} 便
**/
func GetDynamicClient() (dynamic.Interface, error) {
config, err := utils.GetConfig()
if err != nil {
log.Println("GetConfig 失败: ", err.Error())
return nil, err
}
// 实例化 DynamicClient
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
log.Println("NewForConfig 失败: ", err.Error())
return nil, err
}
return dynamicClient, nil
}
// GetDynamicClientRes from kubeConfigPath
func GetDynamicClientRes(namespace string) {
dynamicClient, err := GetDynamicClient()
if err != nil {
log.Println("GetDynamicClient 失败: ", err.Error())
return
}
// 设置要请求的 GVR
gvr := schema.GroupVersionResource{
Group: "",
Version: "v1",
Resource: "pods",
}
// 发送请求,并得到返回结果
unStructData, err := dynamicClient.Resource(gvr).Namespace(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
// 使用反射将 unStructData 的数据转成对应的结构体类型,例如这是是转成 v1.PodList 类型
podList := &corev1.PodList{}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(
unStructData.UnstructuredContent(),
podList,
)
if err != nil {
panic(err.Error())
}
// 输出 Pods 资源信息
for _, item := range podList.Items {
fmt.Printf("namespace: %v, name: %v\n", item.Namespace, item.Name)
}
}

@ -0,0 +1,78 @@
package main
import (
"ClientGo/utils"
"context"
"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"
"log"
)
/**
@author: sre
@date: 2022/8/10 0010
@desc: RESTClient
RESTful Get()Put()Post()Delete() Kubernetes APIServer RESTful API
Kubernetes CRD
**/
// GetRESTClient RESTClient 其实就是底层使用 net/http 库,将调用 Kubernetes APIServer 的 API 请求,进行了封装,对参数和返回结果进行了序列化及反序列化
func GetRESTClient() (*rest.RESTClient, error) {
config, err := utils.GetConfig()
if err != nil {
log.Println("GetConfig 失败: ", err.Error())
return nil, err
}
// 配置 API 路径
config.APIPath = "api"
// 配置分组版本
config.GroupVersion = &corev1.SchemeGroupVersion
// 配置数据的编解码器
config.NegotiatedSerializer = scheme.Codecs
// 实例化 RESTClient
restClient, err := rest.RESTClientFor(config)
if err != nil {
//panic(err.Error())
log.Println("实例化 RESTClient 失败: ", err.Error())
return nil, err
}
return restClient, nil
//它虽然可以操作 Kubernetes 的所有资源对象,但是使用起来确实比较复杂,需要配置的参数过于繁琐,因此,为了更优雅的更方便的与 Kubernetes APIServer 进行交互,则需要进一步的封装。
}
// GetRes from GetRESTClient
func GetRes(namespace string) {
// 定义返回接收值
restClient, err := GetRESTClient()
if err != nil {
log.Println("获取客户端失败: ", err.Error())
return
}
// 声明空结构体
result := &corev1.PodList{}
err = restClient.Get().
Namespace(namespace). // 查询的 Namespace
Resource("pods"). // 查询的资源类型
VersionedParams(&metav1.ListOptions{Limit: 100}, scheme.ParameterCodec). // 参数及序列化工具
Do(context.TODO()). // 发送请求
Into(result) // 写入返回值
if err != nil {
panic(err.Error())
}
// 输出返回结果
for _, res := range result.Items {
fmt.Println(res.GenerateName)
fmt.Printf("namespace: %v, name: %v, status: %v\n", res.Namespace, res.Name, res.Status.Phase)
}
}

@ -0,0 +1,49 @@
module ClientGo
go 1.19
require (
k8s.io/apimachinery v0.24.3
k8s.io/client-go v0.24.3
)
require (
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
github.com/go-logr/logr v1.2.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/imdario/mergo v0.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/api v0.24.3 // indirect
k8s.io/klog/v2 v2.60.1 // indirect
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

@ -0,0 +1,11 @@
api for kubernetes clientgo
https://www.huweihuang.com/kubernetes-notes/develop/client-go.html
https://juejin.cn/post/6962869412785487909
https://www.fdevops.com/2022/06/26/31114
[]: # Language: markdown
[]: # Path: readme.md

@ -0,0 +1,45 @@
package utils
import (
"errors"
"flag"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"log"
"os"
"path/filepath"
)
/**
@author: sre
@date: 2022/8/10 0010
@desc: GetConfig from kubeConfigPath
**/
// GetConfig from kubeConfigPath
func GetConfig(kubeConfigPath ...string) (*rest.Config, error) {
var kubeConfig *string
if len(kubeConfigPath) > 0 {
kubeConfig = &kubeConfigPath[0]
} else if home := homeDir(); home != "" {
kubeConfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
log.Println("can not find kubeconfig")
return nil, errors.New("can not find kubeconfig")
}
// 加载配置文件,生成 config 对象
config, err := clientcmd.BuildConfigFromFlags("", *kubeConfig)
if err != nil {
log.Println("加载配置文件失败: ", err.Error())
return nil, err
}
return config, nil
}
// homeDir get current user home
func homeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h
}
return os.Getenv("USERPROFILE") // windows
}

@ -0,0 +1,68 @@
package utils
import (
"fmt"
"testing"
)
/**
@author: sre
@date: 2022/8/10 0010
@desc: todo
**/
func TestGetConfigHome(t *testing.T) {
config, err := GetConfig()
if err != nil {
fmt.Println("加载配置文件失败: ", err.Error())
return
}
fmt.Println(config.APIPath)
fmt.Println(config.Host)
fmt.Println(config.Username)
fmt.Println(config.Password)
fmt.Println(config.BearerToken)
fmt.Println(config.TLSClientConfig.CertFile)
fmt.Println(config.TLSClientConfig.KeyFile)
fmt.Println(config.TLSClientConfig.CAFile)
fmt.Println(config.TLSClientConfig.Insecure)
fmt.Println(config.TLSClientConfig.ServerName)
fmt.Println(config.GroupVersion)
fmt.Println(config.NegotiatedSerializer)
fmt.Println(config.QPS)
fmt.Println(config.Burst)
fmt.Println(config.Timeout)
fmt.Println(config.ContentConfig)
fmt.Println(config.WrapTransport)
fmt.Println(config.RateLimiter)
fmt.Println(config.GroupVersion)
fmt.Println(config.NegotiatedSerializer)
}
func TestGetConfigDefine(t *testing.T) {
config, err := GetConfig("../nogit.k8s.config")
if err != nil {
fmt.Println("加载配置文件失败: ", err.Error())
return
}
fmt.Println(config.APIPath)
fmt.Println(config.Host)
fmt.Println(config.Username)
fmt.Println(config.Password)
fmt.Println(config.BearerToken)
fmt.Println(config.TLSClientConfig.CertFile)
fmt.Println(config.TLSClientConfig.KeyFile)
fmt.Println(config.TLSClientConfig.CAFile)
fmt.Println(config.TLSClientConfig.Insecure)
fmt.Println(config.TLSClientConfig.ServerName)
fmt.Println(config.GroupVersion)
fmt.Println(config.NegotiatedSerializer)
fmt.Println(config.QPS)
fmt.Println(config.Burst)
fmt.Println(config.Timeout)
fmt.Println(config.ContentConfig)
fmt.Println(config.WrapTransport)
fmt.Println(config.RateLimiter)
fmt.Println(config.GroupVersion)
fmt.Println(config.NegotiatedSerializer)
}
Loading…
Cancel
Save