###暴雪爸爸开了8.0,我去保卫艾泽拉斯了,很久没有更新。公司用的BIND做的DNS管理,采用了文本格式存储。之前用过BIND+MYSQL+DLZ,对于后面想要自行搭建运维可视化平台的小伙伴来说,确实很方便。但性能问题是个大问题,最后无奈采用通过Dnspython封装的BIND接口,操作BIND的jnl文件进行动态解析。
附上一个dlz和原生bind的性能测试数据(比较老,仅供参考):
授之以渔-运维平台应用模块三(BIND篇)_第1张图片

效果图如下:
授之以渔-运维平台应用模块三(BIND篇)_第2张图片
授之以渔-运维平台应用模块三(BIND篇)_第3张图片
授之以渔-运维平台应用模块三(BIND篇)_第4张图片

#一、 Jnl文件
jnl 文件(journal文件)是bind动态更新的时候记录更新内容所生成的日志文件。BIND9支持两个授予用户对一个域执行动态更新权限的备选方案,分别由allow-update和update-policy设定。其中allow-update 授于指定用户对域中的任何名称的任何的记录更新的权利。allow-update指定哪些主机允许为主域名服务器提交动态 DNS 更新。默认为拒绝任何主机进行更新,详见百度。

##二、 环境准备

  • Dnspython对应你的python版本,官网http://www.dnspython.org/
  • Django运行版本1.6.1
  • Python运行版本2.7.1

##三、 食用过程
###1.生成TSIG key,修改named.conf添加授权,定义zone文件添加allow-update(详见百度,这里不具体展开)
###2.增删改后端部分代码

# -*- coding: utf8 -*-
import dns.tsigkeyring
import dns.update
import dns.query 
import dns.resolver
keyring = dns.tsigkeyring.from_text({"youth":tsig key密码})
up = dns.update.Update("youth.cn", keyring=keyring)
up .add("test2", 60, 'a', "192.168.183.131")    #添加名称为test2的A记录,TTL时间60,解析地址192.168.183.131
up.delete("test2")  #删除test2记录
up.replace("test2", 360, "CNAME", "test3.youth.cn.")  #将test2修改为CNAME记录,TTL时间360,CNAME地址test3.youth.cn.
dns.query.tcp(up, SERVER_IP)

###3.前端用的Metronic框架,jQuery表格插件用的dataTables,部分前端代码如下:



{% for i in user.groups.values %}{% ifequal i.name 'admin' %}
{% else %}{% endifequal %}{% endfor %}
添加DNS解析记录
DNS解析记录汇总
{% for bind in binds%} {% endfor %}
ID 名称 类型 内部/外部 解析地址 TTL 备注解析地址 更改时间 查看状态 更改操作 删除操作
{{ bind.id }} {{ bind.bind_name }} {% ifequal bind.bind_zone_id '1' %} k618.cn {% endifequal %} {% ifequal bind.bind_zone_id '2' %} youth.cn {% endifequal %} {% ifequal bind.bind_zone_id '3' %} ccyl.org.cn {% endifequal %} {% ifequal bind.bind_zone_id '4' %} gqt.org.cn {% endifequal %} {% ifequal bind.bind_type_id '1' %} A记录 {% endifequal %} {% ifequal bind.bind_type_id '6' %} CNAME记录 {% endifequal %} {% ifequal bind.bind_type_id '3' %} MX记录 {% endifequal %} {% ifequal bind.bind_type_id '4' %} NS记录 {% endifequal %} {% ifequal bind.bind_type_id '2' %} AAAA记录 {% endifequal %} {% ifequal bind.bind_type_id '5' %} TXT记录 {% endifequal %} {% ifequal bind.bind_internal_external '1' %} 内部解析 {% endifequal %} {% ifequal bind.bind_internal_external '2' %} 外部解析 {% endifequal %} {{ bind.bind_ip}} {{ bind.bind_ttl}} {{ bind.bind_intro}} {{ bind.bind_time|date:"Y-m-d H:i:s"}}

这块做了一个异步的查询,其实就是点击+号,能返回到这个域名绑定的公网IP所对应的主机,效果图如下:
image.png

