清除 Docker 容器终止

Cleanup on Docker container kill

我希望有一个多 docker 容器设置 运行 nodejs 和 socket.io。 我正在为一些共享 socketId/state 使用 redis。当我终止一个 nodejs 进程时,我执行了一个清理函数来删除与该进程相关的 sockeId/state。

process.stdin.resume();//so the program will not close instantly

function exitHandler(options, err) {

console.log('exitHandler');

_.forEach(global.sockets, (socket)=> {
    if (global.redisClient) {
        global.redisClient.hdel('socketA', socket);
        global.redisClient.hdel('socketB', socket);
        global.redisClient.del(`socketC_${socket}`);
    }
});

_.forEach(global.userIds, (userId)=> {
    if (global.redisClient) {
        global.redisClient.hdel('socketD', userId);
        global.redisClient.del(`socketE_${userId}`);
    }
});

if (options.cleanup) console.log('clean');
if (err) console.log(err.stack);
if (options.exit) process.exit();
}

//do something when app is closing
process.on('exit', exitHandler.bind(null, {cleanup: true}));

//catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {exit: true}));

//catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit: true}));

当节点不在容器中 运行 时,这很有效。当它在容器中并且我杀死容器时,不会执行清理。我想在我进行清理之前容器正在杀死所有通信管道。有想法该怎么解决这个吗 ?

您需要收听 SIGTERM。当你 运行 docker stop <container> 时,它会向容器发送一个 SIGTERM 并等待 10 秒。如果容器没有同时停止,它将向内核发送一个 SIGKILL 来完成容器。

推荐参考:Gracefully Stopping Docker container

因此,从容器内部,您应该监听 SIGTERM。从外部,你可以使用 docker API 检查你的容器是否被杀死并做正确的工作:Monitoring Docker Events