自动化运维—tomcat服务起停(mysql+shell+django+bootstrap+jquery)

服务器 数据中心 自动化
项目介绍:自动化运维是未来的趋势,最近学了不少东西,正好通过这个小项目把这些学的东西串起来,练练手。

项目简介:

项目介绍:自动化运维是未来的趋势,最近学了不少东西,正好通过这个小项目把这些学的东西串起来,练练手。

基础架构:

  • 服务器端:web框架-Django
  • 前端:html css jQuery bootstrap
  • 脚本:shell
  • 适用系统:redhat5.8/redhat6.6

平台已实现功能:

中间件和数据库软件的启停和状态检查 (tomcat,nginx,apache,oracle,mysql)

完整功能设计图:

[[198479]]

效果图:

架构图(简要):

项目源码:https://github.com/SwimBalance/autoops4

shell脚本

 #!/bin/sh 
#Filename:starttomcat.sh 
#需要传入参数:$1 $2 $3 
#    $1:tomcat的home目录 
#    $2:端口号 
#    $3:启动tomcat超时时长 
#输出结果说明: 
#    101:启动成功 
#    104:启动超时 
 
#写日志函数 
log(){ 
    echo `date +"%F %T"`"    "$* >> /logs/tomcat.log 

 
#开启tomcat函数 
starttomcat(){ 
    log "[command]:"$0"    [parameters]:"$* 
    #启动tomcat前需要调用checktomcat获取tomcat状态 
    status=`. /operation/tomcat/checktomcat.sh $1 $2` 
    #如果tomcat处于运行状态,就不必再启动,把状态信息返回前端 
    if [ $status -eq 101 ];then 
        echo 101 
    #如果tomcat未运行,执行启动操作 
    else 
        su - tomcat -c $1/bin/startup.sh  >/dev/null 2>&1 
        #设置count计时 
        count=0 
        #每5秒检查一次tomcat状态,直到检查到tomcat成功启动或者超时 
        status=`. /operation/tomcat/checktomcat.sh $1 $2` 
        until [ $status -eq 101 ] || [ $count -ge $3 ] 
        do 
            sleep 5 
            let count=$count+5 
            status=`. /operation/tomcat/checktomcat.sh $1 $2` 
        done 
        #如果检测到tomcat正常,判断为启动成功,返回状态信息 
        if [ $status -eq 101 ];then 
            echo 101 
        #如果超时还未启动成功,则判断为启动超时,返回启动超时代号104 
        else 
            echo 104 
        fi 
    fi 

 
starttomcat $1 $2 $3 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.

views.py:tomcat操作响应函数

# 针对tomcat服务器的操作: 
# 1.首先通过前台获得ID 和 操作 
# 2.通过ID 丰富信息 
# 3.形成完整的操作SQL 
# 4.执行SQL,返回结果 
# 5.将操作信息及结果写入操作记录表,并将结果返回前台 
# 6.前台收到信息更新tomcat现在运行状态 
def operation(request): 
    # 获得前台信息 
    tomcat_id = request.GET.get('id'
    tomcat_action = request.GET.get('action'
    oper = request.COOKIES.get('loginname'
    # 根据ID和action 获得任务信息,并形成完整的操作SQL,都存入taskinfo中 
    taskinfo = get_taskinfo(tomcat_id, tomcat_action, oper) 
    # 传入taskinfo,执行SQL操作,返回目标服务器控制台的结果 
    mytask = Task(taskinfo) 
    result = mytask.execute() 
    if result.isdigit(): 
        taskinfo['resulut'] = result 
    else
        taskinfo['resulut'] = '102' 
    # 将操作记录写入记录表中,同时更新tomcatdata表中的状态字段 
    genrecords_updatestatus(taskinfo) 
    # 将结果传到前台 
    message = { 
        '101''Tomcat正常运行.'
        '102''Tomcat异常,请人工检查.'
        '103''Tomcat服务关闭.'
        '104''Tomcat启动超时.'
        '105''Tomcat关闭超时.'
    } 
    return JsonResponse({ 
        'status': taskinfo['resulut'], 
        'message': message[taskinfo['resulut']], 
    }) 
 
# 根据ID生成taskinfo 
def get_taskinfo(tomcat_id, tomcat_action, oper): 
    with connection.cursor() as cursor
        cursor.execute
            'SELECT id, tomcatport, tomcathome, ipaddress, startwait, stopwait FROM tomcatdata WHERE id = %s' % tomcat_id 
        ) 
        tomcater = dictfetchall(cursor)[0] 
        serverip = tomcater['ipaddress'
        cursor.execute
            "SELECT user1,password1 FROM machine_pwd WHERE ipaddress = '%s'" % serverip 
        ) 
        userinfo = dictfetchall(cursor)[0] 
    if tomcat_action == 'check_tomcat'
        tomcat_home = tomcater['tomcathome'
        tomcat_port = tomcater['tomcatport'
        command = 'sh /operation/tomcat/checktomcat.sh %s %s ' % (tomcat_home, tomcat_port) 
    elif tomcat_action == 'start_tomcat'
        # 需要传入三个参数 home目录/端口号/启动超时时长 
        tomcat_home = tomcater['tomcathome'
        tomcat_port = tomcater['tomcatport'
        start_wait = tomcater['startwait'
        # sh_dir = '/operation/tomcat/starttomcat.sh' 
        command = 'sh /operation/tomcat/starttomcat.sh %s %s %s ' % (tomcat_home, tomcat_port, start_wait) 
    elif tomcat_action == 'stop_tomcat'
        # 需要传入三个参数 home目录/端口号/启动超时时长 
        tomcat_home = tomcater['tomcathome'
        tomcat_port = tomcater['tomcatport'
        stop_wait = tomcater['stopwait'
        # sh_dir = '/operation/tomcat/starttomcat.sh' 
        command = 'sh /operation/tomcat/stoptomcat.sh %s %s %s ' % (tomcat_home, tomcat_port, stop_wait) 
    task_info = { 
        'id': tomcat_id, 
        'action': tomcat_action, 
        'oper': oper, 
        'ip': tomcater['ipaddress'], 
        'user': userinfo['user1'], 
        'pwd': userinfo['password1'], 
        'cmd': command, 
        'result''' 
    } 
    return task_info 
 
 
# 写入操作记录并更新tomcat状态 
def genrecords_updatestatus(taskinfo): 
    with connection.cursor() as cursor
        sqlstatement1 = "insert into audit_log (oper_user, oper_command, oper_message) VALUES ('%s', '%s', '%s')" % ( 
            taskinfo['oper'], taskinfo['cmd'], taskinfo['resulut']) 
        sqlstatement2 = "update tomcatdata set status = %d where id = %r" % (int(taskinfo['resulut']), taskinfo['id']) 
        cursor.execute(sqlstatement1) 
        cursor.execute(sqlstatement2) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.

Task类

import paramiko 
 
 
lass Task(object): 
   def __init__(self, task_info): 
       self.task_info = task_info 
 
   def create_connect(self): 
       # 创建SSH对象 
       connectObj = paramiko.SSHClient() 
       # 把要连接的机器添加到known_hosts文件中 
       connectObj.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
       # 连接服务器 
       connectObj.connect
           hostname=self.task_info['ip'], 
           username=self.task_info['user'], 
           password=self.task_info['pwd'], 
           port=22, 
           timeout=10 
       ) 
       # 判断是否连接成功 
       ################### 
       return connectObj 
 
   def execute(self): 
       try: 
           connectObj = self.create_connect() 
       except
           return '102' 
       cmd = self.task_info['cmd'
       stdin, stdout, stderr = connectObj.exec_command(cmd) 
       result = stdout.read() 
       connectObj.close() 
       if not result: 
           result = stderr.read().strip() 
       return result.decode().strip() 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.

js文件

 $(function () { 
     $("ul[id='servicemgr'] li").click(function () { 
         <!-- 导入workPage--> 
         if (this.id == 'toms') { 
             $("#workpage").empty().load("/static/maintenance/html/workpage.html #tom_workpage"); 
             $.ajax({ 
                 type: "GET"
                 url: "./../tomcatData/"
                 datatype: 'json'
                 data: {page: 1}, 
                 success: function (datas) { 
                     loadtomcatdata(datas) 
                 } 
             }); 
         } else if (this.id == 'oras') { 
             $("#workpage").empty().load("/static/maintenance/html/workpage.html #ora_workpage"); 
             $.ajax({ 
                 type: "GET"
                 url: "./../oracleData/"
                 datatype: 'json'
                 success: function (datas) { 
                     loadoracledata(datas) 
                 } 
             }) 
         } 
     }); 
 }); 
  
 // 针对tomcat服务器的操作 
 function opt_tomcat(obj) { 
     var tomcat_mes = $("#tomcat_mes"); 
     tomcat_mes.empty().append("正在玩命操作,请等待…"); 
     var id = obj.id; 
     var action = obj.name
     $.ajax({ 
         type: 'Get'
         url: './../operation'
         data: {'id': id, 'action'action}, 
         success: function (data) { 
             tomcat_mes.empty().append(data['message']); 
             //更新状态 
             if (data['status'] == '101') { 
                 $(obj).parent().prevAll('.status').children('span').attr('class''glyphicon glyphicon-ok-sign'
             } else if (data['status'] == '102' || data['status'] == '104' || data['status'] == '105') { 
                 $(obj).parent().prevAll('.status').children('span').attr('class''glyphicon glyphicon-exclamation-sign'
             } else if (data['status'] == '103') { 
                 $(obj).parent().prevAll('.status').children('span').attr('class''glyphicon glyphicon-remove-sign'
             } 
         } 
     }) 
 } 
 // 分页 
 function page(obj) { 
     var page_number = $(obj).text(); 
     $.ajax({ 
         type: "GET"
         url: "./../tomcatData/"
         datatype: 'json'
         data: {page: page_number}, 
         success: function (datas) { 
             loadtomcatdata(datas) 
         } 
     }); 
 } 
 //导入tomcat数据 
 function loadtomcatdata(datas) { 
     var text = $('.text'); 
     text.empty(); 
     var html = ''
     for (var i = 0; i < datas.length; i++) { 
         var id = datas[i]['id']; 
         var ip = datas[i]['ipaddress']; 
         var host = datas[i]['machine']; 
         var dec = datas[i]['description']; 
         var status = datas[i]['status']; 
         html += '<tr>'
         html += '<td>' + id + '</td>'
         html += '<td>' + ip + '</td>'
         html += '<td>' + host + '</td>'
         html += '<td>' + dec + '</td>'
         // html += '<td class="status">' + status + '</td>'
         //更新状态 
         if (status == '101') { 
             html += '<td class="status"><span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span></td>'
         } else if (status == '102' || status == '104' || status == '105') { 
             html += '<td class="status"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span></td>'
         } else if (status == '103') { 
             html += '<td class="status"><span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span></td>'
         } 
         html += '<td>' + '<button id=' + id + ' onclick="opt_tomcat(this)" name="check_tomcat" class="btn btn-default" data-toggle="modal" data-target="#myModal">'
         html += '<span class="glyphicon glyphicon-check" aria-hidden="true"></span></button></td>'
         html += '<td>' + '<button id=' + id + ' onclick="opt_tomcat(this)" name="start_tomcat" class="btn btn-default" data-toggle="modal" data-target="#myModal">'
         html += '<span class="glyphicon glyphicon-play" aria-hidden="true"></span></button></td>'
         html += '<td>' + '<button id=' + id + ' onclick="opt_tomcat(this)" name="stop_tomcat" class="btn btn-default" data-toggle="modal" data-target="#myModal">'
         html += '<span class="glyphicon glyphicon-stop" aria-hidden="true"></span></button></td>'
         html += '</tr>'
     } 
     text.append(html); 
  

//搜索栏 
function searchtomcat() { 
 
    var search_val = $('#search_tom').val(); 
    $.ajax({ 
        type: "GET"
        url: "/../searchtomcat/"
        data: {'data': search_val}, 
        datatype: "json"
        success: function (datas) { 
            loadtomcatdata(datas); 
            $('#preandnext').empty() 
        } 
    }) 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.

index.html

<!DOCTYPE html> 
<html lang="en"
<head> 
    {% load static %} 
    <title>自动化运维</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"
    <!-- 引入 Bootstrap --> 
    <link href="{% static 'maintenance/bootstrap3.3.7/css/bootstrap.min.css' %}" rel="stylesheet"
    <meta charset="UTF-8"
    <!-- 导入Jquery文件--> 
    <script src="{% static 'maintenance/js/jquery-3.2.1.min.js' %}"></script> 
    <!--导入bootstrap中的js 插件--> 
    <script src="{% static 'maintenance/bootstrap3.3.7/js/bootstrap.min.js' %}"></script> 
    <!--导入自己的js文件--> 
    <script src="{% static 'maintenance/js/show_workpage.js' %}"></script> 
    <style> 
        .glyphicon-ok-sign{color:green} 
        .glyphicon-exclamation-sign{color:crimson;} 
        .glyphicon-remove-sign{color:darkgray} 
    </style> 
</head> 
<body> 
<div class=" container-fluid"
    <div class="row"
        <div class="col-lg-12" style="text-align:center;background-color: #9acfea"
            <h3>AUTO OPERATION 
                <small>自动化运维平台</small> 
            </h3> 
        </div> 
    </div> 
    <div class="row "
        <div class="col-lg-2" style="margin-left :-15px;"
            <ul class="nav nav-pills nav-stacked"
                <li id="home" role="presentation" class="active"><a href="javascript:void(0)">主页</a></li> 
                <li class="active"
                    <a href="#servicemgr" class="nav-header collapsed " data-toggle="collapse"
                        <i class="glyphicon glyphicon-cog"></i>服务管理 
                        <span class="pull-right glyphicon glyphicon-chevron-toggle"></span> 
                    </a> 
                    <ul id="servicemgr" class="nav nav-list collapse in" style="list-style: none"
                        <li id="oras" role="presentation"><a href="javascript:void(0)">Oracle服务管理</a></li> 
                        <li id="mysqls" role="presentation"><a href="javascript:void(0)">MySQL服务管理</a></li> 
                        <li id="toms" role="presentation"><a href="javascript:void(0)">Tomcat服务管理</a></li> 
                        <li id="apache" role="presentation"><a href="javascript:void(0)">Apache服务管理</a></li> 
                        <li id="nginx" role="presentation"><a href="javascript:void(0)">NGINX服务管理</a></li> 
                    </ul> 
                </li> 
                <li class="active"
                    <a href="#systemsetting" class="nav-header collapsed " data-toggle="collapse"
                        <i class="glyphicon glyphicon-cog"></i>系统管理 
                        <span class="pull-right glyphicon glyphicon-chevron-toggle"></span> 
                    </a> 
                    <ul id="systemsetting" class="nav nav-list collapse in"
                        <li class="active"><a href="#"><i class="glyphicon glyphicon-user"></i> 用户信息维护</a></li> 
                        <li><a href="javascript:void(0)"><i class="glyphicon glyphicon-th-list"></i> 应用系统信息维护</a></li> 
                        <li><a href="javascript:void(0)"><i class="glyphicon glyphicon-asterisk"></i> 服务器信息维护</a></li> 
                        <li><a href="javascript:void(0)"><i class="glyphicon glyphicon-eye-open"></i> 日志查看</a></li> 
                    </ul> 
                </li> 
            </ul> 
        </div> 
        <div class="col-lg-10"
            <div id="workpage"></div> 
            <!-- 模态框(Modal) --> 
            <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" 
                 aria-hidden="true"
                <div class="modal-dialog"
                    <div class="modal-content"
                        <div class="modal-header"
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> 
                            <h4 class="modal-title" id="myModalLabel">操作结果</h4> 
                        </div> 
                        <div class="modal-body" id="tomcat_mes"></div> 
                        <div class="modal-footer"
                            <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> 
                        </div> 
                    </div><!-- /.modal-content --> 
                </div><!-- /.modal --> 
            </div> 
        </div> 
    </div> 
    <div class="page-footer"></div> 
</div> 
 
</body> 
</html> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.

 

workpage.html

<!-- tomcat工作页--> 
<div id="tom_workpage"
    <div style="border: 1px;"
        <div class="row"
            <ol class="breadcrumb"
                <li><a href="#">Home</a></li> 
                <li class="active">Tomcat</li> 
            </ol> 
            <div class="row"
                <div class="col-lg-6" style="float: right"
                    <div class="input-group"
                        <input id="search_tom" type="text" class="form-control" placeholder="IP/服务器名称" onkeydown="if(event.keyCode==13) {searchtomcat()}"
                        <span class="input-group-btn"
        <button class="btn btn-default" type="button" onclick="searchtomcat()">查找</button> 
      </span> 
                    </div><!-- /input-group --> 
                </div><!-- /.col-lg-6 --> 
            </div><!-- /.row --> 
            <table class="table table-hover table-condensed"
                <caption><strong>Tomcat应用服务器清单</strong></caption> 
                <thead> 
                <tr> 
                    <th>ID</th> 
                    <th>IP</th> 
                    <th>主机名</th> 
                    <th>概要</th> 
                    <th>状态</th> 
                    <th>检查</th> 
                    <th>开启</th> 
                    <th>停止</th> 
                </tr> 
                </thead> 
                <tbody class="text"
 
                </tbody> 
            </table
        </div> 
        <nav id="preandnext" style="text-align: center"
            <ul class="pagination" style="margin: 0"
                <li onclick="previousPage(this)"><a href="javascript:void(0)">&laquo;</a></li> 
                <li onclick="page(this)"><a href="javascript:void(0)">1</a></li> 
                <li onclick="page(this)"><a href="javascript:void(0)">2</a></li> 
                <li onclick="page(this)"><a href="javascript:void(0)">3</a></li> 
                <li onclick="page(this)"><a href="javascript:void(0)">4</a></li> 
                <li onclick="page(this)"><a href="javascript:void(0)">5</a></li> 
                <li onclick="nextPage(this)"><a href="javascript:void(0)">&raquo;</a></li> 
            </ul> 
        </nav> 
    </div> 
</div> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

 

这个小项目还会继续做下去,期望能达到当初自己设计的那样。。。。。。。

责任编辑:武晓燕 来源: 博客园
相关推荐

2012-10-22 14:54:48

2014-08-04 10:10:35

IT运维自动化运维

2018-06-23 07:31:05

2017-10-13 13:14:35

互联网

2014-09-22 11:24:18

运维

2018-07-26 13:50:37

IT架构运维

2013-04-16 14:55:21

自动化运维Puppet实战

2012-11-20 17:22:57

2015-10-08 10:55:23

云服务自动化运维 ANSIBLE

2013-04-17 15:48:51

2010-08-12 17:39:07

网站运维自动化管理

2014-06-20 18:26:45

WOT2014自动化运维

2012-05-05 21:22:40

2012-05-05 21:48:43

puppet自动化运维

2012-05-05 22:27:46

puppet自动化运维

2014-07-26 15:11:20

WOT2014自动化运维

2015-10-09 13:14:10

clip自动化运维工具

2013-04-11 17:31:28

运维自动化Cobbler

2012-05-05 21:28:44

2024-06-11 10:41:14

点赞
收藏

51CTO技术栈公众号