群健康检查将任务设置为完成状态

时间:2019-08-17 09:04:04

标签: node.js docker swarm

A已经创建了一个集群并在其上运行一个简单的nodejs应用程序。我希望测试运行状况检查在群体环境中的工作方式。我已经将healthcheck块设置为像这样的撰写文件:

 healthcheck:
        test:  ["CMD", "curl", "-f", "http://localhost:3000/healthcheck"]
        interval: 1m
        timeout: 10s
        retries: 1
        start_period: 20s

nodejs源很简单:

const express = require("express");
const os = require("os");

var fs = require('fs');
const app=express();
let health = "ok";

app.get("/", (req, res) => {
    var hostname = fs.readFileSync('/host/etc/hostname', 'utf8');

    var body =    " Hello from SwarmDemo (V1.0)" + "<br>";
    body = body + " container name: " + os.hostname()+ "<br>";
    body = body + " host name: " + hostname;

    res.send(body);
});

app.get("/healthcheck", (req, res) => {
    if (health == "ok") {
        res.send("OK")
    } else {
        res.status(503);
        res.send("");
    }
});

app.get("/kill", (req, res) => {
    var hostname = fs.readFileSync('/host/etc/hostname', 'utf8');

    health = "killed";
    res.send("Host " + hostname + " was killed!")
});

app.listen(3000, () => {
    console.log("Server is running on port 3000");
});

我期望蜂群停止不健康的容器并启动一个新容器,但事实并非如此。它会停止容器,但只会将任务状态设置为完成并离开它,而不会启动新的状态。

如果我检查已停止的容器,则表示exitCode为0,这意味着,据我所知,它已成功停止,但不是因为失败。我可以看到healthchek调用,该调用也返回了503 HTTP响应代码:

        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2019-08-16T17:33:55.778937745Z",
            "FinishedAt": "2019-08-16T17:35:59.664281868Z",
            "Health": {
                "Status": "unhealthy",
                "FailingStreak": 1,
                "Log": [
                    {
                        "Start": "2019-08-16T19:34:55.779656075+02:00",
                        "End": "2019-08-16T19:34:56.648373763+02:00",
                        "ExitCode": 0,
                        "Output": "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r100     2  100     2    0     0     22      0 --:--:-- --:--:-- --:--:--    22\nOK"
                    },
                    {
                        "Start": "2019-08-16T19:35:56.658734507+02:00",
                        "End": "2019-08-16T19:35:57.549464299+02:00",
                        "ExitCode": 22,
                        "Output": "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\ncurl: (22) The requested URL returned error: 503 Service Unavailable\n"
                    }
                ]
            }
        },

如果我将重启策略从失败修改为任何:

            restart_policy:
                condition: any
                delay: 5s
                max_attempts: 3
                window: 30s

有效。它停止contaier并开始新的。

我的问题是:当运行状况检查失败时,如何强制群集启动新的容器。我应该发送其他信息,然后发送5xx HTTP响应代码吗?

我看过一些文章,其中HTTP调用包装在脚本中。如果HTTP调用返回了200,则返回1,否则返回0。

这是唯一的解决方案吗?

1 个答案:

答案 0 :(得分:0)

似乎,如果docker毫无问题地停止了容器,则状态将是完整的。这意味着,在这种情况下,它并不关心健康状况。

如果我使用kill方法停止节点进程:

app.get("/kill", (req, res) => {
 process.exit(1);
});

或在健康检查中:

app.get("/healthcheck", (req, res) => {
    if (health == "ok") {
        res.send("OK")
    } else {
        process.exit(1);
    }
});

有效。状态将失败。