查看原文
其他

CI/CD支撑运维自动化:系统监控级原子模块

三页 木讷大叔爱运维 2022-07-13

圣诞节快乐





读完需 8 分钟

速读需 4 分钟 



简述

《CI/CD如何支撑运维自动化》讲述了借助Jenkins 通过CI/CD的方式来实现运维自动化的想法,并规划了以下几个原子模块:

  • 操作系统级

  • Java应用级

  • Apollo配置中心级

  • 监控系统级

  • CMDB级

通过pipeline对以上原子模块进行编排来满足不同场景的需求。为让大家更深入的理解,下面来介绍下系统监控级原子模块的应用。


本文涉及功能在运维自动化所处的位置如图:


监控场景

对于系统应用的监控,我们一般多采用URL监控或端口监控,这是两种完全不同的方式。端口监控无法在应用假死的情况下进行告警,因此建议以URL监控为主、端口监控为辅的方式来满足监控需求。


另为了URL监控和端口监控的统一管理,因此我们使用集中监控主机10.10.10.250,在Zabbix监控场景下我们统一通过10.10.10.250自动发现URL及端口。


1.URL监控

# 1.站点文件vim  http_site.conf#格式:APP_NAME|MONITOR_URL#标准urlTEST1|10.10.10.1:8080#非标准urlTEST2|10.10.10.1:8080/XXXXX
# 2.站点监控脚本# vim url_check.py#!/usr/bin/env python#comment:#1.兼容http_site文件中标准及非标url#2. 正常状态码返回200;超时返回10000import pycurlimport jsonimport sysimport osimport StringIO
mulu = '/App/scripts/zabbix'website = os.path.join(mulu, 'http_site.txt')

def website_discovery(): sitelist = [] with open(website, 'r') as url: for line in url: line=line.strip('\n')       line=line.split('|')       if len(line) == 2:         service = line[0] link = line[1] else:         link = line + "format error"         site = {}        site['{#LINK}'] = link       site['{#SERVICE}'] = service sitelist.append(site) #json序列化 discovery_site_info = {"data":sitelist} print json.dumps(discovery_site_info, sort_keys=True, indent=4, separators=(',', ':'))

def website_response_code(): if len(sys.argv) == 3: try: link=sys.argv[2]            num=link.split('/')            if len(num) > 1:                url="http://" + link            else:                url="http://" + link + "/monitor"            c=pycurl.Curl() b=StringIO.StringIO() c.setopt(pycurl.WRITEFUNCTION, b.write) c.setopt(pycurl.FOLLOWLOCATION, 0) c.setopt(pycurl.URL, url)            #c.setopt(pycurl.PROXY, proxy) #c.setopt(pycurl.CUSTOMREQUEST, "GET") #c.setopt(pycurl.POSTFIELDS, query) c.setopt(pycurl.CONNECTTIMEOUT, 50) c.setopt(pycurl.TIMEOUT, 50) c.perform() except Exception: print "1000" else: status=c.getinfo(c.HTTP_CODE) b.close() c.close() print status else: print "Usage: python http_response_code_status.py website_response_code website or proxy"
if __name__ == '__main__':
if sys.argv[1] == 'website_discovery': website_discovery() elif sys.argv[1] == 'website_response_code': website_response_code() else:    print "Usage: python http_response_code_status.py [website_discovery]|[website_response_code website]"


通过脚本我们做出的规划是

  • 标准化监控URL为10.10.10.1:8080/monitor

  • 非标准化监控URL为10.10.10.2:8080/XXXX


我们希望监控脚本可以兼容未标准化的老应用,也能够接入标准化的新应用。当状态码返回非200时,能够通过APP_NAME 及 IP:PORT 直接区分关联应用: 

告警内容为:# 标准应用50s超时TEST1|10.10.10.1:8080 状态码为1000# 非标准应用返回为502TEST2|10.10.10.2:8080/XXXXX 状态码为502


2.端口监控

# 1.端口文件vim  port.conf#格式:APP_NAME|IP:PORTTEST1|10.10.10.1:8080TEST2|10.10.10.2:8080
# 2.端口监控脚本# vim port_check.sh#!/bin/bashdiscovery() {      printf "{\n" printf "\t\"data\": [\n"    info=(`cat /App/script/zabbix/port.conf`)    for ((num=0;i<${#info[@]};++i)) do        service=`echo ${info[$num]} | awk -F'|' '{print $1}'`        link=`echo ${iinfo[$num]} | awk -F'|' '{print $2}'` if [[ $num -eq $((${#ip_port[@]}-1)) ]] then            printf "\t\t{ \"{#LINK}\":\"${link}\", \"{#SERVICE}\":\"${service}\" }\n" else            printf "\t\t{ \"{#LINK}\":\"${link}\", \"{#SERVICE}\":\"${service}\" },\n" ((num++)) fi done printf "\t]\n" printf "}\n"}
test_port() {    ip=`echo $1 | awk -F':' '{print $1}'`    port=`echo $1 | awk -F':' '{print $2}'` nc -z -w 2 $1 $2 2> /dev/null && echo 0 || echo 1}
if [[ $1 == 'discovery' ]]then discoveryelif [[ $1 == 'test_port' ]]then    test_port $2else    echo "Usage: /App/script/zabbix/port_check.sh discovery | test_port"fi

