紫色飞猪的研发之旅--04client-go客户端
2021-09-02 17:58
951 查看
此部分是对紫色飞猪的研发之旅--02golang:client-go浅学demo[https://www.cnblogs.com/zisefeizhu/p/15207204.html]的补充
对02的改动点如下:
cmd/root.go
// 初始化配置 func initConifg() { config.Loader(cfgFile) // cfgFile string //dservice.Demo() //service.RESTClient() //service.ClientSet() //service.DynamicClient() service.DiscoveryClient() }
config/config.go
// DeployAndKuExternal 部署与k8s外部 func DeployAndKuExternal() *rest.Config { // 3. 在k8s的环境中kubectl配置文件一般放在用户目录的.kube文件中 if home := homeDir(); home != ""{ kubeconfig = flag.String("kubeconfig",filepath.Join(home,".kube","config"),"(可选)kubeconfig 文件的绝对路径") fmt.Println("kubeConfig", *kubeconfig) }else { kubeconfig = flag.String("kubeconfig","","kubeconfig 文件的绝对路径") fmt.Println(kubeconfig) fmt.Println("##################") } flag.Parse() // 4.创建集群配置,首先使用 inCluster 模式(需要区配置对应的RBAC 权限,默认的sa是default-->是没有获取deployment的List权限) if config, err = rest.InClusterConfig(); err != nil { // 使用Kubeconfig文件配置集群Config对象 if config,err = clientcmd.BuildConfigFromFlags("",*kubeconfig); err != nil { panic(err.Error()) } } return config } // DeployAndKuInternal 部署与k8s内部 func DeployAndKuInternal() *rest.Config { // 使用当前上下文环境 kubeconfig := filepath.Join( os.Getenv("KUBECONFIG"), ) config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { logrus.Fatal(err) } return config } // KubeConfig k8s的config加载 func KubeConfig() *rest.Config { switch choose := viper.GetInt("DeploymentMethod"); choose { case 1 : config = DeployAndKuExternal() case 0 : config = DeployAndKuInternal() } return config }
service/demo.go
package service /* 参考文档: Kubernetes的Group、Version、Resource学习小记: https://xinchen.blog.csdn.net/article/details/113715847 Client-go 实战:https://xinchen.blog.csdn.net/article/details/113753087 注:上面的链接博主写的已经十分详细,本着好记性不如烂笔头的目的 跟着敲了一边 */ import ( "context" "flag" "fmt" appsV1 "k8s.io/api/apps/v1" coreV1 "k8s.io/api/core/v1" metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/discovery" "k8s.io/client-go/kubernetes/scheme" rschema "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "operator/config" "operator/pkg" ) func RESTClient() { //RestClient demo : 查询kube-system这个namespace下的所有pod,然后在控制台打印每个pod的几个关键字段; config := config.KubeConfig() // 参考path : /api/v1/namespaces/{namespace}/pods config.APIPath = "api" // pod的group是空字符串 config.GroupVersion = &coreV1.SchemeGroupVersion // 指定序列化工具 config.NegotiatedSerializer = scheme.Codecs // 根据配置信息构建restClient实例 restClient, err := rest.RESTClientFor(config) if err!=nil { panic(err.Error()) } // 保存pod结果的数据结构实例 result := &coreV1.PodList{} // 指定namespace namespace := "kube-system" // 设置请求参数,然后发起请求 // GET请求 err = restClient.Get(). // 指定namespace,参考path : /api/v1/namespaces/{namespace}/pods Namespace(namespace). // 查找多个pod,参考path : /api/v1/namespaces/{namespace}/pods Resource("pods"). // 指定大小限制和序列化工具 VersionedParams(&metaV1.ListOptions{Limit:100}, scheme.ParameterCodec). // 请求 Do(context.TODO()). // 结果存入result Into(result) if err != nil { panic(err.Error()) } // 表头 fmt.Printf("namespace\t status\t\t name\n") // 每个pod都打印namespace、status.Phase、name三个字段 for _, d := range result.Items { fmt.Printf("%v\t %v\t %v\n", d.Namespace, d.Status.Phase, d.Name) } } const ( NAMESPACE = "test-clientset" DEPLOYMENT_NAME = "client-test-deployment" SERVICE_NAME = "client-test-service" ) func ClientSet() { /* 本次编码实战的需求如下: 写一段代码,检查用户输入的operate参数,该参数默认是create,也可以接受clean; 如果operate参数等于create,就执行以下操作: 新建名为test-clientset的namespace 新建一个deployment,namespace为test-clientset,镜像用tomcat,副本数为2 新建一个service,namespace为test-clientset,类型是NodePort 如果operate参数等于clean,就删除create操作中创建的service、deployment、namespace等资源: 以上需求使用Clientset客户端实现,完成后咱们用浏览器访问来验证tomcat是否正常; */ // 获取用户输入的操作类型,默认是create,还可以输入clean,用于清理所有资源 operate := flag.String("operate", "clean", "operate type : create or clean") // 把用户传递的命令行参数解析为对应变量的值 flag.Parse() fmt.Printf("operation is %v\n", *operate) // 实例化clientset对象 clientset, err := kubernetes.NewForConfig(config.KubeConfig()); if err != nil { panic(err.Error()) } // 如果要执行清理操作 if "clean" == *operate { clean(clientset) } else { // 创建namespace createNamespace(clientset) // 创建deployment createDeployment(clientset) // 创建service createService(clientset) } } // 清理本次实战创建的所有资源 func clean(clientset *kubernetes.Clientset) { emptyDeleteOptions := metaV1.DeleteOptions{} // 删除service if err := clientset.CoreV1().Services(NAMESPACE).Delete(context.TODO(), SERVICE_NAME,emptyDeleteOptions); err != nil { panic(err.Error()) } // 删除deployment if err := clientset.AppsV1().Deployments(NAMESPACE).Delete(context.TODO(), DEPLOYMENT_NAME, emptyDeleteOptions); err != nil { panic(err.Error()) } // 删除namespace if err := clientset.CoreV1().Namespaces().Delete(context.TODO(),NAMESPACE, emptyDeleteOptions); err != nil { panic(err.Error()) } } // 新建namespace func createNamespace(clientset *kubernetes.Clientset) { namespaceClient := clientset.CoreV1().Namespaces() namespace := &coreV1.Namespace{ ObjectMeta: metaV1.ObjectMeta{ Name: NAMESPACE, }, } result, err := namespaceClient.Create(context.TODO(), namespace, metaV1.CreateOptions{}); if err != nil{ panic(err.Error()) } fmt.Printf("Create namespace %s \n", result.GetName()) } // 新建service func createService(clientset *kubernetes.Clientset) { // 得到service的客户端 serviceClient := clientset.CoreV1().Services(NAMESPACE) // 实例化一个数据结构 service := &coreV1.Service{ ObjectMeta: metaV1.ObjectMeta{ Name: SERVICE_NAME, }, Spec: coreV1.ServiceSpec{ Ports: []coreV1.ServicePort{ { Name: "http", Port: 8080, NodePort: 30080, }, }, Selector: map[string]string{ "app" : "tomcat", }, Type: coreV1.ServiceTypeNodePort, }, } result, err := serviceClient.Create(context.TODO(), service, metaV1.CreateOptions{}); if err != nil { panic(err.Error()) } fmt.Printf("Create service %s \\n", result.GetName()) } // 新建deployment func createDeployment(clientset *kubernetes.Clientset) { // 得到deployment的客户端 deploymentClient := clientset.AppsV1().Deployments(NAMESPACE) // 实例化一个数据结构 deployment := &appsV1.Deployment{ ObjectMeta: metaV1.ObjectMeta{ Name: DEPLOYMENT_NAME, }, Spec: appsV1.DeploymentSpec{ Replicas: pkg.Int32Ptr(2), Selector: &metaV1.LabelSelector{ MatchLabels: map[string]string{ "app": "tomcat", }, }, Template: coreV1.PodTemplateSpec{ ObjectMeta: metaV1.ObjectMeta{ Labels: map[string]string{ "app": "tomcat", }, }, Spec: coreV1.PodSpec{ Containers: []coreV1.Container{ { Name: "tomcat", Image: "tomcat:latest", ImagePullPolicy: "IfNotPresent", Ports: []coreV1.ContainerPort{ { Name: "http", Protocol: coreV1.ProtocolTCP, ContainerPort: 8080, }, }, }, }, }, }, }, } result, err := deploymentClient.Create(context.TODO(), deployment, metaV1.CreateOptions{}); if err != nil { panic(err.Error()) } fmt.Printf("Create deployment %s \n", result.GetName()) } func DynamicClient() { // 查询指定namespace下的所有pod,然后在控制台打印出来,要求用dynamicClient实现 dynamicClient, err := dynamic.NewForConfig(config.KubeConfig()); if err != nil { panic(err.Error()) } // 从dynamicClient 的唯一关联方法所需的入参 gvr := rschema.GroupVersionResource{Version: "v1", Resource: "pods"} // 使用dynamicClient的查询列表方法,查询指定namespace下的所有pod, // 注意此方法返回的数据结构类型是UnstructuredList unstructObj, err := dynamicClient. Resource(gvr). Namespace("kube-system"). List(context.TODO(), metaV1.ListOptions{Limit: 100}); if err != nil { panic(err.Error()) } // 实例化一个PodList数据结构,用于接收从unstructObj转换后的结果 podList := &coreV1.PodList{} // 转换 err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.UnstructuredContent(), podList); if err != nil { panic(err.Error()) } // 表头 fmt.Printf("namespace\t status\t\t name\n") // 每个pod都打印namespace、status.Phase、name三个字段 for _, d := range podList.Items { fmt.Printf("%v\t %v\t %v\n", d.Namespace, d.Status.Phase, d.Name) } } func DiscoveryClient() { // 从kubernetes查询所有的Group、Version、Resource信息,在控制台打印出来 discoveryClient, err := discovery.NewDiscoveryClientForConfig(config.KubeConfig()); if err != nil{ panic(err.Error()) } // 获取所有分组和资源数据 APIGroup, APIResourceListSlice, err := discoveryClient.ServerGroupsAndResources(); if err != nil { panic(err.Error()) } // 先看Group信息 fmt.Printf("APIGroup :\n\n %v\n\n\n\n",APIGroup) // APIResourceListSlice是个切片,里面的每个元素代表一个GroupVersion及其资源 for _, singleAPIResourceList := range APIResourceListSlice { // GroupVersion是个字符串,例如"apps/v1" groupVerionStr := singleAPIResourceList.GroupVersion // ParseGroupVersion方法将字符串转成数据结构 gv, err := rschema.ParseGroupVersion(groupVerionStr) if err != nil { panic(err.Error()) } fmt.Println("*****************************************************************") fmt.Printf("GV string [%v]\nGV struct [%#v]\nresources :\n\n", groupVerionStr, gv) // APIResources字段是个切片,里面是当前GroupVersion下的所有资源 for _, singleAPIResource := range singleAPIResourceList.APIResources { fmt.Printf("%v\n", singleAPIResource.Name) } } }
相关文章推荐
- kubernetes 客户端client-go 使用及常用api
- go net/http Client使用——长连接客户端的使用
- MySql 客户端指令 (MySql.Client-Side.Command)
- 【FileZilla FTP Client】文件与服务器操作客户端
- Lotus Notes Client Settings(Lotus Notes客户端配置)
- Go Kafka客户端简单示例
- System.Net.FtpClient FTP 协议的客户端开发包
- Yii CActiveForm 客户端验证(enableClientValidation)和自定义验证
- Windows C语言 Socket编程 client端(客户端)--断线重连版
- java httpclient发送json 请求 ,go服务端接收
- SharePoint 2010 Client Browser 客户端浏览器
- ClientScriptManager与ScriptManager向客户端注册脚本的区别
- Sharepoint学习笔记 –架构系列—Sharepoint的客户端对象模型(Client Object Model)
- AS3 服务端、客户端协议路由简单写法 ---- AS3 Server、Client Router Demo
- System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本
- CAS单点登录-客户端集成(cas-client)(九)
- 在C#开发中如何使用Client Object Model客户端代码获得SharePoint 网站、列表的权限情况
- CAS-Client客户端研究(五)-SingleSignOutFilter
- Linux里Oracle client客户端简便安装
- Oracle 11G Client 客户端安装步骤(图文详解)