使用不同的命令重新启动 Kubernetes 作业或 Pod
Restart a Kubernetes Job or Pod with a different command
我正在寻找一种从命令行快速 run/restart 一个 Job/Pod 并覆盖要在创建的容器中执行的命令的方法。
对于上下文,我有一个 Kubernetes 作业作为部署过程的一部分执行。有时那个作业崩溃了,我需要 运行 在作业创建的容器内 某些命令 来调试和修复问题(随后的作业然后成功)。
到目前为止我这样做的方法是:
- 复制Job的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
命令创建 Pod:
kubectl run --image xxx -ti
因为我尝试重新启动的作业有某些 volumeMounts
和我需要重用的其他配置。所以我需要像 kubectl run --from-config job/foobar
.
这样的东西
有没有办法实现这个,还是我一直在处理 YAML 定义文件?
编辑:作业 YAML 看起来大约。像这样:
apiVersion: batch/v1
kind: Job
metadata:
name: database-migrations
labels:
app: myapp
service: myapp-database-migrations
spec:
backoffLimit: 0
template:
metadata:
labels:
app: myapp
service: myapp-database-migrations
spec:
restartPolicy: Never
containers:
- name: migrations
image: registry.example.com/myapp:977b44c9
command:
- "bash"
- "-c"
- |
set -e -E
echo "Running database migrations..."
do-migration-stuff-here
echo "Migrations finished at $(date)"
imagePullPolicy: Always
volumeMounts:
- mountPath: /home/example/myapp/app/config/conf.yml
name: myapp-config-volume
subPath: conf.yml
- mountPath: /home/example/myapp/.env
name: myapp-config-volume
subPath: .env
volumes:
- name: myapp-config-volume
configMap:
name: myapp
imagePullSecrets:
- name: k8s-pull-project
您建议的命令不存在。查看 this reference,您可以在其中找到所有可用的命令。
在that documentation the task of the Job的基础上,创建一个或多个Pods,并不断重试执行,直到达到指定的成功终止次数。然后 Job 跟踪成功完成。您不能只更新作业,因为这些字段不可更新。要做你想做的事,你应该删除当前的工作并重新创建一个。
我建议您将所有配置保存在文件中。如果您在配置作业命令时遇到问题,实践表明您应该在 yaml 中修改这些设置并应用于集群 - 如果您的部署崩溃 - 通过将配置存储在文件中,您有一个备份。
如果您对如何改进此任务感兴趣,可以尝试下面描述的这 2 个示例:
首先我创建了几个文件:
示例工作 (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
patch-file.yaml
:
spec:
template:
spec:
containers:
- name: test1
image: busybox
command: ["/bin/sh", "-c", "echo 'patching test' && sleep 500"]
和configmap.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-conf
data:
test: |
#!/bin/sh
echo "skrypt test"
- 如果您想自动执行此过程,您可以使用
plugin
A plugin is a standalone executable file, whose name begins with kubectl-
. To install a plugin, move its executable file to anywhere on your PATH
.
There is no plugin installation or pre-loading required. Plugin executables receive the inherited environment from the kubectl
binary. A plugin determines which command path it wishes to implement based on its name.
这是可以代替您工作的文件
A plugin determines the command path that it will implement based on its filename.
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
此命令使用了一个附加文件(patch-job.yaml
,请参阅此 link)- 我们可以将对 job
.
的更改放入其中
那么你应该更改这个文件的权限并移动它:
sudo chmod +x .kubectl-job
sudo mv ./kubectl-job /usr/local/bin
一切都完成了。现在你可以使用它了。
$ kubectl job
job.batch "test1" deleted
job.batch/test1 replaced
pod/test1-bdxtm condition met
pod/test1-nh2pv condition met
/ #
如您所见,Job
已被替换(删除并创建)。
- 你也可以使用单行命令,这里是例子:
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 -
使用此命令,您可以“手动”更改作业输入参数。这是输出:
job.batch "test1" deleted
job.batch/test1 replaced
如您所见,此解决方案同样有效。
我正在寻找一种从命令行快速 run/restart 一个 Job/Pod 并覆盖要在创建的容器中执行的命令的方法。
对于上下文,我有一个 Kubernetes 作业作为部署过程的一部分执行。有时那个作业崩溃了,我需要 运行 在作业创建的容器内 某些命令 来调试和修复问题(随后的作业然后成功)。
到目前为止我这样做的方法是:
- 复制Job的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
命令创建 Pod:
kubectl run --image xxx -ti
因为我尝试重新启动的作业有某些 volumeMounts
和我需要重用的其他配置。所以我需要像 kubectl run --from-config job/foobar
.
有没有办法实现这个,还是我一直在处理 YAML 定义文件?
编辑:作业 YAML 看起来大约。像这样:
apiVersion: batch/v1
kind: Job
metadata:
name: database-migrations
labels:
app: myapp
service: myapp-database-migrations
spec:
backoffLimit: 0
template:
metadata:
labels:
app: myapp
service: myapp-database-migrations
spec:
restartPolicy: Never
containers:
- name: migrations
image: registry.example.com/myapp:977b44c9
command:
- "bash"
- "-c"
- |
set -e -E
echo "Running database migrations..."
do-migration-stuff-here
echo "Migrations finished at $(date)"
imagePullPolicy: Always
volumeMounts:
- mountPath: /home/example/myapp/app/config/conf.yml
name: myapp-config-volume
subPath: conf.yml
- mountPath: /home/example/myapp/.env
name: myapp-config-volume
subPath: .env
volumes:
- name: myapp-config-volume
configMap:
name: myapp
imagePullSecrets:
- name: k8s-pull-project
您建议的命令不存在。查看 this reference,您可以在其中找到所有可用的命令。
在that documentation the task of the Job的基础上,创建一个或多个Pods,并不断重试执行,直到达到指定的成功终止次数。然后 Job 跟踪成功完成。您不能只更新作业,因为这些字段不可更新。要做你想做的事,你应该删除当前的工作并重新创建一个。
我建议您将所有配置保存在文件中。如果您在配置作业命令时遇到问题,实践表明您应该在 yaml 中修改这些设置并应用于集群 - 如果您的部署崩溃 - 通过将配置存储在文件中,您有一个备份。
如果您对如何改进此任务感兴趣,可以尝试下面描述的这 2 个示例:
首先我创建了几个文件:
示例工作 (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
patch-file.yaml
:
spec:
template:
spec:
containers:
- name: test1
image: busybox
command: ["/bin/sh", "-c", "echo 'patching test' && sleep 500"]
和configmap.yaml
:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-conf
data:
test: |
#!/bin/sh
echo "skrypt test"
- 如果您想自动执行此过程,您可以使用
plugin
A plugin is a standalone executable file, whose name begins with
kubectl-
. To install a plugin, move its executable file to anywhere on yourPATH
.There is no plugin installation or pre-loading required. Plugin executables receive the inherited environment from the
kubectl
binary. A plugin determines which command path it wishes to implement based on its name.
这是可以代替您工作的文件
A plugin determines the command path that it will implement based on its filename.
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
此命令使用了一个附加文件(patch-job.yaml
,请参阅此 link)- 我们可以将对 job
.
那么你应该更改这个文件的权限并移动它:
sudo chmod +x .kubectl-job
sudo mv ./kubectl-job /usr/local/bin
一切都完成了。现在你可以使用它了。
$ kubectl job
job.batch "test1" deleted
job.batch/test1 replaced
pod/test1-bdxtm condition met
pod/test1-nh2pv condition met
/ #
如您所见,Job
已被替换(删除并创建)。
- 你也可以使用单行命令,这里是例子:
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 -
使用此命令,您可以“手动”更改作业输入参数。这是输出:
job.batch "test1" deleted
job.batch/test1 replaced
如您所见,此解决方案同样有效。