k8s中shell脚本启动如何传递信号

背景

在k8s或docker中,有时候我们需要通过shell来启动程序,但是默认shell不会传递信号(sigterm)给子进程,当在pod终止时应用无法优雅退出,直到最大时间时间后强制退出(kill -9)。

分析

普通情况下,大多业务的启动命令如下

command: ["binary", "-flags", ...]

主进程做为1号进程会收到sigterm信号,优雅退出(需要程序捕获信号); 而通过脚本启动时,shell作为1号进程,不会显示传递信号给子进程,造成子进程无法优雅退出,直到最大退出时间后强制终止。

解决方案

exec

如果只需一个进程收到信号,可通过exec命令,exec会替换当前shell进程,即pid不变

#! /bin/bash
# do something
exec binay -flags ...

正常情况测试命令如下,使用sleep来模拟应用sh -c 'echo "start"; sleep 100'
pstree展示如下,sleep进程会生成一个子进程

bash(28701)───sh(24588)───sleep(24589)

通过exec运行后,命令sh -c 'echo "start"; exec sleep 100'

bash(28701)───sleep(24664)

加入exec后,sleep进程替换了shell进程,没有生成子进程

此种方式可以收到信号,但只适用于一个子进程的情况

trap

在shell中可以显示通过trap捕捉信号传递给子进程

#!/bin/bash
echo "start"
binary -flags... &
pid="$!"

_kill() {
  echo "receive sigterm"
  kill $pid #传递给子进程
  wait $pid
  exit 0
}

trap _kill SIGTERM #捕获信号
wait #等待子进程退出

此种方式需要改动启动脚本,显示传递信号给子进程

docker-init

docker-init即在docker启动时加入--init参数,docker-int会作为一号进程,会向子进程传递信号并且会回收僵尸进程。

遗憾的是k8s并不支持--init参数,用户可在镜像中声明init进程,更多可参考container-init

RUN wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64
RUN chmod +x /usr/bin/dumb-init
ENTRYPOINT ["/usr/bin/dumb-init", "-v", "--"]

CMD ["nginx", "-g", "daemon off;"]
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是一个快速部署 KubernetesShell 脚本示例: ``` #!/bin/bash # 安装 Docker apt-get update apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" apt-get update apt-get install -y docker-ce docker-ce-cli containerd.io # 安装 kubeadm, kubelet 和 kubectl curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb https://apt.kubernetes.io/ kubernetes-xenial main EOF apt-get update apt-get install -y kubelet kubeadm kubectl # 部署 Kubernetes kubeadm init # 配置 kubectl mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config # 部署网络插件 kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml # 输出 join 命令以便其他节点加入 kubeadm token create --print-join-command ``` 此脚本将自动安装 DockerKubernetes 组件,初始化 Kubernetes 集群,配置 kubectl 并部署 Calico 网络插件。运行脚本后,它还将输出 join 命令,以便其他节点可以加入集群。请注意,此脚本可能需要以管理员权限运行,并且需要一些必要的前提条件(例如正确的网络设置)。因此,在使用此脚本之前,请仔细阅读相关文档以确保安全和正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值