测试重启策略-如何使容器崩溃以使其重启

时间:2019-01-31 12:23:16

标签: docker docker-compose

我有一个docker-compose文件,该文件创建了3个Hello World应用程序,并使用nginx负载均衡了不同容器之间的流量。

docker-compose代码如下:

version: '3.2'
services:
  backend1:
      image: rafaelmarques7/hello-node:latest
      restart: always
  backend2:
      image: rafaelmarques7/hello-node:latest
      restart: always
  backend3:
      image: rafaelmarques7/hello-node:latest
      restart: always
  loadbalancer:
      image: nginx:latest      
      restart: always
      links:
          - backend1
          - backend2
          - backend3
      ports:
        - '80:80'
      volumes: 
        - ./container-balancer/nginx.conf:/etc/nginx/nginx.conf:ro

我想验证restart: always策略是否确实有效。

我尝试的方法如下:

  • 首先,我使用docker-compose up运行我的应用程序;
  • 我用docker container ps标识容器ID;
  • 我使用docker stop ID_Containerdocker kill ID_Container杀死/停止了其中一个容器。

我期望第三步(停止/杀死容器。这使它在代码137中存在)之后,重新启动策略将启动并再次创建一个新容器。

但是,这不会发生。我已经读到这是有意的,因为它可以手动停止具有重启策略的容器。

尽管如此,我想知道我如何以一种触发重新启动策略的方式来杀死容器,以便我可以实际验证其是否正常工作。

谢谢您的帮助。

2 个答案:

答案 0 :(得分:3)

如果您在主机上运行ps,您将能够看到所有Docker容器中的实际进程。一旦找到容器的主进程的进程ID,就可以sudo kill(必须是root)。这看起来更像是一场“崩溃”,尤其是如果您kill -13发送SIGSEGV。

对于这样的验证场景,偶尔有一个端点使您的应用程序崩溃,您可以在测试版本和其他一些类似的愚蠢的事情中启用它很有用。只需确保您有一个门,以使这些端点在生产版本中不存在。 (在老式C语言中,#ifdef TEST可以胜任;某些语言具有对等的语言,但许多语言没有。)

答案 1 :(得分:3)

您可以docker exec进入正在运行的容器并杀死进程。如果您的入口点进程(pid 1)启动了子进程,请找到它并杀死它

docker exec -it backend3 /bin/sh
ps -ef

查找进程pid 1是其父级,并kill -9为其父级。

如果您的入口点是唯一进程(pid 1),则无法用kill命令将其杀死。考虑用调用实际过程的脚本替换入口点,这将使您能够使用我上面建议的想法。

这应该模拟崩溃的容器,并应该启动重新启动过程。

注意:

  1. 请参阅https://unix.stackexchange.com/questions/457649/unable-to-kill-process-with-pid-1-in-docker-container
  2. 中的说明
  3. 看看为什么不以https://www.elastic.io/nodejs-as-pid-1-under-docker-images/中的pid 1的身份运行NodeJS