[kubernetes] Restart container within pod

I have a pod test-1495806908-xn5jn with 2 containers. I'd like to restart one of them called container-test. Is it possible to restart a single container within a pod and how? If not, how do I restart the pod?

The pod was created using a deployment.yaml with:

kubectl create -f deployment.yaml

This question is related to kubernetes kubectl

The answer is


There are cases when you want to restart a specific container instead of deleting the pod and letting Kubernetes recreate it.

Doing a kubectl exec POD_NAME -c CONTAINER_NAME /sbin/killall5 worked for me.

(I changed the command from reboot to /sbin/killall5 based on the below recommendations.)


There was an issue in coredns pod, I deleted such pod by

kubectl delete pod -n=kube-system coredns-fb8b8dccf-8ggcf

Its pod will restart automatically.


We use a pretty convenient command line to force re-deployment of fresh images on integration pod.
We noticed that our alpine containers all run their "sustaining" command on PID 5. Therefore, sending it a SIGTERM signal takes the container down. imagePullPolicy being set to Always has the kubelet re-pull the latest image when it brings the container back.

kubectl exec -i [pod name] -c [container-name] -- kill -15 5

Killing the process specified in the Dockerfile's CMD / ENTRYPOINT works for me. (The container restarts automatically)

Rebooting was not allowed in my container, so I had to use this workaround.


The whole reason for having kubernetes is so it manages the containers for you so you don't have to care so much about the lifecyle of the containers in the pod.

Since you have a deployment setup that uses replica set. You can delete the pod using kubectl delete pod test-1495806908-xn5jn and kubernetes will manage the creation of a new pod with the 2 containers without any downtime. Trying to manually restart single containers in pods negates the whole benefits of kubernetes.


kubectl exec -it POD_NAME -c CONTAINER_NAME bash - then kill 1

Assuming the container is run as root which is not recommended.

In my case when I changed the application config, I had to reboot the container which was used in a sidecar pattern, I would kill the PID for the spring boot application which is owned by the docker user.


Both pod and container are ephemeral, try to use the following command to stop the specific container and the k8s cluster will restart a new container.

kubectl exec -it [POD_NAME] -c [CONTAINER_NAME] -- /bin/sh -c "kill 1"

This will send a SIGTERM signal to process 1, which is the main process running in the container. All other processes will be children of process 1, and will be terminated after process 1 exits. See the kill manpage for other signals you can send.


All the above answers have mentioned deleting the pod...but if you have many pods of the same service then it would be tedious to delete each one of them...

Therefore, I propose the following solution, restart:

  • 1) Set scale to zero :

     kubectl scale deployment <<name>> --replicas=0 -n service 
    

    The above command will terminate all your pods with the name <<name>>

  • 2) To start the pod again, set the replicas to more than 0

    kubectl scale deployment <<name>> --replicas=2 -n service
    

    The above command will start your pods again with 2 replicas.


I was playing around with ways to restart a container. What I found for me was this solution:

Dockerfile:

...
ENTRYPOINT [ "/app/bootstrap.sh" ]

/app/bootstrap.sh:

#!/bin/bash
/app/startWhatEverYouActuallyWantToStart.sh &
tail -f /dev/null

Whenever I want to restart the container, I kill the process with tail -f /dev/null which I find with

kill -TERM `ps --ppid 1 | grep tail | grep -v -e grep | awk '{print $1}'`

Following that command, all the processes except for the one with PID==1 will be killed and the entrypoint, in my case bootstrap.sh will be executed (again).

That's for the part "restart" - which is not really a restart but it does what you wish, in the end. For the part with limiting restarting the container named container-test you could pass on the container name to the container in question (as the container name would otherwise not be available inside the container) and then you can decide whether to do the above kill. That would be something like this in your deployment.yaml:

    env:
    - name: YOUR_CONTAINER_NAME
      value: container-test

/app/startWhatEverYouActuallyWantToStart.sh:

#!/bin/bash
...
CONDITION_TO_RESTART=0
...
if [ "$YOUR_CONTAINER_NAME" == "container-test" -a $CONDITION_TO_RESTART -eq 1 ]; then
    kill -TERM `ps --ppid 1 | grep tail | grep -v -e grep | awk '{print $1}'`
fi