我的CI工具使用生命周期,因此如果开发人员部署成功,它将转到QA。
我有一个端到端的测试容器,我想在kubernetes中运行,但我如何从容器中获得退出代码?
我能以某种方式运行容器并在一个命令中返回退出代码吗?
kubectl run -it
似乎没有得到退出代码,并且在容器完成后还有一些额外的事情要说。
要从Pod(容器(获取退出代码,可以使用以下命令获取Pod的详细信息:
kubectl get pod termination-demo --output=yaml
输出:
apiVersion: v1
kind: Pod
...
lastState:
terminated:
containerID: ...
exitCode: 0
finishedAt: ...
message: |
Sleep expired
...
要了解更多信息,您可以查看文档。
为了让它更容易,你希望你可以运行:
kubectl get pod busybox-term -ojson | jq .status.containerStatuses[].lastState.terminated.exitCode
或者,如果您不想安装jq
,您可以运行:
kubectl get pod busybox-term --output="jsonpath={.status.containerStatuses[].lastState.terminated.exitCode}"
mWatney之前提到过这种方式,所以我只在这里放了一些额外的细节:
通过这种方式,您可以从Pod返回退出代码0-255(255之后重新启动,256==0(。
-it
和--restart=Never
是必需的,--rm
是可选的,但对于移除失败的pod很有用--restart=Never
告诉生成器创建Pod对象,而不是部署。
$ kubectl run -it --rm exitcode --image=nginx --restart=Never -- bash -c "exit 0"
pod "exitcode" deleted
$ echo $?
0
$ kubectl run -it --rm exitcode --image=nginx --restart=Never -- bash -c "exit 1"
pod "exitcode" deleted
pod default/exitcode terminated (Error)
$ echo $?
1
$ kubectl run -it --rm exitcode --image=nginx --restart=Never -- bash -c "exit 8"
pod "exitcode" deleted
pod default/exitcode terminated (Error)
$ echo $?
8
$ kubectl run -it --rm exitcode --image=nginx --restart=Never -- bash -c "exit 250"
pod "exitcode" deleted
pod default/exitcode terminated (Error)
$ echo $?
250
$ kubectl run -it --rm exitcode --image=nginx --restart=Never -- bash -c "exit 255"
pod "exitcode" deleted
pod default/exitcode terminated (Error)
$ echo $?
255
$ kubectl run -it --rm exitcode --image=nginx --restart=Never -- bash -c "exit 256"
pod "exitcode" deleted
$ echo $?
0
# exit code can also be assigned to a variable
$ kubectl run -it --rm exitcode --image=nginx --restart=Never -- bash -c "exit 255" ; a=$? && echo $a
pod "exitcode" deleted
pod default/exitcode terminated (Error)
255
LoganMzz:的更新
$ kubectl run -it --rm --image=busybox --restart=Never foobar -- ash -c 'exit 10'; echo rc=$?
pod "foobar" deleted
pod default/foobar terminated (Error)
rc=10
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.5", GitCommit:"e6503f8d8f769ace2f338794c914a96fc335df0f", GitTreeState:"clean", BuildDate:"2020-06-26T03:47:41Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.5", GitCommit:"e6503f8d8f769ace2f338794c914a96fc335df0f", GitTreeState:"clean", BuildDate:"2020-06-26T03:39:24Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
10.10.0.21 Ready master 2d1h v1.18.5 10.10.0.21 <none> Ubuntu 16.04.6 LTS 4.4.0-184-generic docker://18.9.7
10.10.0.22 Ready <none> 2d1h v1.18.5 10.10.0.22 <none> Ubuntu 16.04.6 LTS 4.4.0-184-generic docker://18.9.7
我推荐@mark-wtney的答案中的jsonpath
方法,因为您不需要任何其他工具。但我将扩展到,如果您有多个容器,则需要添加一个过滤器。例如:
kubectl get pods pod-name -o jsonpath='{.status.containerStatuses[?(@.name=="container-name")].state.terminated.exitCode}'
kubectl get po pod_name -ojson | jq .status.containerStatuses[].state.terminated.exitCode
您可以将kubectl get
的输出通过管道传输到jq,jq可以解析json并打印退出代码,如果存在单个容器,则可以跳过-c container_name
。
kubectl get pod pod_name -c container_name-n namespace -ojson | jq .status.containerStatuses[].state.terminated.exitCode
我想在临时pod中运行一个命令,只是为了验证我的网络策略是否正确。然后,在容器内运行的命令的退出代码应该指示访问是被允许还是被拒绝。例如:
kubectl run --rm -it --image centos:7 --restart=Never xxx -- exit 1
kubectl get pod xxx -ojson | jq .status.containerStatuses[].state.terminated.exitCode
其中"exit 1"替换为实现我的检查的命令。
但是,当然,由于--rm用于运行容器,因此POD在命令之后不再存在,因此检索退出状态失败。唯一的解决方法是不使用--rm选项,然后清理临时pod。
另一种可能更好的选择是从命令中回显输出字符串,然后检查输出。该命令可以使用"陷阱"捕获任何出口并返回出口状态
trap 'echo EXITCODE $?; exit' EXIT
在上面,EXIT捕获任何出口,"出口"使用原始出口代码执行出口。
然后使用获取exitcode
code="$( kubectl ... | awk '/EXITCODE/ { print $2 }')"