我们希望监控脚本可以兼容未标准化的老应用,也能够接入标准化的新应用。当状态码返回非0时,能够通过APP_NAME 及 IP:PORT 直接区分关联应用: 

告警内容为:# 响应非0则告警TEST1|10.10.10.1:8080 状态码为1


场景需求

当我们每上线一个应用都需要手动添加URL监控或端口监控,这对团队成员的素质要求很高,一旦有遗漏,很可能导致应用故障无法及时发现。因此就有了自动添加监控项的需求。


还是以Zabbix监控平台为例,自动添加监控项涉及到的方法如下:

  • 获取集中管理机上监控项,从而判断是否需要新增;

  • 在集中管理机上新增监控项;



具体流程图如下:

场景实现


我们在Jenkins扩展共享库中定义了一个系统监控级的原子模型,目的是定义和系统监控相关的方法,用于和其他自动场景进行联动。虽然我们以Zabbix监控为例子,但不限于此,如:

  • Zabbix

  • 夜莺

  • Prometheus

  • Grafana


在此我们初步定义的功能有:

  • 监控项新增

  • 监控项屏蔽、恢复


其他可根据实际需求自行补充。


1.扩展共享库模目录结构

shared-library|--resources|--src|--vars |--zabbix.groovy

2.模块功能实现

vim zabbix.groovy/*用途:1.zabbix 添加监控*/import groovy.json.JsonSlurper
// 获取管理机监控项def Zabbix_ItemKey_Status(APP_Item_Key) { def data = """ { "jsonrpc":"2.0", "method":"item.get", "params":{ "output": "extend", "hostids": "10355", "search": { "key_": "${APP_Item_Key}" } }, "auth":"c919301e492b03f66673f2274e9ba9db", "id":1 } """ def response = httpRequest contentType: 'APPLICATION_JSON', httpMode: 'POST', requestBody: data, url: "http://10.164.194.54:8888/api_jsonrpc.php" def jsonSlurper = new JsonSlurper() def content = jsonSlurper.parseText(response.content) println('Response: '+response.content) return content.result.isEmpty()}
// 新增URL监控、端口监控至相关配置文件def Zabbix_Config(AppName,APP_Alter_TYPE,APP_Item_Key) { if (Zabbix_ItemKey_Status(APP_Item_Key)) { if (APPLICATION_JSON == "IP_PORT"){ sh """ sudo su - root -c 'ansible 10.10.10.250 -b -m lineinfile -a \" """ Println("True: IP_PORT") }else {            sh """ sudo su - root -c 'ansible 10.10.10.250 -b -m lineinfile -a \" """ Println("True: HTTP_URL") } }else { Println("监控项已存在无需操作") }}


由于是在集中管理机上新增监控项,在此我们省略了获取集中管理机的hostid操作。而是直接通过固定的hostid来查找对应的监控项是否存在,最后执行新增操作。


3.Jenkins pipeline script

@Library('shared-library')pipeline { agent any    options {     timestamps()    }    stages{        stage('添加端口监控') {         when {                expression { IP_PORT != '' }            }     steps {     script {                    zabbix.Zabbix_Config("${APP_NAME}","IP_PORT","${IP_PORT}")     }     }     }        stage('添加url监控') { when {                expression { HTTP_URL != '' } } steps { script {                    zabbix.Zabbix_Config("${APP_NAME}","HTTP_URL","${HTTP_URL}") } } }         }}

从pipeline 脚本看,参数化构建过程中会根据参数是否为空来判断是否执行相应的动作。如果为空,则跳过;如果不为空,则调用扩展共享库进一步操作。


4.Jenkins参数化构建

填写运行参数:

构建结果:


总结

我们通过对扩展共享库中的系统监控级原子模型进行编排,来实现监控项的自动增加,为以后的系统应用自动上线场景做好了铺垫。


Apollo:分布式配置管理中心

CI/CD如何支撑运维自动化

运维思索:自动化运维体系如何入手?

运维思考:Java进程管理规范

cachecloud:支持Redis多种架构的云管理平台

Jenkins+Ansible:助力基础设施建设



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存