一、介绍
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函数负责以下工作:
- 访问用户主目录下的 .kube文件夹中的配置文件。
- 使用 kube 配置文件的路径创建一个 *rest。Configby invokinclientcmd.BuildConfigFromFlags.
- 创建一个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。