使用 client-go API 在 Go 中创建和管理 Kubernetes 作业 教程

一、介绍

Kubernetes API 服务器提供了一个 REST API 接口,供客户端与之交互并执行创建部署等操作。但是客户端应用程序不必理解和使用较低级别的 HTTP 操作,如 GET、PUT、POST 或 PATCH,因为不同语言有多个客户端库。最受欢迎的一个是Go 客户端库。

本指南介绍如何使用 Kubernetes Go 客户端创建作业和 Cron 作业。在我们进入细节之前,让我们简要了解这些概念。

1.1、工作

Kubernetes作业可用于运行有限时间后必须完成的应用程序类型。这些短期任务(如批处理作业)可能作为一次性进程运行,也可能定期运行。就像部署一样,作业也会创建一个或多个 Pod。要使作业被视为完成,其 Pod 应成功终止。如果作业执行失败,Kubernetes 会重试执行。也可以删除或暂停作业 – 在这两种情况下,作业创建的 Pod 都会被删除。

1.2、重复作业

CronJob 可用于需要按特定时间间隔运行的任务,例如每天/每周/每月一次。根据基于Cron格式的计划定期创建新的作业对象。

二、准备工作

若要完成本指南,需要以下各项:

  • AVultr Kubernetes Engine (VKE) cluster.
  • 在本地工作站上安装Go 编程语言(版本 1.18 或更高版本)。
  • 在本地工作站上安装最新版本的kubectl。

三、初始化项目

在本地计算机上,创建一个目录并切换到该目录:

mkdir k8s-jobs-go-client

cd k8s-jobs-go-client

创建一个新的 Go 模块:

go mod init k8s-jobs-go-client

这将创建一个新的go.mod文件

创建一个新文件main.go

touch main.go

 四、导入库

要导入所需的 Go 模块,请将以下内容添加到main.go文件:

package main



import (

    "context"

    "flag"

    "fmt"

    "log"

    "path/filepath"



    batchv1 "k8s.io/api/batch/v1"

    apiv1 "k8s.io/api/core/v1"



    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"

)

 五、添加初始化函数

将下面的代码添加到main.go

var clientset *kubernetes.Clientset



const jobName = "test-job-clientgo"

const cronJobName = "test-cronjob-clientgo"



func init() {

    var kubeconfig *string

    if home := homedir.HomeDir(); home != "" {

        kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")

    } else {

        kubeconfig = flag.String("kubeconfig","  ", "absolute path to the kubeconfig file")

    }

    flag.Parse()



    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)

    if err != nil {

        log.Fatal(err)

    }

    clientset, err = kubernetes.NewForConfig(config)

    if err != nil {

        log.Fatal(err)

    }

}

init函数负责以下工作:

  1. 访问用户主目录下的 .kube文件夹中的配置文件
  2. 使用 kube 配置文件的路径创建一个 *rest。Configby invokinclientcmd.BuildConfigFromFlags.
  3. 创建一个kubernetes。通过调用 kubernetes 进行客户端设置。NewForConfig传入 *rest。配置

六、添加函数以创建作业

createJob函数添加到main.go文件:

func createJob() {

    fmt.Println("creating job", jobName)

    jobsClient := clientset.BatchV1().Jobs(apiv1.NamespaceDefault)



    job := &batchv1.Job{ObjectMeta: metav1.ObjectMeta{

        Name: jobName,

    },

        Spec: batchv1.JobSpec{

            Template: apiv1.PodTemplateSpec{

                Spec: apiv1.PodSpec{

                    Containers: []apiv1.Container{

                        {

                            Name: "pi",

                            Image: "perl:5.34.0",

                            Command: []string{"perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"},

                        },

                    },

                    RestartPolicy: apiv1.RestartPolicyNever,

                },

            },

        },

    }



    _, err := jobsClient.Create(context.Background(), job, metav1.CreateOptions{})

    if err != nil {

        log.Fatal("failed to create job", err)

    }



    fmt.Println("created job successfully")

}

如果成功,此函数将创建一个名为test-job-clientgo 的作业

  • 首先,它获得v1。通过调用客户端集的作业接口实例。批处理V1()。具有默认命名空间的 Jobs()
  • 准备新的作业定义
  • 调用 JobInterface.Create 以启动作业创建

七、添加主函数

最后,添加 main 函数,它将调用createJob函数。

func main() {

    createJob()

}

 八、运行程序以创建新作业

确保已将kubectl配置为指向要用于本指南的 Kubernetes 集群。例如,使用kind cluster create来创建一个新的Kubernetes集群。这也将自动配置kubectl

kubectl get nodes

应会看到以下输出:

NAME                 STATUS   ROLES           AGE   VERSION

kind-control-plane   Ready    control-plane   23h   v1.24.0

运行程序:

go run main.go

应会看到以下输出:

creating job test-job-clientgo

created job successfully

确认作业已创建:

kubectl get job/test-job-clientgo

应会看到以下输出:

NAME                COMPLETIONS   DURATION   AGE

test-job-clientgo   1/1           7s         66s

作业创建了一个 Pod,大约需要 7 秒来计算 Pi 的值(到 2000 位)并将其打印出来。

要确认结果,请检查 Pod 日志:

kubectl logs $(kubectl get pods --selector=job-name=test-job-clientgo --output=jsonpath='{.items[*].metadata.name}')

 九、添加删除作业的函数

