参考
- 教程: 构建 CronJob - Kubebuilder 中文文档
- Kubernetes operator(九) kubebuilder 实战演练 之 自定义CronJob_cronjob kubebuilder-CSDN博客
小结
# yaml 改动有关或重新生成,如 crd、webhook 等 yaml
$ make manifests
# 部署 crd
$ make install
# 卸载 crd
$ make uninstall
# controller 调试,在终端可看到 controller 日志
$ make run
# 生成镜像,此处为默认名称,详见 Dockerfile 中 IMG 环境变量
$ make docker-build
# 自定义生成镜像名称
$ make docker-build IMG=dfy-cronjob-operator:v2
# 部署 controller 和 webhook 到集群中
$ make deploy
# 卸载 controller 和 webhook
$ make undeploy
# 查看 make deploy 会部署哪些内容
$ kustomize build config/default
- 调试过程
# 1. 部署 crd
$ make manifests install
# 2. 运行 controller
$ make run
# 3. 创建示例,需要提前手动填充 config/samples/batch_v1_cronjob.yaml 对应的 crd 字段内容
kubectl apply -f config/samples/batch_v1_cronjob.yaml
1 | 创建 CRD
# we'll use a domain of tutorial.kubebuilder.io,
# so all API groups will be <group>.tutorial.kubebuilder.io.
# 1. 执行 domain 域名,避免与其他域的同名 CRD 冲突
$ kubebuilder init --domain tutorial.kubebuilder.io
# 2. 在该域内生成 CronJob CRD,也可以称之为,创建一个 API
$ kubebuilder create api --group batch --version v1 --kind CronJob
# 3. 生成 crd 定义 yaml
$ make manifests
# 4. 部署 crd:将 crd 这种类型告知给 k8s 集群,也就是执行 crd 定义yaml
$ make install
# 5. 若 cronjob 结构定义有改动,需要重新生成和部署 crd, 就是执行上面 3 和 4 步,简化如下
$ make manifest install
domain 有什么作用
# 可以看到 cronjob,k8s 原生也有
# 我们创建的 cronjob 和 k8s 原生 cronjob,都设置 group 为 batch, version 为 v1
# 若未指定 domain,将造成冲突
kubectl api-resources | grep cronjob
cronjobs cj batch/v1 true CronJob
cronjobs cj2 batch.tutorial.kubebuilder.io/v1 true CronJob
2 | 设计 CRD 结构定义
// api/v1/cronjob_types.go
// +kubebuilder:object:root=true 标记这是一个根对象,这个类型直接对应于一个 Kubernetes API 资源,而不是嵌套在其他资源中的子资源。
// +kubebuilder:resource:shortName=cj2 执行该类型的缩写为 cj2
// +kubebuilder:subresource:status 为该类型生成个 status 子资源
// 用户自定义 crd
// CronJob is the Schema for the cronjobs API
type CronJob struct {
Root Object Definitions
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec CronJobSpec `json:"spec,omitempty"`
Status CronJobStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// 自动生成,用于承接一堆 CRD 实例,可以理解为数组,用于存储多个 CRD 实例
// CronJobList contains a list of CronJob
type CronJobList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []CronJob `json:"items"`
}
// 用户自定义,对应 crd 的 spec 字段
// CronJobSpec defines the desired state of CronJob
type CronJobSpec struct {
// +kubebuilder:validation:MinLength=0
// The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
Schedule string `json:"schedule"`
// +kubebuilder:validation:Minimum=0
// Optional deadline in seconds for starting the job if it misses scheduled
// time for any reason. Missed jobs executions will be counted as failed ones.
// +optional
StartingDeadlineSeconds *int64 `json:"startingDeadlineSeconds,omitempty"`
// Specifies how to treat concurrent executions of a Job.
// Valid values are:
// - "Allow" (default): allows CronJobs to run concurrently;
// - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet;
// - "Replace": cancels currently running job and replaces it with a new one
// +optional
ConcurrencyPolicy ConcurrencyPolicy `json:"concurrencyPolicy,omitempty"`
// This flag tells the controller to suspend subsequent executions, it does
// not apply to already started executions. Defaults to false.
// +optional
Suspend *bool `json:"suspend,omitempty"`
// Specifies the job that will be created when executing a CronJob.
JobTemplate batchv1beta1.JobTemplateSpec `json:"jobTemplate"`
// +kubebuilder:validation:Minimum=0
// The number of successful finished jobs to retain.
// This is a pointer to distinguish between explicit zero and not specified.
// +optional
SuccessfulJobsHistoryLimit *int32 `json:"successfulJobsHistoryLimit,omitempty"`
// +kubebuilder:validation:Minimum=0
// The number of failed finished jobs to retain.
// This is a pointer to distinguish between explicit zero and not specified.
// +optional
FailedJobsHistoryLimit *int32 `json:"failedJobsHistoryLimit,omitempty"`
}
// 用户自定义,对应 status 子资源
// 在 controller reconcile 中自定义更新逻辑,通过 if err := r.Status().Update(ctx, &cronJob); err != nil { 更新 status 子资源
// CronJobStatus defines the observed state of CronJob
type CronJobStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// A list of pointers to currently running jobs.
// +optional
Active []corev1.ObjectReference `json:"active,omitempty"`
// Information when was the last time the job was successfully scheduled.
// +optional
LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`
}
// kubebuilder 自动生成的,将 Kinds 注册到 API group 中。这使我们可以将此 API group 中的 Kind 添加到任何 Scheme 中。
func init() {
SchemeBuilder.Register(&CronJob{}, &CronJobList{})
}
详解 status 子资源
- https://kubernetes.io/zh-cn/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#subresources
当你在自定义资源(Custom Resource)中使用 // +kubebuilder:subresource:status
标记时,kubebuilder
会在生成的 CRD YAML 文件中包含一个 status
子资源。这意味着 Kubernetes 会为该自定义资源管理 status
子资源,允许你通过专门的 API 来更新资源的状态。
具体作用如下:
- 启用
status
子资源: 标记告诉 Kubernetes 这个自定义资源有一个status
子资源,这个子资源可以通过 Kubernetes API 单独访问和更新。 - API 分离: 允许状态和规格(spec)分离,通过不同的 API 端点分别更新。规格可以通过
/spec
更新,而状态可以通过/status
更新。 - 状态更新: 状态更新通常由控制器执行。控制器会定期检查资源的状态并更新
status
字段,以反映资源的当前状态或操作结果。 - 权限控制: 在使用
status
子资源时,可以对status
和spec
操作分别设置 RBAC 权限。这样可以确保只有具有适当权限的实体才能修改资源状态。
3 | 编写 controller
// controllers/cronjob_controller.go
// kubebuilder 为我们搭建了一个基本的 reconciler 结构体。
// 几乎每个 reconciler 都需要记录日志,并且需要能够获取对象,因此这个结构体是开箱即用的。
// CronJobReconciler reconciles a CronJob object
// 可自定义添加字段,用于记录或控制,如 Log 字段
type CronJobReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
}
// 编写 controller 的控制逻辑、调谐逻辑
func (r *CronJobReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
_ = context.Background()
_ = r.Log.WithValues("cronjob", req.NamespacedName)
// your logic here
return ctrl.Result{}, nil
}
- controller 的初始化,在项目根目录 main.go 中
if err = (&controllers.CronJobReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
// 未赋值此 Log 字段时,Log 对应一个 logr.Logger 零值(结构体内的所有字段都为 零值)
Log: ctrl.Log.WithName("controllers").WithName("CronJob"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "CronJob")
os.Exit(1)
}
关注 job 资源
- 由于 cronjob 需要操作并关注 job 资源,所以需要权限和关注
- 权限,通过 kubebuilder 注释实现
- 关注,通过 owns ,job 资源变化也会出发 cronjob 的调谐逻辑
// controllers/cronjob_controller.go
// 1. 足够的权限,操作 job 资源
//+kubebuilder:rbac:groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete 自动生成
//+kubebuilder:rbac:groups=batch.tutorial.kubebuilder.io,resources=cronjobs/status,verbs=get;update;patch 自动生成
//+kubebuilder:rbac:groups=batch.tutorial.kubebuilder.io,resources=cronjobs/finalizers,verbs=update 自动生成
//+kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;patch;delete 手动添加
//+kubebuilder:rbac:groups=batch,resources=jobs/status,verbs=get 手动添加
func (r *CronJobReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
... ...
}
// 2. 关注 cronjob 掌管的 job 资源变化,触发调谐逻辑
// - 其他知识:创建一个 Indexer
var (
// Indexer 名称
jobOwnerKey = ".metadata.controller"
apiGVStr = batch.GroupVersion.String()
)
func (r *CronJobReconciler) SetupWithManager(mgr ctrl.Manager) error {
// 创建一个名为 .metadata.controller 的 Indexer
if err := mgr.GetFieldIndexer().IndexField(&kbatch.Job{}, jobOwnerKey, func(rawObj runtime.Object) []string {
// grab the job object, extract the owner...
job := rawObj.(*kbatch.Job)
owner := metav1.GetControllerOf(job)
if owner == nil {
return nil
}
// ...make sure it's a CronJob...
if owner.APIVersion != apiGVStr || owner.Kind != "CronJob" {
return nil
}
// ...and if so, return it
return []string{owner.Name}
}); err != nil {
return err
}
// 关注 cronjob 创建的 job 实例,job 的变化会触发 cronjob 的 reconcile 调谐逻辑
return ctrl.NewControllerManagedBy(mgr).
For(&batch.CronJob{}).
Owns(&kbatch.Job{}).
Complete(r)
}
Owns 字段的作用
在 Kubernetes 中,Owns
字段用于指定控制器应该监视的资源类型,这些资源是由该控制器管理的主要资源拥有的。具体来说,当一个控制器声明它“拥有”某些资源时,它表示控制器不仅要监视和管理其主要资源,还要监视这些主要资源所创建或拥有的其他资源。
示例代码
在你的示例代码中:
// controllers/cronjob_controller.go
return ctrl.NewControllerManagedBy(mgr).
For(&batchv1.CronJob{}).
Owns(&kbatchv1.Job{}).
Complete(r)
详细解释
- For(&batchv1.CronJob{}):
- 这行代码指定控制器的主要资源类型是
CronJob
。 - 控制器将监视和管理
CronJob
资源,当CronJob
资源发生变化时,它将调用Reconcile
方法。
- 这行代码指定控制器的主要资源类型是
- Owns(&kbatchv1.Job{}):
- 这行代码指定控制器还应监视
Job
资源,这些Job
资源是由CronJob
资源创建或拥有的。 - 当
Job
资源发生变化(例如创建、更新或删除)时,控制器也会调用Reconcile
方法。 - 这确保了
CronJob
控制器可以响应其拥有的Job
资源的变化,从而确保CronJob
和Job
之间的一致性和正确性。
- 这行代码指定控制器还应监视
作用
Owns
的作用包括以下几个方面:
- 资源关系管理:
- 确保控制器不仅监视主要资源(如
CronJob
),还监视这些资源创建或拥有的子资源(如Job
)。 - 当子资源状态改变时,控制器可以及时响应和处理。
- 确保控制器不仅监视主要资源(如
- 自动调用 Reconcile:
- 当控制器拥有的子资源发生变化时,Kubernetes 会通知控制器,并自动调用
Reconcile
方法。 - 这有助于保持主要资源和子资源之间的一致性。例如,当一个
Job
完成或失败时,CronJob
控制器可以根据需要更新CronJob
的状态。
- 当控制器拥有的子资源发生变化时,Kubernetes 会通知控制器,并自动调用
- 简化控制器逻辑:
- 通过
Owns
字段,控制器开发者可以简化控制器逻辑,因为 Kubernetes 会自动处理子资源的事件通知。 - 开发者只需在
Reconcile
方法中处理这些事件即可。
- 通过
结论
在 Kubernetes 中,Owns
字段是控制器的一种声明,用于指定控制器除了监视主要资源外,还要监视由这些主要资源拥有的其他资源。当这些拥有的资源发生变化时,Kubernetes 会自动调用控制器的 Reconcile
方法,从而确保资源之间的一致性和正确性。
4 | 编写 webhook
-
实现 defaulting webhooks 和 validating webhooks - Kubebuilder 中文文档
-
Kubernetes operator(九) kubebuilder 实战演练 之 自定义CronJob_cronjob kubebuilder-CSDN博客
使用 kubebuilder create webhook
命令可以为指定的 Kubernetes 资源创建 Webhook,帮助进行默认值设置和程序化验证。让我们详细解释这个命令及其参数的作用。
命令和参数
kubebuilder create webhook --group batch --version v1 --kind CronJob --defaulting --programmatic-validation
作用
该命令会为指定的 CronJob
资源创建 Webhook,用于处理默认值设置和程序化验证。
参数解释
--group batch
:- 指定资源所属的 API 组为
batch
。 CronJob
资源会被创建在batch
API 组下。
- 指定资源所属的 API 组为
--version v1
:- 指定资源的 API 版本为
v1
。 CronJob
资源使用的版本是v1
。
- 指定资源的 API 版本为
--kind CronJob
:- 指定资源的类型(或种类)为
CronJob
。 - 这个命令将会为
CronJob
资源创建 Webhook。
- 指定资源的类型(或种类)为
--defaulting
:- 创建一个 Mutating Webhook,用于在创建或更新
CronJob
资源时设置默认值。 - 当用户创建或更新
CronJob
资源但没有提供某些字段的值时,这个 Webhook 会自动填充默认值。
- 创建一个 Mutating Webhook,用于在创建或更新
--programmatic-validation
:- 创建一个 Validating Webhook,用于在创建或更新
CronJob
资源时进行程序化验证。 - 这个 Webhook 会检查传入的
CronJob
资源的字段值是否符合特定的业务逻辑或规则,如果不符合,则拒绝该操作。
- 创建一个 Validating Webhook,用于在创建或更新
生成的内容
运行上述命令后,Kubebuilder 会在项目中生成必要的代码和配置文件,包括:
- Webhook 配置:
- 在
api/v1/cronjob_webhook.go
文件中,会生成默认值设置和验证逻辑的框架代码。
- 在
- Webhook 代码:
Default
方法:用于设置CronJob
资源的默认值。ValidateCreate
、ValidateUpdate
和ValidateDelete
方法:用于在创建、更新和删除CronJob
资源时进行验证。
- Webhook 配置文件:
- 在
config/webhook
目录下生成相应的 YAML 文件,用于配置 Webhook 服务。 - 包括 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration 的配置文件,这些配置文件会被应用到 Kubernetes 集群中,以注册 Webhook 服务。
- 在
示例代码
api/v1/cronjob_webhook.go
文件可能包含以下示例代码:
// +kubebuilder:webhook:path=/mutate-batch-v1-cronjob,mutating=true,failurePolicy=fail,groups=batch,resources=cronjobs,verbs=create;update,versions=v1,name=mcronjob.kb.io
// +kubebuilder:webhook:path=/validate-batch-v1-cronjob,mutating=false,failurePolicy=fail,groups=batch,resources=cronjobs,verbs=create;update;delete,versions=v1,name=vcronjob.kb.io
// 可以理解为 Mutating Webhook 填充默认值,需要手动编写对应逻辑
func (r *CronJob) Default() {
cronjoblog.Info("default", "name", r.Name)
// 设置默认值的逻辑
}
// 可以理解为 Validating Webhook,可以理解为在资源创建、更新、删除时,执行的验证逻辑,需要手动编写
func (r *CronJob) ValidateCreate() error {
cronjoblog.Info("validate create", "name", r.Name)
// 创建时的验证逻辑
return nil
}
func (r *CronJob) ValidateUpdate(old runtime.Object) error {
cronjoblog.Info("validate update", "name", r.Name)
// 更新时的验证逻辑
return nil
}
func (r *CronJob) ValidateDelete() error {
cronjoblog.Info("validate delete", "name", r.Name)
// 删除时的验证逻辑
return nil
}
结论
通过运行 kubebuilder create webhook
命令并指定相应参数,可以为 CronJob
资源创建默认值设置和程序化验证的 Webhook。这些 Webhook 可以帮助自动填充默认值并确保资源的合法性,提升资源管理的自动化和可靠性。
5 | 部署 webhook
-
需要注意的是
- 上面编写的 webhook 没有建议的验证命令,如 make run 验证并调试 controller
- webhook 需要和 controller 一起部署到集群中后,才能验证
- 而又来个问题,webhook 需要证书
-
所以为了便捷调试 controller,我们增加了一个 webhook 开关,来控制 webhook 是否开启
-
// 在 main 函数中增加此段逻辑 if os.Getenv("ENABLE_WEBHOOKS") != "false" { if err = (&batchv1.CronJob{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "unable to create webhook", "webhook", "Captain") os.Exit(1) } }
-
进行 controller 调试
-
# 不开启 webhook $ make run ENABLE_WEBHOOKS=false # 开启 webhook 会报错,缺少证书 $ make run ENABLE_WEBHOOKS=true
-
5.1 安装cert-manager
-
为什么需要给webhook提供证书
- API Server 通过 HTTPS POST 访问 Webhook Server, 因此 Webhook Server 必须要监听在 https 协议上
- 因此我们需要给webhook提供证书
-
kubebuilder官方也 建议使用 cert-manager 为 webhook 服务器提供证书
-
安装cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.yaml
-
查看安装结果
[root@localhost cert-manager]# kubectl get pod -n cert-manager NAME READY STATUS RESTARTS AGE cert-manager-7fb948f468-r5dj2 1/1 Running 0 142m cert-manager-cainjector-75c5fc965c-shtx6 1/1 Running 0 142m cert-manager-webhook-757c9d4bb7-vhgt7 1/1 Running 0 142m [root@localhost cert-manager]# kubectl get ValidatingWebhookConfiguration NAME WEBHOOKS AGE cert-manager-webhook 1 143m [root@localhost cert-manager]# kubectl get MutatingWebhookConfiguration NAME WEBHOOKS AGE cert-manager-webhook 1 143m
5.2 修改配置文件
让我们的webhook,使用cert-manager提供的证书,还需要修改项目中的几个配置文件
不同的 kubebuilder 版本修改的可能不一致,但逻辑都是间 cert manager 相关注释解开即可
-
修改
config/default/kustomization.yaml
,将关于WEBHOOK、CERTMANAGER 的 都取消注释即可# Adds namespace to all resources. namespace: cronjob-operator-system # Value of this field is prepended to the # names of all resources, e.g. a deployment named # "wordpress" becomes "alices-wordpress". # Note that it should also match with the prefix (text before '-') of the namespace # field above. namePrefix: cronjob-operator- # Labels to add to all resources and selectors. #labels: #- includeSelectors: true # pairs: # someName: someValue resources: - ../crd - ../rbac - ../manager # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - ../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. - ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. - ../prometheus patches: # Protect the /metrics endpoint by putting it behind auth. # If you want your controller-manager to expose the /metrics # endpoint w/o any authn/z, please comment the following line. - path: manager_auth_proxy_patch.yaml # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - path: manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. # 'CERTMANAGER' needs to be enabled to use ca injection - path: webhookcainjection_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. # Uncomment the following replacements to add the cert-manager CA injection annotations replacements: - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs kind: Certificate group: cert-manager.io version: v1 name: serving-cert # this name should match the one in certificate.yaml fieldPath: .metadata.namespace # namespace of the certificate CR targets: - select: kind: ValidatingWebhookConfiguration fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 0 create: true - select: kind: MutatingWebhookConfiguration fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 0 create: true - select: kind: CustomResourceDefinition fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 0 create: true - source: kind: Certificate group: cert-manager.io version: v1 name: serving-cert # this name should match the one in certificate.yaml fieldPath: .metadata.name targets: - select: kind: ValidatingWebhookConfiguration fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 1 create: true - select: kind: MutatingWebhookConfiguration fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 1 create: true - select: kind: CustomResourceDefinition fieldPaths: - .metadata.annotations.[cert-manager.io/inject-ca-from] options: delimiter: '/' index: 1 create: true - source: # Add cert-manager annotation to the webhook Service kind: Service version: v1 name: webhook-service fieldPath: .metadata.name # namespace of the service targets: - select: kind: Certificate group: cert-manager.io version: v1 fieldPaths: - .spec.dnsNames.0 - .spec.dnsNames.1 options: delimiter: '.' index: 0 create: true - source: kind: Service version: v1 name: webhook-service fieldPath: .metadata.namespace # namespace of the service targets: - select: kind: Certificate group: cert-manager.io version: v1 fieldPaths: - .spec.dnsNames.0 - .spec.dnsNames.1 options: delimiter: '.' index: 1 create: true
-
修改
config/crd/kustomization.yaml
,为每个 CRD 启用 CA 注入# This kustomization.yaml is not intended to be run by itself, # since it depends on service name and namespace that are out of this kustomize package. # It should be run by config/default resources: - bases/batch.graham924.com_cronjobs.yaml #+kubebuilder:scaffold:crdkustomizeresource patches: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD - path: patches/webhook_in_cronjobs.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD - path: patches/cainjection_in_cronjobs.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # [WEBHOOK] To enable webhook, uncomment the following section # the following config is for teaching kustomize how to do kustomization for CRDs. configurations: - kustomizeconfig.yaml
5.3 开启webhook环境变量开关
export ENABLE_WEBHOOKS=true
5.4 打包镜像并上传仓库
# 打包镜像并上传到仓库
make docker-build docker-push IMG=dfy-cronjob-operator:v2
# 此处打包镜像,但不上传到仓库,因为是本地调试
# IMG 是指定镜像名称,若不指定,其会使用 Makefile 中默认的 IMG 变量名称
make docker-build IMG=dfy-cronjob-operator:v2
# 采用的是 kind 集群
# 查看当前使用的 kind 集群名称
kubectl config current-context
# 将镜像导入到 kind 集群
kind load docker-image dfy-cronjob-operator:v2 --name k8s-cluster-ingress
# 执行部署
make deploy IMG=dfy-cronjob-operator:v2
无法运行排错
-
查看部署的 deployment 镜像拉取策略是否为 IfNotPresent 策略
-
若不为,可修改镜像 pull 策略。 在
/config/manager/manager.yaml
配置文件中, 添加imagePullPolicy
策略。 由于本地开发, 并不准备上传到云上, 所以设置为IfNotPresent
。-
spec: securityContext: runAsNonRoot: true containers: - command: - /manager args: - --leader-elect image: controller:latest name: manager ## 由于不上传到镜像仓库, 所以这里以本地编译的版本为准 imagePullPolicy: IfNotPresent
-
5.5 部署和验证
make deploy IMG=dfy-cronjob-operator:v2
kubectl create -f config/samples/batch_v1_cronjob.yaml
- 可以修改
config/samples/batch_v1_cronjob.yaml
,为schedule写一个错误的cron表达式,看是否会创建成功。- 期望情况是创建的时候就会报错cron验证失败