Pod 卡在 `CrashLoopBackOff` 上,即使它应该进入 /bin/bash

Pod Stuck on `CrashLoopBackOff` even though it should go into /bin/bash

我是 运行 一个带有 minikubeKubernetes 集群,我的部署(或个人 Pods)不会留在 运行 即使我在 Dockerfile 中指定它应该保持打开终端(我也用 sh 尝试过)。他们不断重启,有时在再次重启前卡在 CrashLoopBackOff 状态:

FROM ubuntu

EXPOSE 8080

CMD /bin/bash

我的部署文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sleeper-deploy
spec:
  replicas: 10
  selector:
    matchLabels:
      app: sleeper-world
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: sleeper-world
    spec:
      containers:
      - name: sleeper-pod
        image: kubelab
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

总而言之,我的工作流程如下 (deploy.sh):

#!/bin/bash

# Cleaning

kubectl delete deployments --all
kubectl delete pods --all

# Building the Image

sudo docker build \
    -t kubelab \
    .

# Deploying

kubectl apply -f sleeper_deployment.yml

顺便说一句,我已经使用 sudo docker run -dt kubelab 单独测试了 Docker 容器,它确实保持了 。为什么它不保持在 Kubernetes 内?对于这种特殊情况,我应该使用参数(在 YAML 文件中)还是标志?

1。原始答案(但经过编辑...)

如果您熟悉 Docker,请检查 this

如果您正在寻找 docker run -dt kubelab 的等效项,请尝试 kubectl run -it kubelab --restart=Never --image=ubuntu /bin/bash。在您的情况下,使用 Docker -t 标志:Allocate a pseudo-tty。这就是您的 Docker 容器保持运行的原因。

尝试:

kubectl run kubelab \
    --image=ubuntu \
    --expose \
    --port 8080 \
    -- /bin/bash -c 'while true;do sleep 3600;done'

或者:

kubectl run kubelab \
    --image=ubuntu \
    --dry-run -oyaml \
    --expose \
    --port 8080 \
    -- /bin/bash -c 'while true;do sleep 3600;done'

2。解释发生了什么(由 Philippe Fanaro 添加):

如@David Maze 所述,bash 进程将立即退出,因为人工终端不会有任何内容进入其中,这与 Docker 的行为略有不同。

如果您更改 restart 策略,它仍然会终止,区别在于 Pod 不会重新生成或重启。

一种方法是(注意 restartPolicy 的选项卡):

apiVersion: v1
kind: Pod
metadata:
  name: kubelab-pod
  labels:
    zone: prod
    version: v1
spec:
  containers:
  - name: kubelab-ctr
    image: kubelab
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 8080
  restartPolicy: Never

但是,如果在 deployment YAML 中指定,这将 无效 。那是因为部署强制重新生成,试图始终达到 期望状态 。这可以在 Deployment Documentation Webpage:

中确认

Only a .spec.template.spec.restartPolicy equal to Always is allowed, which is the default if not specified.

3。如果你真的想强制 Docker 容器保留 运行

在这种情况下,您将需要一些不会退出的东西。 类似服务器的进程 就是一个例子。但您也可以尝试 :

中提到的内容
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

This will keep your container alive until it is told to stop. Using trap and wait will make your container react immediately to a stop request. Without trap/wait stopping will take a few seconds.