<p>I'm running a <code>Kubernetes</code> cluster with <code>minikube</code> and my deployment (or individual Pods) won't stay running even though I specify in the <code>Dockerfile</code> that it should stay leave a terminal open (I've also tried it with <code>sh</code>). They keep getting restarted and sometimes they get stuck on a <code>CrashLoopBackOff</code> status before restarting again:</p>

<pre><code>FROM ubuntu

EXPOSE 8080

CMD /bin/bash
</code></pre>

<p>My deployment file:</p>

<pre><code>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
</code></pre>

<p>All in all, my workflow follows (<code>deploy.sh</code>):</p>

<pre class="lang-sh prettyprint-override"><code>#!/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
</code></pre>

<p>By the way, I've tested the Docker Container solo using <code>sudo docker run -dt kubelab</code> and <em>it does stay up</em>. Why doesn't it stay up within <code>Kubernetes</code>? Is there a parameter (in the YAML file) or a flag I should be using for this special case?</p>

Philippe Fanaro
<h1>1. Original Answer (but edited...)</h1>

<p>If you are familiar with Docker, check <a href="https://kubernetes.io/docs/reference/kubectl/docker-cli-to-kubectl/" rel="nofollow noreferrer">this</a>.</p>

<p>If you are looking for an equivalent of <code>docker run -dt kubelab</code>, try <code>kubectl run -it kubelab --restart=Never --image=ubuntu /bin/bash</code>. In your case, with the Docker <code>-t</code> flag: <a href="https://docs.docker.com/engine/reference/run/" rel="nofollow noreferrer">Allocate a pseudo-tty</a>. That's why your Docker Container stays up.</p>

<p>Try:</p>

<pre class="lang-sh prettyprint-override"><code>kubectl run kubelab \
    --image=ubuntu \
    --expose \
    --port 8080 \
    -- /bin/bash -c 'while true;do sleep 3600;done'
</code></pre>

<p>Or:</p>

<pre class="lang-sh prettyprint-override"><code>kubectl run kubelab \
    --image=ubuntu \
    --dry-run -oyaml \
    --expose \
    --port 8080 \
    -- /bin/bash -c 'while true;do sleep 3600;done'
</code></pre>

<h1>2. Explaining what's going on (Added by Philippe Fanaro):</h1>

<p>As stated by @David Maze, the <code>bash</code> process is going to exit immediately because the artificial terminal won't have anything going into it, a slightly different behavior from Docker.</p>

<p>If you change the <code>restart</code> Policy, it will still terminate, the difference is that the Pod won't regenerate or restart.</p>

<p>One way of doing it is (pay attention to the tabs of <code>restartPolicy</code>):</p>

<pre><code>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
</code></pre>

<p>However, this will <strong>not</strong> work if it is specified inside a <code>deployment</code> YAML. And that's because deployments force regeneration, trying to always get to the <em>desired state</em>. This can be confirmed in the <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/" rel="nofollow noreferrer">Deployment Documentation Webpage</a>:</p>

<blockquote>
  <p>Only a <a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy" rel="nofollow noreferrer"><code>.spec.template.spec.restartPolicy</code></a> equal to <code>Always</code> is allowed, which is the default if not specified.</p>
</blockquote>

<h1>3. If you really wish to force the Docker Container to Keep Running</h1>

<p>In this case, you will need something that doesn't exit. A <em>server-like process</em> is one example. But you can also try something mentioned in <a href="https://stackoverflow.com/a/35770783/4756173">this StackOverflow answer</a>:</p>

<pre><code>CMD exec /bin/bash -c "trap : TERM INT; sleep infinity &amp; wait"
</code></pre>

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