docker - 程序干净退出,但 kubernetes 处于 CrashLoopBackOff 中

标签 docker go kubernetes

我创建了一个连接到服务器、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/

相关文章:

docker - 为什么只有 `expose` 配置的服务能够与互联网通信?

docker - 如何将受信任的根 CA 添加到 Docker alpine

struct - 无法在golang中包含多个文件

kubernetes - 如果 kubernetes 服务失败会发生什么?

kubernetes - Apache Airflow 或 Argoproj 用于在 kubernetes 上长时间运行和 DAG 任务

windows - 在 Windows 上使用 VirtualBox 为 Kubernetes 创建 Docker 容器

node.js - 使用 docker-sync 时合并容器文件

oracle - 如何在 docker 容器内的 Oracle 数据库上使用 sqlldr?

go - 如何保持与 golang 的登录 session 以进行抓取?

go - 在 Web 应用程序中运行计划任务