自定义实现Stack任务状态监控

73 阅读2分钟

需求调研

在日常服务运维过程中,难免需要一些监控工具代替人工完成各种机械的工作。

当前需要实现一个Stack下的Service所有任务状态监控的工具,它主要负责:定期检查Stack下的Service的replica服务是否都在正常运行。通俗点理解就是,比方Stack下ServiceA(设置了4个副本数)和ServiceB(设置了2个副本数),定时检查这6(4+2)个副本任务都运行正常。当存在异常replica服务的时候,推送报警邮件。

实现方案

实现代码

废话不多说,直接上代码

import urllib.request
import logging
import json
import sys
import time
import os
import requests

def check_stack_task(stack):
    try:
        get_task_list_url = "http://192.168.2.100:9000/api/endpoints/1/docker/tasks?filters=%7B%22label%22:%5B%22com.docker.stack.namespace%3D{}%22%5D%7D&X-API-Key=XXXXX"
        get_task_list_resp = urllib.request.urlopen(get_task_list_url.format(stack))
        get_task_list_resp_json = json.loads(get_task_list_resp.read())
        """
            for get_task_list_resp_json
                if DesiredState == running :应该启动的副本,个数之和等于副本数
                    if Status.State == running :启动成功的副本
                    else 未启动成功的副本,error_message = Status.Err
                else 忽略
        """
        replica = 0
        SUCCESS = 0
        FAIL = 0
        error_message = ''
        for task in get_task_list_resp_json:
            if task.get('DesiredState') == 'running':
                replica += 1
                Status = task.get('Status')
                State = Status.get('State')
                if State == 'running':
                    SUCCESS += 1
                else :
                    FAIL += 1
                    error_message += ('<' + State + '>' + str(Status.get('Err')))
        if SUCCESS == replica:
            push_message(stack,'SUCCESS','',replica,SUCCESS)
        if FAIL > 0:
            push_message(stack,'FAIL',error_message,replica,SUCCESS)
    except Exception as e:
            print(e)
    
def push_message(stack,status,error_message,replica,SUCCESS):

    msg="「Stack Status」"+ status +"\nstack:"+stack + "\nreplicas:" + str(SUCCESS) + "/" +  str(replica)  +(' √' if status == 'SUCCESS' else ' ✕' ) + "\ntime:"+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+  ( '' if status == 'SUCCESS'  else ("\nerror:" + error_message))
    print(msg)
    """
    推送邮箱
    """
if __name__=="__main__":
    """
    入参:stack名称
    """
    stack = sys.argv[1]
    check_stack_task(stack)

注意:在调用Portainer API 的时候需要先在控制台中获取一个Access token。

执行脚本,测试效果>>>>

docker>python check_stack.py stack-service-a
「Docker Deploy」SUCCESS
stack:stack-service-a
replicas:1/1 √
time:2022-07-25 20:18:09

docker>python check_stack.py stack-service-b
「Stack Status」FAIL
stack:stack-service-b
replicas:1/2 ✕
time:2022-07-25 20:21:34
error:<pending>no suitable node (scheduling constraints not satisfied on 8 nodes; max replicas per node limit exceed)

定时任务

# 进入任务编辑
crontab -e
# 添加定时任务,每隔5分钟 执行 "python /app/check_stack.py" 命令
0 0/5 * * * ? python /app/check_stack.py  >>/app/logs/check.log 2>&1

本文实现思路纯属个人思路,如有不对的对方,感谢指出!!!