Probius+Prometheus通過API集成POD監控

上一篇文章Probius+Kubernetes任務系統如虎添翼講了我們把Kubernetes集成進了任務系統Probius,上線後小夥伴反饋雖然擺脫了Kubernetes-Dashboard,但還是得去Grafana系統查看容器的監控數據,能否將容器監控也給集成進Probius呢?只要能優化流程提高效率那就必須給安排

當前Kubernetes集羣通過Prometheus來收集和存儲監控數據同時藉助Grafana來畫圖展示,Probius若想集成容器監控只需要獲取Prometheus存儲的容器數據並繪圖展示即可,這裏涉及到兩塊內容:1. 獲取Prometheus中存儲的POD數據,2. 根據獲取到的POD數據進行畫圖展示,完成後的效果如下

獲取數據

Prometheus提供queryquery_range兩個API來獲取數據,query可以查詢給定時間點的數據,而query_range支持查詢給定時間段內的數據集合,對於我們的需求query_range再合適不過了

GET /api/v1/query_range

API支持以下幾個參數:

query:Prometheus查詢表達式,string類型

start:開始時間,rfc3339或是unix_timestamp格式

end:結束時間,rfc3339或是unix_timestamp格式

step:步長,可以是15s這樣的持續時間格式

timeout:超時時間

根據這些信息就可以編寫獲取數據的程序了,大概如下

class PrometheusApi:
    def __init__(self, range=1):
        self.domain = "https://prometheus.ops-coffee.cn"

        self.nowtime = datetime.datetime.now(datetime.timezone.utc)
        self.start_time = self.nowtime - datetime.timedelta(hours=int(range))

    def get_pod_metric(self, namespace, pod):
        _data = {"datetime": [], "cpu": {}, "memory": {}, "bandwidth": {}, "iops": {}}

        # cpu
        params = {
            "query": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace='%s', pod='%s'}) by (container)" % (
                namespace, pod),
            "start": self.start_time.isoformat(),
            "end": self.nowtime.isoformat(),
            "step": "60s"
        }
        rc = requests.get(self.domain + '/api/v1/query_range', params=params)

        for c in rc.json().get('data').get('result'):
            _data['cpu'][c['metric']['container']] = [j[1] for j in c['values']]
            
        return True, 200, _data

這裏如果對Prometheus的查詢表達式不熟悉,可以直接去Grafana圖形那複製表達式來使用,這裏我把cpu\memory等需要展示的數據統一在一個函數裏處理了,這樣只需要根據namesapce、pod和時間範圍就能獲取到一個pod的所有監控數據,方便前端展示

需要注意的是Prometheus默認使用的是UTC時間,所以在做時間處理時需要跟本地時間做轉換

畫圖展示

數據獲取到了,下一步就是畫圖展示,這裏採用了echarts,使用也非常簡單,大概代碼如下

<div class="tab-pane" id="tab-monitor">
  <div class="row">
    <div class="col-md-4">
      <div class="input-group">
        <div class="input-group-btn"><button class="btn btn-default">選擇實例</button></div>
        <select class="form-control" id="id_pod_monitor" onchange="getPodMonitor()">
          <option value="">------</option>
        </select>
      </div>
    </div>

    <div class="col-md-2">
       <div class="input-group">
          <div class="input-group-btn"><button class="btn btn-default">時間範圍</button></div>
          <select class="form-control" id="id_pod_monitor_time" onchange="getPodMonitor()">
            <option value="1" selected="selected">最近1小時</option>
            <option value="4">最近4小時</option>
            <option value="24">最近24小時</option>
            <option value="48">最近48小時</option>
            <option value="72">最近72小時</option>
          </select>
        </div>
    </div>
    <div class="col-md-6">
      <div class="pull-right">
        <button class="btn btn-default" onclick="getPodMonitor()">
          <span class="glyphicon glyphicon-refresh"></span> 刷新
        </button>
      </div>
    </div>
  </div>

  <div class="row" style="margin-top:10px;">
    <div class="col-md-6" id="id_chart_cpu" style="position: relative; height: 300px;"></div>
    <div class="col-md-6" id="id_chart_memory" style="position: relative; height: 300px;"></div>
    <div class="col-md-6" id="id_chart_bandwidth" style="position: relative; height: 300px;"></div>
    <div class="col-md-6" id="id_chart_iops" style="position: relative; height: 300px;"></div>
  </div>
</div>

<script>
    var chart_cpu = echarts.init(document.getElementById('id_chart_cpu')),
        chart_memory = echarts.init(document.getElementById('id_chart_memory')),
        chart_bandwidth = echarts.init(document.getElementById('id_chart_bandwidth')),
        chart_iops = echarts.init(document.getElementById('id_chart_iops'));
    
    function getPodMonitor() {
      var pod = $('#id_pod_monitor').val(), range = $('#id_pod_monitor_time').val();
      $.get("/kubeops/namespace/{{ namespace }}/pod/" + pod + "/monitor/?range="+ range +"&format=json", function(data) {
        if (data.state) {
          let cpu_legend = new Array, cpu_series = new Array;
          $.each(data.data.cpu, function (k, v) {
            cpu_legend.push(k);
            cpu_series.push({
              data: v,
              name: k,
              type: 'line'
            });
          })
    
          chart_cpu.setOption(
            {
              title: {text: 'CPU使用(單位:core)'},
              tooltip: {trigger: 'axis'},
              legend: {data:cpu_legend},
              xAxis: {data: data.data.datetime},
              yAxis: {type: 'value'},
              series: cpu_series
            }
          )
        }
      })
    }
</script>

echarts使用了最簡單的折線圖,也沒有太多花裏胡哨的東西,就是去後端取數據然後展示

至此搞定Probius集成POD監控,雖然這只是一個小功能但卻是很有用~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章