玛卡巴卡的卡巴卡玛 发表于 2023-11-3 02:57:24

client-go实战之七:准备一个工程管理后续实战的代码

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览


[*]本文是《client-go实战》系列的第八篇,主要内容是新建一个golang工程,用于管理代码,后面整个系列的代码都会保存在这个工程中
工程结构简述


[*]此工程打算写一个简单的接口,接下来所有实战的功能代码都实现这个接口,在命中输入参数来决定执行哪个实现类
[*]整个工程结构如下图所示,后续的实战中,每个功能类都如绿色箭头所示,是个独立的go文件
https://img2023.cnblogs.com/blog/485422/202309/485422-20230923163655658-1235185429.png
编码


[*]新建一个名为client-go-tutorials的golang工程
[*]为了便于扩展,新建名为action的文件夹,里面增加action.go文件,内容如下
package action

import "k8s.io/client-go/kubernetes"

type Action interface {
        DoAction(clientset *kubernetes.Clientset) error
}

[*]后面的实战都实现这个接口,先把前文的helloworld迁移到本工程中,即list_pod.go
package action

import (
        "context"
        "fmt"

        "k8s.io/apimachinery/pkg/api/errors"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/client-go/kubernetes"
)

type ListPod struct{}

func (listPod ListPod) DoAction(clientset *kubernetes.Clientset) error {
        namespace := "kube-system"

        // 查询pod列表
        pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
        if err != nil {
                panic(err.Error())
        }

        nums := len(pods.Items)

        fmt.Printf("There are %d pods in the cluster\n", nums)

        // 如果没有pod就返回了
        if nums < 1 {
                return nil
        }

        // 遍历列表中的每个pod
        for index, pod := range pods.Items {
                fmt.Printf("%v. pod name : %v\n", index, pod.Name)

                // 用pod name精确搜索单个pod
                podObj, err := clientset.CoreV1().Pods(namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{})
                if errors.IsNotFound(err) {
                        fmt.Printf("Pod %s in namespace %s not found\n", pod.Name, namespace)
                } else if statusError, isStatus := err.(*errors.StatusError); isStatus {
                        fmt.Printf("Error getting pod %s in namespace %s: %v\n",
                                pod.Name, namespace, statusError.ErrStatus.Message)
                } else if err != nil {
                        panic(err.Error())
                } else {
                        fmt.Printf("Found pod %s in namespace %s\n", podObj.Name, namespace)
                }
        }

        return nil
}程序入口


[*]接下来是main.go,这是程序的入口,代码有以下功能:

[*]加载kubernetes的配置文件,以便后续的处理
[*]检查命令的入参action,根据不同的值执行不同的实现类,在本篇就是list-pod,即获取pod列表并在控制台输出


[*]main.go源码如下
package main

import (
        "client-go-tutorials/action"
        "flag"
        "fmt"
        "path/filepath"

        "k8s.io/client-go/kubernetes"
        "k8s.io/client-go/tools/clientcmd"
        "k8s.io/client-go/util/homedir"
)

func main() {
        var kubeconfig *string
        var actionFlag *string

        // 试图取到当前账号的家目录
        if home := homedir.HomeDir(); home != "" {
                // 如果能取到,就把家目录下的.kube/config作为默认配置文件
                kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
        } else {
                // 如果取不到,就没有默认配置文件,必须通过kubeconfig参数来指定
                kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
        }

        actionFlag = flag.String("action", "list-pod", "指定实际操作功能")

        flag.Parse()

        fmt.Println("解析命令完毕,开始加载配置文件")

        // 加载配置文件
        config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
        if err != nil {
                panic(err.Error())
        }

        // 用clientset类来执行后续的查询操作
        clientset, err := kubernetes.NewForConfig(config)
        if err != nil {
                panic(err.Error())
        }

        fmt.Printf("加载配置文件完毕,即将执行业务 [%v]\n", *actionFlag)

        var actionInterface action.Action

        // 注意,如果有新的功能类实现,就在这里添加对应的处理
        switch *actionFlag {
        case "list-pod":
                listPod := action.ListPod{}
                actionInterface = &listPod
        case "conflict":
                conflict := action.Confilct{}
                actionInterface = &conflict
        }

        err = actionInterface.DoAction(clientset)
        if err != nil {
                fmt.Printf("err: %v\n", err)
        } else {
                fmt.Println("执行完成")
        }
}启动配置


[*]最后,如果您用的是vscode,可以像下面这样配置launch.json文件,以便快速运行main.go,以及输入参数
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
      {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}",
            "args": ["-action=list-pod"]
      }
    ]
}

[*]最后,确认.kube/config文件可以正常使用
[*]按照下图操作,可以正常运行程序,输出pod列表信息
https://img2023.cnblogs.com/blog/485422/202309/485422-20230923163655695-887250964.png
[*]至此,本篇完成,接下来的实战都会使用本篇创建的工程,在这里面添加action接口的实现类
源码下载


[*]上述完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
名称链接备注项目主页https://github.com/zq2599/blog_demos该项目在GitHub上的主页git仓库地址(https)https://github.com/zq2599/blog_demos.git该项目源码的仓库地址,https协议git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议

[*]这个git项目中有多个文件夹,本篇的源码在tutorials/client-go-tutorials文件夹下,如下图红框所示:
https://img2023.cnblogs.com/blog/485422/202309/485422-20230923163655648-1441444504.png
欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: client-go实战之七:准备一个工程管理后续实战的代码