是否可以重新运行 kubernetes 作业?

Bos*_*one 80 docker kubernetes

我有以下 Kubernetes 作业配置:

---
apiVersion: batch/v1
kind: Job
metadata:
  name: dbload
  creationTimestamp: 
spec:
  template:
    metadata:
      name: dbload
    spec:
      containers:
      - name: dbload
        image: sdvl3prox001:7001/pbench/tdload
        command: ["/opt/pbench/loadTpcdsData.sh",  "qas0063", "dbc", "dbc", "1"]
      restartPolicy: Never
      imagePullSecrets: 
        - name: pbenchregkey
status: {}
Run Code Online (Sandbox Code Playgroud)

当我完成kubectl create -f dbload-deployment.yml --record这项工作并创建了一个 pod 时,Docker 容器运行完成,我得到以下状态:

$ kubectl get job dbload
NAME      DESIRED   SUCCESSFUL   AGE
dbload    1         1            1h
$ kubectl get pods -a
NAME           READY     STATUS      RESTARTS   AGE
dbload-0mk0d   0/1       Completed   0          1h
Run Code Online (Sandbox Code Playgroud)

这项工作是一次性交易,我需要能够重新运行它。如果我尝试使用kubectl create命令重新运行它,我会收到此错误

$ kubectl create -f dbload-deployment.yml --record
Error from server: error when creating "dbload-deployment.yml": jobs.batch "dbload" already exists
Run Code Online (Sandbox Code Playgroud)

当然我可以做kubectl delete job dbload然后跑,kubectl create但我想知道我是否可以以某种方式重新唤醒已经存在的工作?

F. *_*ago 62

您可以通过将作业替换为自身来模拟重新运行:

  1. 启动你的工作
  • kubectl get job "your-job" -o json > your-job.json
  1. 替换原地工作
  • kubectl get job "your-job" -o json | kubectl replace --force -f -

如果由于自动生成的标签或选择器而出现错误,您可以使用 jq 删除或编辑它们:

  • kubectl get job "your-job" -o json | jq 'del(.spec.selector)' | jq 'del(.spec.template.metadata.labels)' | kubectl replace --force -f -

更新Jeremy Huiskamp的建议

  • 强烈建议先将作业 json 的副本保存到文件中。`kubectl replace` 在遇到重新创建它的错误之前删除该作业。 (5认同)
  • 先保存json,然后重新创建! (2认同)

coh*_*dar 47

不,绝对没有办法重新运行 kubernetes 作业。您需要先将其删除。

  • 可以使用“kubectl Replace --force”一步完成 - 如果作业存在,它将删除该作业,然后无条件(重新)创建它。见下文。 (7认同)
  • 像我这样需要更多细节的人 - 这是两个步骤的过程。首先使用 `kubectl delete job <job_name>` 删除你的作业,然后使用 `kubectl apply -f <job_yml>` (5认同)

vp1*_*124 38

您还可以通过指定来避免您提到的错误

  generateName: dbload
Run Code Online (Sandbox Code Playgroud)

而不是简单地 name

在这种情况下,您使用此 yaml 文件提交的每个作业都将具有一个唯一名称,类似于dbloada1b2c. 然后,你可以决定你是否需要删除旧的工作,但你不会这样做。

这是一个有效的 yaml 示例:

apiVersion: batch/v1
kind: Job
metadata:
  generateName: netutils-
spec:
  parallelism: 1
  template:
    spec:
      containers:
      - image: amouat/network-utils 
        name: netutil
      restartPolicy: Never

Run Code Online (Sandbox Code Playgroud)

这是kubectl get job两个kubectl create -f example.yaml命令后的输出:

NAME             COMPLETIONS   DURATION   AGE
netutils-5bs2s   0/1           14s        14s
netutils-dsvfk   0/1           10s        10s

Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你的这个闪避。仅用于文档,这只适用于 `kubectl create` (5认同)
  • 不,它是 ObjectMeta 的标准部分,适用于 pod 和作业:[k8s 参考](https://kubernetes.io/docs/resources-reference/v1.7/#objectmeta-v1-meta)。我一直在使用它,这是我所做工作的核心。 (4认同)
  • 你是用 `kubectl create` 还是 `kubectl apply` 创建你的工作?根据此参考,后者将不起作用:https://github.com/kubernetes/kubernetes/issues/44501。所以你必须做`kubectl create`。我也刚刚在 Azure 上尝试过,它也可以在那里工作。`kubectl version` 在 AKS 上显示 `v1.15.10`,在 GKE 上显示 `v1.14.10-gke.27` ok,但就像我说的,我已经这样做了很长时间,所以它也适用于早期版本。 (2认同)

小智 7

作为@F 的改进。"kubectl.kubernetes.io/last-applied-configuration"圣地亚哥的想法是,您可以简单地使用存储在保存初始应用配置的注释中的值,而无需任何自动生成的字段:

kubectl get job <jobname> -o json | \
jq -r '.metadata.annotations."kubectl.kubernetes.io/last-applied-configuration"' | \
kubectl replace --save-config --force -f -
Run Code Online (Sandbox Code Playgroud)

注意:对于kubectl replace,请记住传递,--save-config以便它使用最后应用的配置更新注释字段。