序言
人生是一场消耗,要把美好的时光放在喜欢的人与事上。
写在前面
前面学习了job,现在思考一下两个问题
文章标记颜色说明:
- 黄色:重要标题
- 红色:用来标记结论
- 绿色:用来标记一级论点
- 蓝色:用来标记二级论点
第1个问题
job执行完之后不会立刻从k8s面板里删除,你可以看到有很多留存状态的记录,如果cronjob频次很高,留下的这些job记录就会增长,有没有隐患?
解答:
频繁留存未删除的Job记录可能会导致以下隐患:
浪费资源:每个Job都需要占用一定的资源,包括CPU、内存等,如果留存的Job记录过多,就会浪费宝贵的资源。
影响性能:Kubernetes控制面板需要定期查询Job状态,如果留存的Job记录过多,会增加查询负担,从而影响Kubernetes控制面板的性能。
安全问题:留存的Job记录可能包含敏感信息,如镜像仓库的凭证、配置文件等,如果泄露给攻击者,可能会导致安全问题。
为了避免以上隐患,建议定期清理过期的Job记录,可以通过配置Job的TTL来实现自动清理。另外,也可以通过手动删除已完成的Job记录来进行清理。
那如何实现清理呢?
好的,我可以再详细一点地解释一下如何清理过期的Job记录。
在Kubernetes中,可以通过设置Job的TTL(time to live)来自动删除过期的Job记录。TTL是指Job完成后保留在系统中的最长时间,超过这个时间后,Job记录将自动被删除。设置TTL需要在Job的spec中指定activeDeadlineSeconds字段,例如:
apiVersion: batch/v1 kind: Job #资源类型 metadata: name: my-job spec: activeDeadlineSeconds: 3600 # 设置TTL为1小时 template: # ...
上面的配置将设置TTL为1小时,即Job完成后最多保留1小时。
除了设置TTL外,还可以通过手动删除已完成的Job记录来进行清理。可以使用kubectl命令来删除Job记录,例如:
kubectl delete job my-job
上面的命令将删除名为my-job的Job记录。如果要删除所有已完成的Job记录,可以使用以下命令:
kubectl delete jobs --field-selector=status.successful>0
这个命令将删除所有已完成的Job记录,其中--field-selector=status.successful>0表示只删除成功完成的Job记录。
需要注意的是,手动删除Job记录可能会删除一些有用的信息,因此建议先备份相关数据再进行清理。另外,如果Job频繁执行,建议使用自动清理的方式来避免留存过多的Job记录。
怎么实现自动清理?
实现自动清理可以使用 Kubernetes 的 TTL Controller。
TTL Controller 是 Kubernetes 的一个控制器,它可以根据资源的 TTL 设置自动删除过期的资源。TTL Controller 可以应用于许多 Kubernetes 资源,包括 Job、Pod、Secret 等。
要使用 TTL Controller,需要先创建一个 TTL Controller 的定义文件,内容如下:
apiVersion: batch/v1 kind: CronJob #资源类型 metadata: name: ttl-controller spec: schedule: "*/5 * * * *" # 定时清理任务 jobTemplate: spec: ttlSecondsAfterFinished: 3600 # 设置TTL为1小时 template: # 定义清理任务的容器 spec: containers: - name: clean-jobs image: alpine:latest command: ["sh", "-c", "kubectl delete jobs --field-selector=status.successful>0"]
上面的定义文件将创建一个 CronJob,用于定时清理已完成的 Job 记录。其中,schedule 字段用于指定定时清理任务的执行时间,这里设置为每 5 分钟执行一次;ttlSecondsAfterFinished 字段用于设置 Job 记录的 TTL,这里设置为 1 小时;template 字段中的容器定义了清理任务的执行逻辑,这里使用了 Alpine Linux 镜像,并通过 kubectl 命令删除已完成的 Job 记录。
将上述定义文件保存为 ttl-controller.yaml,并使用 kubectl apply 命令来创建 TTL Controller:
kubectl apply -f ttl-controller.yaml
这样,TTL Controller 就会自动执行定时清理任务,删除过期的 Job 记录。需要注意的是,TTL Controller 只能删除已完成的 Job 记录,因此需要确保 Job 完成后才会留下记录。另外,建议根据实际情况调整 TTL 的值和定时清理任务的频率。
第2个问题
在业务开发过程中,开发人员有可能不能直接操作k8s,而定时任务在业务中更新又很快,按你这种方式是每次变动都需要k8s管理人员操作的,怎么样把定时任务的更新交给开发人员管理?
解答:
1 使用 Workload Identity实现
为了让业务开发人员能够方便地管理定时任务,可以使用 Kubernetes 的 Workload Identity 功能。
Workload Identity 是 Kubernetes 的一项安全功能,可以将 Kubernetes 中的服务账号与 Google Cloud 平台上的服务账号关联起来。
使用 Workload Identity 可以让 Kubernetes 中的服务账号获得访问 Google Cloud 平台资源的权限,从而实现业务开发人员管理 Kubernetes 资源的目的。
具体来说,可以按照以下步骤使用 Workload Identity 来让业务开发人员管理定时任务:
在 Google Cloud 平台上创建一个服务账号,并授予它适当的权限,例如访问 Kubernetes API 的权限。
在 Kubernetes 中创建一个 ServiceAccount,并将它与上述服务账号关联起来。可以使用以下命令创建 ServiceAccount,并将它与服务账号关联:
kubectl create serviceaccount my-sa gcloud iam service-accounts add-iam-policy-binding --role roles/iam.workloadIdentityUser --member "serviceAccount:my-project.svc.id.goog[my-namespace/my-sa]" my-sa@my-project.iam.gserviceaccount.com kubectl annotate serviceaccount --namespace my-namespace my-sa iam.gke.io/gcp-service-account=my-sa@my-project.iam.gserviceaccount.com ``` 上述命令中,my-sa 是创建的 ServiceAccount 的名称,my-project 和 my-namespace 分别是 [Google Cloud](poe://www.poe.com/_api/key_phrase?phrase=Google%20Cloud&prompt=Tell%20me%20more%20about%20Google%20Cloud.) 平台和 Kubernetes 集群的项目和命名空间名称。
在 Kubernetes 中创建一个 Role 或 ClusterRole,并授予它适当的权限,例如创建、删除 Job 的权限。
将上述 Role 或 ClusterRole 与 ServiceAccount 关联起来。可以使用以下命令创建 RoleBinding 或 ClusterRoleBinding,例如:
kubectl create rolebinding my-role-binding --role=my-role --serviceaccount=my-namespace:my-sa --namespace=my-namespace ``` 上述命令中,my-role 是上述创建的 Role 或 ClusterRole 的名称,my-namespace 是 Kubernetes 集群的命名空间名称。
将上述 ServiceAccount 的密钥添加到业务应用程序中,以便在调用 Kubernetes API 时使用。可以使用以下命令来获取 ServiceAccount 的密钥:
kubectl get secret --namespace my-namespace $(kubectl get serviceaccount my-sa --namespace my-namespace -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode ``` 这个命令将获取 ServiceAccount 的密钥,并将其解码为原始的 token 字符串。
通过上述步骤,业务开发人员就可以使用 ServiceAccount 的密钥来调用 Kubernetes API,从而创建、更新、删除定时任务等资源。需要注意的是,业务开发人员只能访问被授权的资源和操作,不能访问其他资源和操作。另外,需要确保在使用 Workload Identity 时,密钥不被泄露,以保障安全性。
2 使用 RBAC(Role-Based Access Control)功能
除了使用 Workload Identity,还可以使用 Kubernetes 的 RBAC(Role-Based Access Control)功能来实现业务开发人员管理定时任务。
RBAC 是 Kubernetes 的一项安全功能,可以通过定义角色、角色绑定等方式来控制用户对 Kubernetes 资源的访问权限。使用 RBAC 可以将 Kubernetes 资源的管理权限授权给特定的用户或组,从而实现业务开发人员管理 Kubernetes 资源的目的。
具体来说,可以按照以下步骤使用 RBAC 来让业务开发人员管理定时任务:
在 Kubernetes 中创建一个 ServiceAccount,并为它授予适当的权限,例如创建、删除 Job 的权限。可以使用以下命令创建 ServiceAccount:
kubectl create serviceaccount my-sa ```
在 Kubernetes 中创建一个 Role 或 ClusterRole,并授予它适当的权限,例如创建、删除 Job 的权限。可以使用以下命令创建 Role 或 ClusterRole:
kubectl create role my-role --verb=create,get,update,delete --resource=jobs ``` 上述命令中,my-role 是创建的 Role 或 ClusterRole 的名称,--verb 和 --resource 参数分别用于指定授权的操作和资源类型,这里授权了创建、获取、更新和删除 Job 的权限。
将上述 Role 或 ClusterRole 与 ServiceAccount 关联起来。可以使用以下命令创建 RoleBinding 或 ClusterRoleBinding,例如:
kubectl create rolebinding my-role-binding --role=my-role --serviceaccount=my-namespace:my-sa --namespace=my-namespace ``` 上述命令中,my-role 是上述创建的 Role 或 ClusterRole 的名称,my-namespace 是 Kubernetes 集群的命名空间名称。
将 ServiceAccount 的密钥提供给业务开发人员,以便在调用 Kubernetes API 时使用。可以使用以下命令来获取 ServiceAccount 的密钥:
kubectl get secret --namespace my-namespace $(kubectl get serviceaccount my-sa --namespace my-namespace -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode ``` 这个命令将获取 ServiceAccount 的密钥,并将其解码为原始的 token 字符串。
通过上述步骤,业务开发人员就可以使用 ServiceAccount 的密钥来调用 Kubernetes API,从而创建、更新、删除定时任务等资源。需要注意的是,业务开发人员只能访问被授权的资源和操作,不能访问其他资源和操作。另外,需要确保在授权时,只授权必要的权限,以保障安全性。
3 使用项目代码实现定时任务
大部分,简单的定时任务,一般是用语言自带的定时任务去实现。