var TableAdvanced = function () {

    var initTable4 = function () {
        var table = $('#bindlist');

        var nCloneTh = document.createElement('th');
        nCloneTh.className = "table-checkbox";

        var nCloneTd = document.createElement('td');
        nCloneTd.innerHTML = '';

        table.find('thead tr').each(function () {
            this.insertBefore(nCloneTh, this.childNodes[0]);
        });

        table.find('tbody tr').each(function () {
            this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
        });

        var oTable = table.dataTable({

            // Internationalisation. For more info refer to http://datatables.net/manual/i18n
            "language": {
                "aria": {
                    "sortAscending": ": activate to sort column ascending",
                    "sortDescending": ": activate to sort column descending"
                },
                "emptyTable": "未有相关数据",
                "info": "当前显示 _START_ 到 _END_ 条,共 _TOTAL_ 条记录。",
                "infoEmpty": "当前显示0到0条,共0条记录",
                "infoFiltered": "(数据库中共为 _MAX_ 条记录)",
                "lengthMenu": "显示 _MENU_ 记录",
                "search": "模糊查询:",
                "zeroRecords": "对不起,查询不到任何相关数据",
               "oPaginate": {
                   "sFirst": "首页",
                   "sPrevious": " 上一页 ",
                   "sNext": " 下一页 ",
                   "sLast": " 尾页 "
               }                
            },

            "columnDefs": [{
                "orderable": false,
                "targets": [0]
            }],
            "order": [
                [9, 'dec']
            ],
            "lengthMenu": [
                [5, 15, 20, -1],
                [5, 15, 20, "All"] // change per page values here
            ],
            // set the initial value
            "pageLength": 10
        });

        var tableWrapper = $('#sample_4_wrapper'); // datatable creates the table wrapper by adding with id {your_table_jd}_wrapper
        var tableColumnToggler = $('#sample_4_column_toggler');

        /* modify datatable control inputs */
        tableWrapper.find('.dataTables_length select').select2(); // initialize select2 dropdown
        table.on('click', ' tbody td .row-details', function () {
            var nTr = $(this).parents('tr')[0];
            if (oTable.fnIsOpen(nTr)) {
                $(this).addClass("row-details-close").removeClass("row-details-open");
                oTable.fnClose(nTr);
            } else {
                var ip = $(this).parent().parent().find('td').eq(6).attr("id");
                var type = $(this).parent().parent().find('td').eq(4).attr("id");
                var intro = $(this).parent().parent().find('td').eq(8).attr("id");
                $(this).addClass("row-details-open").removeClass("row-details-close");;
                fnFormatDetails(nTr, $(this).attr("data_id"),ip,type,intro);
            }
        });
          function fnFormatDetails(nTr, pdataId, ip ,type ,intro) {
                var aData = oTable.fnGetData(nTr);
               //根据配置Id 异步查询数据
                $.ajax({
                       type:'get',
                       url:"../bind_host_get/?ip="+ip+"&type="+type+"&intro="+intro,
                       data:{"pdataId":pdataId},
                       dataType:"json",
                       async:true,
                       beforeSend:function(xhr){//信息加载中
                           oTable.fnOpen( nTr, ' 详细信息加载中...', 'details' );
                       },
                       success:function (obj){
                               var sOut = '';
                               for(var id in obj){
                                    sOut += '';
                               }
                               sOut+='
'+id+'' + obj[id] + '
'; oTable.fnOpen( nTr,sOut, 'details' ); }, error: function(){//请求出错处理 oTable.fnOpen( nTr,'加载数据超时', 'details' ); } }); } /* handle show/hide columns*/ $('input[type="checkbox"]', tableColumnToggler).change(function () { /* Get the DataTables object again - this is not a recreation, just a get of the object */ var iCol = parseInt($(this).attr("data-column")); var bVis = oTable.fnSettings().aoColumns[iCol].bVisible; oTable.fnSetColumnVis(iCol, (bVis ? false : true)); }); } return { //main function to initiate the module init: function () { if (!jQuery().dataTable) { return; } console.log('me 1'); initTable4(); console.log('me 2'); } }; }();

####这里踩过的坑:
最终公司的DNS惨遭了30G的DD,导致运营商都跟着一起倒霉,后续将NS解析迁移至网宿的云DNS平台,我的平台还是通过网宿的云DNS平台所提供的接口API进行域名解析,BIND只作为内网解析及解析记录汇总(即选择外部解析后,解析记录将存储在我的内部平台上并推送记录到网宿节点,这也是为了将来万一换厂家,直接推送全部记录即可)
授之以渔-运维平台应用模块三(BIND篇)_第5张图片
####URL监控用的Openfalcon做的,后续会慢慢补上。。。