使用不同的命令重新启动 Kubernetes 作业或 Pod

Mar*_*lka 8 kubernetes kubectl kubernetes-jobs

我正在寻找一种从命令行快速运行/重新启动作业/Pod 并覆盖要在创建的容器中执行的命令的方法。

对于上下文,我有一个 Kubernetes 作业,它作为部署过程的一部分执行。有时该作业会崩溃,我需要在作业创建的容器内运行某些命令来调试和修复问题(后续作业会成功)。

到目前为止我这样做的方法是:

  • 复制作业的 YAML,保存到文件中
  • 清理 YAML(删除 Kubernetes 管理的字段)
  • command:字段更改为tail -f /dev/null(以便容器保持活动状态)
  • kubectl apply -f job.yaml && kubectl get all && kubectl exec -ti pod/foobar bash
  • 在容器内运行命令
  • kubectl delete job/foobar当我完成时

这是非常乏味的。我正在寻找一种方法来做类似以下的事情

kubectl restart job/foobar --command "tail -f /dev/null"

# or even better
kubectl run job/foobar --exec --interactive bash
Run Code Online (Sandbox Code Playgroud)

我无法使用以下run命令创建 Pod:

kubectl restart job/foobar --command "tail -f /dev/null"

# or even better
kubectl run job/foobar --exec --interactive bash
Run Code Online (Sandbox Code Playgroud)

因为我尝试重新启动的作业具有volumeMounts我需要重用的某些配置和其他配置。所以我需要类似的东西kubectl run --from-config job/foobar


有没有办法实现这一点,或者我是否一直在处理 YAML 定义文件?


编辑:作业 YAML 看起来大约。像这样:

kubectl run --image xxx -ti
Run Code Online (Sandbox Code Playgroud)

小智 8

您建议的命令不存在。查看此参考,您可以在其中找到所有可用的命令。

根据该文档,作业的任务是创建一个或多个 Pod 并继续重试执行它们,直到达到指定数量的成功终止 Pod。然后作业会跟踪成功的完成情况。您不能只更新作业,因为这些字段不可更新。要执行您想要的操作,您应该删除当前作业并重新创建一个。


我建议您将所有配置保存在文件中。如果您在配置作业命令时遇到问题,实践表明您应该在 yaml 中修改这些设置并应用于集群 - 如果您的部署崩溃 - 通过将配置存储在文件中,您就有了备份。

如果您有兴趣如何改进此任务,您可以尝试下面描述的两个示例:

首先我创建了几个文件:

作业示例 ( job.yaml):

apiVersion: batch/v1
kind: Job
metadata:
  name: test1
spec:
  template:
    spec:
      containers:
      - name: test1
        image: busybox
        command: ["/bin/sh", "-c", "sleep 300"]
        volumeMounts:
        - name: foo
          mountPath: "/script/foo"
      volumes:
      - name: foo
        configMap:
          name: my-conf
          defaultMode: 0755
      restartPolicy: OnFailure
Run Code Online (Sandbox Code Playgroud)

patch-file.yaml:

spec:
  template:
    spec:
      containers:
      - name: test1
        image: busybox
        command: ["/bin/sh", "-c", "echo 'patching test' && sleep 500"]
Run Code Online (Sandbox Code Playgroud)

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-conf
data:
  test: |
    #!/bin/sh
    echo "skrypt test"
Run Code Online (Sandbox Code Playgroud)
  1. 如果你想自动化这个过程,你可以使用plugin

插件是一个独立的可执行文件,其名称以kubectl-. 要安装插件,请将其可执行文件移动到PATH.

无需安装或预加载插件。插件可执行文件从二进制文件接收继承的环境kubectl。插件根据其名称确定它希望实现的命令路径。

这是可以取代您工作的文件

插件根据其文件名确定它将实现的命令路径。

kubectl-job:

#!/bin/bash
kubectl patch -f job.yaml -p "$(cat patch-job.yaml)" --dry-run=client -o yaml | kubectl replace --force -f - && kubectl wait --for=condition=ready pod -l job-name=test1 && kubectl exec -it $(kubectl get pod -l job-name=test1 --no-headers -o custom-columns=":metadata.name") -- /bin/sh
Run Code Online (Sandbox Code Playgroud)

该命令使用一个附加文件(patch-job.yaml请参阅此链接) - 我们可以将更改放入其中job

然后您应该更改该文件的权限并移动它:

sudo chmod +x .kubectl-job
sudo mv ./kubectl-job /usr/local/bin
Run Code Online (Sandbox Code Playgroud)

一切都完成了。现在你就可以使用它了。

$ kubectl job
job.batch "test1" deleted
job.batch/test1 replaced
pod/test1-bdxtm condition met
pod/test1-nh2pv condition met
/ #
Run Code Online (Sandbox Code Playgroud)

如您所见,Job已被替换(删除和创建)。


  1. 您还可以使用单行命令,示例如下:
kubectl get job test1 -o json | jq "del(.spec.selector)" | jq "del(.spec.template.metadata.labels)" | kubectl patch -f - --patch '{"spec":  {"template":  {"spec":  {"containers": [{"name": "test1", "image": "busybox", "command": ["/bin/sh", "-c",  "sleep 200"]}]}}}}' --dry-run=client -o yaml | kubectl replace --force -f -
Run Code Online (Sandbox Code Playgroud)

使用此命令,您可以更改“手动”输入参数的工作。这是输出:

job.batch "test1" deleted
job.batch/test1 replaced
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这个解决方案也有效。