my_init 解决胖容器僵尸进程清理问题
2019-06-15 本文已影响46人
AEGQ
背景:
虽然不建议,但总有需求把容器当成虚拟机来用,如果产生了僵尸进程,容器就很难正常删除,甚至会导致kubelet状态不稳定。
经测试 tini、dumb-init、pid1并不能容器中清理执行脚本产生的僵尸进程,my_init比较完美解决,容器可以正常删除。
示例:
一、单进程容器僵尸进程处理
使用 tini 作为1号进程处理子进程创建的僵尸进程
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
二、胖容器僵尸进程处理
使用 my_init 作为1号进程处理所有进程创建的僵尸进程
-
改造 alpine 镜像
FROM alpine:3.9
RUN apk --no-cache add runit curl python && \
ln -s /sbin/runsvdir /usr/bin/runsvdir && \
ln -s /sbin/sv /usr/bin/sv && \
curl -o /sbin/my_init https://raw.githubusercontent.com/AEGQ/tools/master/alpine/my_init && \
chmod +x /sbin/my_init
ENTRYPOINT ["/sbin/my_init","--skip-startup-files"]
-
改造 centos 镜像
FROM centos
RUN rpm -Uvh https://packagecloud.io/imeyer/runit/packages/el/7/runit-2.1.1-7.el7.centos.x86_64.rpm/download && \
yum install -y curl python python-pip && \
pip install argparse && \
curl -o /sbin/my_init https://raw.githubusercontent.com/AEGQ/tools/master/centos/my_init && \
ln -s -t /usr/bin /sbin/sv && \
ln -s -t /usr/bin /sbin/runsvdir && \
chmod +x /sbin/my_init
ENTRYPOINT ["/sbin/my_init","--skip-startup-files"]
-
改造 ubuntu 镜像
FROM ubuntu:18.04
RUN apt-get update && \
apt-get install -y curl runit python && \
curl -o /sbin/my_init https://raw.githubusercontent.com/AEGQ/tools/master/ubuntu/my_init && \
chmod +x /sbin/my_init
ENTRYPOINT ["/sbin/my_init","--skip-startup-files "]
-
使用官方base镜像(ubuntu)
FROM phusion/baseimage
# for test
#RUN apt-get update && apt-get install procps wget -y
#RUN wget https://github.com/AEGQ/tools/raw/master/zombie -O /zombie
#RUN chmod +x /zombie
ENTRYPOINT ["/sbin/my_init","--skip-startup-files "]
三、 测试
# 生成僵尸进程代码
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
if(!fork()){
if(fork()){
while(1){
sleep(5);
}
}
}
return 0;
}
# 安装 gcc
[alpine] # apk add libc-dev gcc
[centos] # yum install gcc
[ubuntu] # apt-get install gcc
# 编译
# gcc -o zombie main.c
# 生成僵尸进程
# watch -n 1 ./zombie
# for (( i=0; i < 500; i++ )); do ./zombie; done
# 测试容器在有或没有僵尸进程的情况下,是否能正常删除。