deleteJob函数添加到main.go

func deleteJob() {

    fmt.Println("deleting job", jobName)



    jobsClient := clientset.BatchV1().Jobs(apiv1.NamespaceDefault)



    pp := metav1.DeletePropagationBackground

    err := jobsClient.Delete(context.Background(), jobName, metav1.DeleteOptions{PropagationPolicy: &pp})

    if err != nil {

        log.Fatal("failed to delete job", err)

    }

    fmt.Println("deleted job successfully")

}

更新函数:注释掉createJob函数并添加deleteJob函数。

func main() {

    //createJob()

    deleteJob()

}

 十、运行程序以删除现有作业

要运行该程序:

go run main.go

应会看到以下输出:

deleting job test-job-clientgo

deleted job successfully

确认作业已删除:

kubectl get job/test-job-clientgo

应会看到以下输出:

Error from server (NotFound): jobs.batch "test-job-clientgo" not found

确认作业创建的 Pod 也已删除:

kubectl get pods --selector=job-name=test-job-clientgo

应会看到以下输出:

No resources found in default namespace.

 十一、添加函数以创建 CronJob

createCronJob函数添加到main.go

func createCronJob() {

    fmt.Println("creating cron job", cronJobName)



    cronJobsClient := clientset.BatchV1().CronJobs(apiv1.NamespaceDefault)



    cronJob := &batchv1.CronJob{ObjectMeta: metav1.ObjectMeta{

        Name: cronJobName},

        Spec: batchv1.CronJobSpec{

            Schedule: "* * * * *",

            JobTemplate: batchv1.JobTemplateSpec{

                Spec: batchv1.JobSpec{

                    Template: apiv1.PodTemplateSpec{

                        Spec: apiv1.PodSpec{

                            Containers: []apiv1.Container{

                                {

                                    Name: "hello",

                                    Image: "busybox:1.28",

                                    Command: []string{"/bin/sh", "-c", "date; echo Hello from the Kubernetes cluster"},

                                },

                            },

                            RestartPolicy: apiv1.RestartPolicyOnFailure,

                        },

                    },

                },

            },

        },

    }



    _, err := cronJobsClient.Create(context.Background(), cronJob, metav1.CreateOptions{})

    if err != nil {

        log.Fatal("failed to create cron job", err)

    }



    fmt.Println("created cron job successfully")

}

如果成功,此函数将创建一个名为test-cronjob-clientgo 的CronJob

  • 首先,它获得v1。通过调用客户端集的 CronJobInterface实例。批处理V1()。具有默认命名空间的 CronJobs()
  • 准备新的CronJob定义
  • 调用CronJobInterface.Create以启动CronJob创建

更新函数:注释掉deleteJob函数并添加createCronJob函数。

func main() {

    //createJob()

    //deleteJob()

    createCronJob()

}

 十二、运行程序以创建 CronJob

要运行该程序:

go run main.go

应会看到以下输出:

creating cron job test-cronjob-clientgo

created cron job successfully

确认已创建CronJob

kubectl get cronjob/test-cronjob-clientgo

应会看到以下输出:

NAME                    SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE

test-cronjob-clientgo   * * * * *   False     0        <none>          17s

CronJob每分钟创建一个Pod,并打印当前时间以及一条消息。检查豆荚:

kubectl get pods

应会看到以下输出:

NAME                                   READY   STATUS      RESTARTS   AGE

test-cronjob-clientgo-27804391-qcjzd   0/1     Completed   0          2m49s

你应该看到名称以test-cronjob-clientgo开头的Pod。

要检查Pod日志,请执行以下操作:

kubectl logs <enter Pod name>

您应该会看到包含当前日期的输出以及一条消息:

Fri Sep 12 14:34:00 UTC 2022

Hello from the Kubernetes cluster

 十三、添加用于删除 CronJob 的函数

添加删除CronJob函数:

func deleteCronJob() {

    fmt.Println("deleting cron job", cronJobName)



    cronJobsClient := clientset.BatchV1().CronJobs(apiv1.NamespaceDefault)



    pp := metav1.DeletePropagationBackground

    err := cronJobsClient.Delete(context.Background(), cronJobName, metav1.DeleteOptions{PropagationPolicy: &pp})

    if err != nil {

        log.Fatal("failed to delete cron job", err)

    }

    fmt.Println("deleted cron job successfully")

}

更新函数:注释掉createCronJob函数并添加deleteCronJob函数。

func main() {

    //createJob()

    //deleteJob()

    //createCronJob()

    deleteCronJob()

}

 十四、运行程序以删除现有的 CronJob

运行程序:

go run main.go

应会看到以下输出:

deleting cron job test-cronjob-clientgo

deleted cron job successfully

确认作业已删除:

kubectl get cronjob/test-cronjob-clientgo

应会看到以下输出:

Error from server (NotFound): cronjobs.batch "test-cronjob-clientgo" not found

确认 cron作业创建的Pod也被删除了

kubectl get pods

你不应该看到名称以test-cronjob-clientgo 开头的Pod。

 十五、结论

本指南介绍了如何使用 Kubernetes Go 客户端库创建和删除Job 和CronJob

赞(0)
未经允许不得转载:主机百科 » 使用 client-go API 在 Go 中创建和管理 Kubernetes 作业 教程