前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官:能在容器里面通过 kill -9 杀死容器吗?问倒一大片。。。

面试官:能在容器里面通过 kill -9 杀死容器吗?问倒一大片。。。

作者头像
民工哥
发布2023-12-12 14:48:18
2700
发布2023-12-12 14:48:18
举报

我们都知道,想要在 Linux 中终止一个进程有两种方式。

  • 如果是前台进程可以使用 Ctrl+C 键进行终止。
  • 如果是后台进程,那么需要使用 kill 命令来终止(其实 Ctrl+C 也是kill命令)。

kill命令默认将信号(signal)15发给进程,让进程优雅地退出,释放资源。而kill -9则是强制终止进程,相当于发送信号9,不管进程是否想要退出,都会被迫停止运行。

下面是kill命令的基本语法:

代码语言:javascript
复制
kill [-s signal | -signal] pid

其中,signal 可以是信号的名称或数字,也可以使用-号对信号进行取反(例如,-9 表示强制终止进程)。pid是进程的PID号。

强制终止进程可能会导致进程意外终止,因此需要谨慎使用,kill -9还可以用于终止僵尸进程。

上面我了解了关于 Kill 命令的具体使用方法以及注意事项。

前几天有读者私聊问我,他遇到一个相关的面试题,面试官问他:能否在容器里使用 Kill -9 命令杀死容器?一下给他直接问懵逼了。

下面我们就来一起探讨一下这个经典的面试题。

我们都知道,容器里面第一个进程的PID为 1,那么当我们进入容器后,能否通过。

代码语言:javascript
复制
# kill -9 1

的方式杀死自己吗 ?

答案是不能。为什么呢?看下面。

SIGKILL(-9)信号有两个特殊的地方

  • 1、除了PID为1的进程以外,其他进程不能忽略这个信号。
  • 2、不允许捕获,注册handler。这个其实很容易理解,SIGKILL的目的是强制杀死进程,如果进程自己捕获处理后,并没有执行exit退出,那么就永远无法杀死了。而PID为1 的进程,通常称为init进程,是忽略SIGKILL信号的,所以无法在容器的PID Namespace里面杀死的。

细心的你可能已经发现了,我说的是无法在容器内的PID Namespace里面杀死。那么,容器外呢?当然可以,docker kill 命令就是在容器外通过发送SIGKILL杀死容器的,因为在宿主机上,这个init进程的ID已经不再是 1 了。

那我们可以在容器内部通过信号杀死自己吗?还是回到上面说的,SIGKILL信号不能被捕获,但其他信号可以啊。譬如 SIGQUIT、SIGTERM。下面是一个捕获SIGQUIT的Demo。

代码语言:javascript
复制
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

void handler(int sig)
{
 exit(sig);
}

int main(int argc, char *argv[])
{
 int duration;
 if (argc > 1)
 {
  duration = atoi(argv[1]);
  printf("Sleeping for %ds\n", duration);
  sleep(duration);
  exit(EXIT_SUCCESS);
 }
 if(signal(SIGQUIT, handler) == SIG_ERR)
  exit(EXIT_FAILURE);

 for (;;)
  pause();
}

执行代码编译(gcc -Wall a.c -o a.o && ./a.o) 后通过Dockerfile打到镜像里面,启动进入容器便可以通过 ”kill -3 “杀死容器,优雅退出了。如下所示。

代码语言:javascript
复制
[root@test ~]# docker exec -it cd1c839a758d  sh
sh-4.4#
sh-4.4# kill -9 1
sh-4.4#
sh-4.4# kill -3 1
sh-4.4# [root@test ~]#

上面也顺便演示了在容器里面通过”kill -9 “ 是无法杀死容器的。

所以,在进入容器后,想要在容器内停止容器可以使用以下命令:

代码语言:javascript
复制
docker stop <container_id>

其中,<container_id> 是要停止的容器的 ID。可以通过 docker ps 命令来获取当前正在运行的容器列表及其 ID。执行上述命令后,Docker 会向容器发送一个 SIGTERM 信号,请求它优雅地停止。如果容器在一定时间内没有响应,Docker 将会强制终止该容器。

另外,也可以使用以下命令来直接强制停止容器:

代码语言:javascript
复制
docker kill <container_id>

这个命令会向容器发送一个SIGKILL信号,直接杀死该进程并终止容器。

所以,docker kill 才是 kill 容器的终极武器

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 民工哥技术之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档