如何将 kubernetes 命名空间动态传递给 k8s cronjob
How to pass kubernetes namespaces dynamically to k8s cronjob
我有一个 cronjob 可以清理一些工作,因为我的 kubernetes 是旧版本所以不能使用 ttlafterfinished
。我如何才能获取已部署此作业的命名空间并动态传递命名空间名称,而不是多次重复相同的命令?
这是我的定时任务:
kind: CronJob
metadata:
name: jobs-cleanup
spec:
schedule: "*/30 * * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
serviceAccountName: cleanup-operator
containers:
- name: jobs-cleanup
image: google.io/test/job:1.0
args:
- -c
- |
for i in $(seq 9);do
kubectl get jobs --sort-by=.metadata.creationTimestamp -n dev$i | grep "job-init" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n dev$i;done
kubectl get jobs --sort-by=.metadata.creationTimestamp -n stg1 | grep "fusionauth-job" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n stg1
kubectl get jobs --sort-by=.metadata.creationTimestamp -n pt1 | grep "fusionauth-job" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n pt1
kubectl get jobs --sort-by=.metadata.creationTimestamp -n sit1 | grep "fusionauth-job" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n sit1
command:
- /bin/sh
restartPolicy: Never
imagePullSecrets:
- name: secret
比您现在所做的更灵活的替代方法是将要删除的作业名称列表存储在 list/array 中。然后,您可以遍历作业名称列表并执行命令。
下面是您的命令的一个更简单的 (IMO) 版本,它使用 -o=jsonpath
支持而不是 kubectl
来指定搜索条件。
# The list of jobs you want to delete from any/all namespaces.
jobs_list="job-init fusionauth-job"
for job_name in ${jobs_list}; do
kubectl get jobs -A --sort-by=.metadata.creationTimestamp \
-o=jsonpath="{range .items[?(@.metadata.name == '${job_name}')]}{.metadata.namespace} {.metadata.name}{'\n'}{end}" \
| while read namespace job;do kubectl delete job ${job} -n ${namespace};done;
done
The following was added as a result of the comments/conversation below.
如果您的集群中的作业名称具有递增的后缀,例如 fusionauth-job-01
、fusionauth-job-02
等,并且您希望仅 保持最新该作业在特定命名空间中的实例,那么您将需要利用 jq
之类的东西,以便您可以进行一些正则表达式匹配。 kubectl
的 jsonpath
功能不支持正则表达式。
例如,假设您的集群具有如下所示的作业。
NAMESPACE NAME
default fusionauth-job-01
team1 fusionauth-job-01
team1 fusionauth-job-02
team1 job-init-01
team1 job-init-02
team2 fusionauth-job-01
team2 fusionauth-job-02
team2 fusionauth-job-03
此外,作业按时间戳顺序列出,这意味着 fusionauth-job-03
是命名空间 team2
中的最新作业(其名称匹配 fusionauth-job*
),job-init-02
是命名空间 team1
中的最新作业(其名称匹配 job-init*
),fusionauth-job-02
是命名空间 team1
中的最新作业(具有该名称模式),而 fusionauth-job-01
是命名空间 default
.
中唯一的作业 运行
在 运行 你的 jobs-cleanup
工作之后,预计将留下以下工作:
NAMESPACE NAME
default fusionauth-job-01
team1 fusionauth-job-02
team1 job-init-02
team2 fusionauth-job-03
此处显示了生成这些结果的脚本:
# The list of job name prefixes you want to delete from any/all namespaces.
jobs_list="job-init fusionauth-job"
for job_name in ${jobs_list}; do
ns_observed=""
echo "Searching for ${job_name}*"
kubectl get jobs -A --sort-by=.metadata.creationTimestamp -o json \
| jq -r '.items[] | select(.metadata.name | test('\"${job_name}\"')) | .metadata.namespace + " " + .metadata.name' \
| tac \
| while read namespace job;do
if test "${ns_observed#*$namespace}" != "$ns_observed";then
# If we've seen this namespace already for this job, then delete the
# job, since the one we found previously is the newest.
kubectl delete job ${job} -n ${namespace};
else
# Otherwise, if this is the first time observing this namespace, then
# this is the newest job that starts with this job name in this namespace.
ns_observed="$ns_observed $namespace";
fi;
done;
done
我有一个 cronjob 可以清理一些工作,因为我的 kubernetes 是旧版本所以不能使用 ttlafterfinished
。我如何才能获取已部署此作业的命名空间并动态传递命名空间名称,而不是多次重复相同的命令?
这是我的定时任务:
kind: CronJob
metadata:
name: jobs-cleanup
spec:
schedule: "*/30 * * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
serviceAccountName: cleanup-operator
containers:
- name: jobs-cleanup
image: google.io/test/job:1.0
args:
- -c
- |
for i in $(seq 9);do
kubectl get jobs --sort-by=.metadata.creationTimestamp -n dev$i | grep "job-init" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n dev$i;done
kubectl get jobs --sort-by=.metadata.creationTimestamp -n stg1 | grep "fusionauth-job" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n stg1
kubectl get jobs --sort-by=.metadata.creationTimestamp -n pt1 | grep "fusionauth-job" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n pt1
kubectl get jobs --sort-by=.metadata.creationTimestamp -n sit1 | grep "fusionauth-job" | cut -d' ' -f1 | tac | tail -n +2 | xargs -I % kubectl delete jobs % -n sit1
command:
- /bin/sh
restartPolicy: Never
imagePullSecrets:
- name: secret
比您现在所做的更灵活的替代方法是将要删除的作业名称列表存储在 list/array 中。然后,您可以遍历作业名称列表并执行命令。
下面是您的命令的一个更简单的 (IMO) 版本,它使用 -o=jsonpath
支持而不是 kubectl
来指定搜索条件。
# The list of jobs you want to delete from any/all namespaces.
jobs_list="job-init fusionauth-job"
for job_name in ${jobs_list}; do
kubectl get jobs -A --sort-by=.metadata.creationTimestamp \
-o=jsonpath="{range .items[?(@.metadata.name == '${job_name}')]}{.metadata.namespace} {.metadata.name}{'\n'}{end}" \
| while read namespace job;do kubectl delete job ${job} -n ${namespace};done;
done
The following was added as a result of the comments/conversation below.
如果您的集群中的作业名称具有递增的后缀,例如 fusionauth-job-01
、fusionauth-job-02
等,并且您希望仅 保持最新该作业在特定命名空间中的实例,那么您将需要利用 jq
之类的东西,以便您可以进行一些正则表达式匹配。 kubectl
的 jsonpath
功能不支持正则表达式。
例如,假设您的集群具有如下所示的作业。
NAMESPACE NAME
default fusionauth-job-01
team1 fusionauth-job-01
team1 fusionauth-job-02
team1 job-init-01
team1 job-init-02
team2 fusionauth-job-01
team2 fusionauth-job-02
team2 fusionauth-job-03
此外,作业按时间戳顺序列出,这意味着 fusionauth-job-03
是命名空间 team2
中的最新作业(其名称匹配 fusionauth-job*
),job-init-02
是命名空间 team1
中的最新作业(其名称匹配 job-init*
),fusionauth-job-02
是命名空间 team1
中的最新作业(具有该名称模式),而 fusionauth-job-01
是命名空间 default
.
在 运行 你的 jobs-cleanup
工作之后,预计将留下以下工作:
NAMESPACE NAME
default fusionauth-job-01
team1 fusionauth-job-02
team1 job-init-02
team2 fusionauth-job-03
此处显示了生成这些结果的脚本:
# The list of job name prefixes you want to delete from any/all namespaces.
jobs_list="job-init fusionauth-job"
for job_name in ${jobs_list}; do
ns_observed=""
echo "Searching for ${job_name}*"
kubectl get jobs -A --sort-by=.metadata.creationTimestamp -o json \
| jq -r '.items[] | select(.metadata.name | test('\"${job_name}\"')) | .metadata.namespace + " " + .metadata.name' \
| tac \
| while read namespace job;do
if test "${ns_observed#*$namespace}" != "$ns_observed";then
# If we've seen this namespace already for this job, then delete the
# job, since the one we found previously is the newest.
kubectl delete job ${job} -n ${namespace};
else
# Otherwise, if this is the first time observing this namespace, then
# this is the newest job that starts with this job name in this namespace.
ns_observed="$ns_observed $namespace";
fi;
done;
done