在Pod内重启容器

203

我有一个名为 test-1495806908-xn5jn 的Pod,其中包含2个容器。 我想重新启动其中一个名为 container-test 的容器。 是否可以重新启动Pod中的单个容器? 如果不行,那么如何重新启动Pod?

该Pod是使用deployment.yaml创建的:

kubectl create -f deployment.yaml
16个回答

1
在Dockerfile中指定的CMD / ENTRYPOINT进程终止对我有用。(容器会自动重新启动)
由于我的容器不允许重新启动,所以我不得不使用这个解决方法。

1
正确但可能不太流行的答案是,如果您需要重新启动 Pod 中的一个容器,则该容器不应该在同一个 Pod 中。按设计,您无法单独重启 Pod 中的单个容器。只需将容器移动到自己的 Pod 中即可。来自文档:
“运行单个容器的 Pod。'每个 Pod 一个容器'模型是 Kubernetes 最常见的用例;在这种情况下,您可以将 Pod 视为围绕单个容器的包装器;Kubernetes 管理 Pod 而不是直接管理容器。
注意:将多个共存和共同管理的容器分组到单个 Pod 中是相对高级的用例。您应该仅在容器紧密耦合的特定情况下使用此模式。”

https://kubernetes.io/docs/concepts/workloads/pods/


1
重新启动单个容器是完全可能的,但具体方法可能因集群配置而异。一般来说,您需要满足以下两个条件:
- 将Pod设置为restartPolicy: Always(对于大多数工作负载来说,默认设置即可) - 使主容器进程停止而不删除Pod。这是有趣的部分。
请记住,容器只是一个小的隔离环境(命名空间),用于承载某个进程(以及网络、文件系统等)在某个人的(通常是相对通用的)Linux服务器上(在Kubernetes术语中称为node)。这意味着:
  • 如果您是在容器运行的节点上的root用户,您可以制造一些混乱,我想我不需要进行描述,对吧?但大多数情况下您不是。这是一件好事。
  • 如果容器有一个shell,并且您可以使用kubectl exec命令进入它
    kubectl exec -it $POD -c $CONTAINER -- sh -c 'kill 1'
    
    这将向进程1发送一个TERM信号,之后大多数行为良好的进程会相对优雅地退出。进程1通常是容器的主进程(或者有时不是),在其退出后,容器将被销毁并由kubelet接管重新启动。如果进程很顽固,您可以尝试kill -9 1,这应该彻底杀死它,但效果可能因情况而异。
  • 如果容器是"distroless"(即没有shell),您无法使用上述技巧,但如果您的集群版本至少为1.25(甚至可能更旧),有一种方法
    kubectl debug -it --image=busybox $POD --target=$CONTAINER -- sh -c 'kill 1'
    
    这将在Pod中创建一个新的"临时容器",该容器几乎与--target容器处于相同的环境中。这使您能够查看目标进程并将其终止,使用的工具是提供的--image中的工具。我使用了busybox,因为它很小而且能够完成工作,但您当然可以使用任何更大的镜像,如ubuntu

0
我正在尝试重新启动容器的各种方式。对我来说,我找到的解决方案是这个:

Dockerfile:

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

/app/bootstrap.sh:

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


每当我想重新启动容器时,我会使用tail -f /dev/null命令来终止进程。这个命令可以帮助我找到需要终止的进程。
kill -TERM `ps --ppid 1 | grep tail | grep -v -e grep | awk '{print $1}'`

在执行该命令后,除了 PID==1 的进程外,所有其他进程都将被终止,并且入口点(在我的情况下是 bootstrap.sh)将被再次执行。

这就是“重启”部分的作用 - 实际上并不是真正的重启,但最终会达到你的目的。对于限制重启名为 container-test 的容器的部分,你可以将容器名称传递给相关容器(因为容器名称在容器内部是不可用的),然后你可以决定是否执行上述的 kill 操作。 在你的 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

-1
有时候我们不知道 pod 使用的是哪个操作系统,可能没有 sudo 或者 reboot 命令。
更安全的选择是创建一个快照并重新创建 pod。
kubectl get <pod-name> -o yaml > pod-to-be-restarted.yaml; 
kubectl delete po <pod-name>; 
kubectl create -f pod-to-be-restarted.yaml

-1
kubectl delete pods POD_NAME

这个命令将会自动删除该Pod并重新启动另一个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接