需求调研
在日常服务运维过程中,难免需要一些监控工具代替人工完成各种机械的工作。
当前需要实现一个Stack下的Service所有任务状态监控的工具,它主要负责:定期检查Stack下的Service的replica服务是否都在正常运行。通俗点理解就是,比方Stack下ServiceA(设置了4个副本数)和ServiceB(设置了2个副本数),定时检查这6(4+2)个副本任务都运行正常。当存在异常replica服务的时候,推送报警邮件。
实现方案
- 技术选型:Python3 Request,简单脚本,使用Python实现方便些。
- 实现思路:调用Portainer API 的接口http://192.168.2.100:9000/api/endpoints/1/docker/tasks?filters={"label":["com.docker.stack.namespace=stack-name"]}, 获取Stack任务列表,遍历所有任务,检查服务容器状态。(注:1 是swarm id)
实现代码
废话不多说,直接上代码
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
本文实现思路纯属个人思路,如有不对的对方,感谢指出!!!