我创建了一个连接到服务器、rpc 交换、登录和退出的 Go 客户端。在 kubernetes 中部署,我希望这会从“Running -> Completed -> Running
”循环中移动,类似于 dnsutils 的方式。使用“sleep 3600”命令部署运行一个小时并退出。
我将其简化为最小的 go 程序,以确保没有复杂性侵入,这是:
k8s-tester ➜ cat client.go
package main
func main() {
return
}
不过,当我这样做时,我实际上看到它经历了“
Running -> Completed -> CrashLoopBackOff -> Running
”状态。问:为什么当从 shell 运行时,kubernetes 将此程序视为崩溃,显示退出状态为 0 (EXIT_SUCCESS)?
k8s-tester ➜ kubectl create deployment --image kvaradha/client test-client deployment.apps/test-client created k8s-tester ➜ kubectl get pods -w -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-world-server-85486b969b-x744z 1/1 Running 0 10h 10.1.0.159 docker-desktop linux-544887f4fb-gksd8 1/1 Running 12 14h 10.1.0.156 docker-desktop postgres-57944b47cb-2cqtk 1/1 Running 0 13d 10.1.0.136 docker-desktop test-client-74cddbb988-rxx8f 0/1 Completed 1 4s 10.1.0.169 docker-desktop test-client-74cddbb988-rxx8f 0/1 CrashLoopBackOff 1 5s 10.1.0.169 docker-desktop test-client-74cddbb988-rxx8f 0/1 Completed 2 21s 10.1.0.169 docker-desktop test-client-74cddbb988-rxx8f 0/1 CrashLoopBackOff 2 33s 10.1.0.169 docker-desktop test-client-74cddbb988-rxx8f 0/1 Completed 3 50s 10.1.0.169 docker-desktop test-client-74cddbb988-rxx8f 0/1 CrashLoopBackOff 3 62s 10.1.0.169 docker-desktop
更多细节:
我使用的简单 Dockerfile:
FROM scratch
MAINTAINER "kannan@ieee.org"
ARG ARCH
COPY client /client
ENTRYPOINT [ "/client" ]
构建和部署为:
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o client .
docker build -t kvaradha/client .
kubectl create deployment --image kvaradha/client test-client
@sfrehse 建议的 docker 输出:
k8s-tester ➜ docker run --rm kvaradha/client
2020/02/28 21:33:17 hostname: 127.0.0.1:65432 name: H809430
k8s-tester ➜ echo $?
0
@CurtisMatton:描述 pods 让我明白:
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m2s default-scheduler Successfully assigned default/test-client-74cddbb988-jmxmd to docker-desktop Warning Failed 110s kubelet, docker-desktop Failed to pull image "kvaradha/client": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout Warning Failed 110s kubelet, docker-desktop Error: ErrImagePull Normal BackOff 109s kubelet, docker-desktop Back-off pulling image "kvaradha/client" Warning Failed 109s kubelet, docker-desktop Error: ImagePullBackOff Normal Pulling 55s (x4 over 2m1s) kubelet, docker-desktop Pulling image "kvaradha/client" Normal Created 54s (x3 over 2m) kubelet, docker-desktop Created container client Normal Pulled 54s (x3 over 2m) kubelet, docker-desktop Successfully pulled image "kvaradha/client" Normal Started 53s (x3 over 2m) kubelet, docker-desktop Started container client Warning BackOff 9s (x7 over 96s) kubelet, docker-desktop Back-off restarting failed container
用“FROM golang”构建了一个容器,最终结果相同:
test-client-bd4c475d4-cmnd6 1/1 Running 2 30s test-client-bd4c475d4-cmnd6 0/1 Completed 2 31s hello-world-client-77775898c-564lt 0/1 Completed 325 27h test-client-bd4c475d4-cmnd6 0/1 CrashLoopBackOff 2 44s hello-world-client-77775898c-564lt 0/1 CrashLoopBackOff 325 27h
最佳答案
这是预期的和预期的行为。 Kubernetes 的主要工作是确保给定的应用程序始终运行。如果应用程序退出(无论退出代码如何),Kubernetes(更具体地说是 kubelet
守护进程)将假定应用程序已崩溃并重新启动它。因此,您的应用程序应该是一个长时间运行的进程(即:服务器)。
如果您的应用程序只运行一次然后干净地退出,Kubernetes Job会比部署更合适。这样 pod 将运行完成而没有 CrashLoopBackOff
错误。
关于docker - 程序干净退出,但 kubernetes 处于 CrashLoopBackOff 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60456464/