STUDY

PicOS OvS sFlow Prometheus 연동 - sFlow-RT, 연동 과정, Prometheus 설정

YOU__NAVI 2025. 3. 19. 13:40

Prometheus 설정하는 방법이 한국어 자료가 없고 내용이 부실해서 여기에 별도로 정리함.

 

구조: OvS sFlow → sFlow-RT  Prometheus

 

OvS sFlow 설정 방법:

Web GUI로 설정하나 CLI로 설정하나 결과는 동일하다.

Polling: Counter Sample의 Polling Interval 주기 (Default: 128)

Header: 이전 글의 Flow Sample의 Raw packet header로 취할 바이트 (Default: 128)

Agent: 샘플링 데이터를 Collector에게 보낼 Interface 이름

Sampling: 샘플링 레이트 (Default: 128)

Targets: Collector 위치 IP, Port

 

sFlow-RT: sFlow Collector 중 하나로 InMon에서 제공. 자체 Prometheus Exporter가 있고 오픈소스는 아닌듯 함

설치: https://sflow-rt.com/download.php

 

sFlow-RT 와 Prometheus와 연동하기 

1. sFlow-RT Exporter 설치
https://github.com/sflow-rt/prometheus

sflow-rt/get-app.sh sflow-rt prometheus
# You need to restart sFlow-RT

 

2. sFlow-RT 실행

3. http://<IP>:8008/ 접속해서 sFlow-RT 실행 확인

4. prometheus.yml 수정

  - job_name: "sflow-rt-exporter"
    metrics_path: /app/prometheus/scripts/export.js/flows/ALL/txt
    static_configs:
      - targets: ["localhost:8008"]
    params:
      metric: ["sflow_bytes"]
      key:
        [
          "null:agent:unknown",
          "null:ipsource:unknown",
          "null:ipdestination:unknown",
          "null:tcpsourceport:unknown",
          "null:tcpdestinationport:unknown",
          "null:udpsourceport:unknown",
          "null:udpdestinationport:unknown",
          "null:ipprotocol:unknown",
          "null:ethernetprotocol:unknown",
        ]
      label:
        [
          "agent",
          "srcIP",
          "dstIP",
          "tcpSrcPort",
          "tcpDstPort",
          "udpSrcPort",
          "udpDstPort",
          "ipProtocolType",
          "ethernetType",
        ]  
      value: ['bytes']
      scale: ['8']
      aggMode: ['sum']
      minValue: ['1000']
      maxFlows: ['1000000']
      t: ['10']

 

5. Prometheus 재시작
6. Prometheus 접속해서 sFlow 결과 확인

 

잘 되는데 뭐가 문제냐?

부정확한 값. iPerf3 60초 100MB 보내면 대략 720MB 정도로 표기하고 실제 Wireshark 캡처 용량도 740MB 이지만 조회한 데이터는 850MB 정도이고 60초 이후에 집계할 때마다 값이 증가하면서 갱신됨. iPerf3 테스트는 끝난지 30초 지났지만 값이 계속 증가함.

중복된 Counter Sample의 값이 엇나가서 이런 현상이 발생한다고 추측하는데 정확하진 않다.

 

그럼 prometheus 튜닝하면 되지않냐? 

문제는 4. prometheus.yml 수정 단계인데

 

1. /app/prometheus/scripts/export.js/flows/ALL/txt 접속 불가능: 이건 어쨌든 동작하니까 REST 맞추면 해결된다고 칩시다.

2. params 정보 없음

sFlow-RT 공식 제공 정보가 많이 부족하기 때문에 튜닝이 어렵다.

 

https://blog.sflow.com/2019/10/flow-metrics-with-prometheus-and-grafana.html

sFlow-RT 공식 블로그에서 작성한 자료와

https://hub.docker.com/r/sflow/prometheus/

sFlow-RT Docker Prometheus 이미지는 prometheus.yml의 예시를 보여주고

https://sflow-rt.com/define_flow.php

특정 속성을 알려주고있다.

 

export.js에 의하면

function getFlows(agents,query) {
  if(!query.metric) throw 'bad_request';

  var metric = query.metric[0];
  var labels = query.label ? query.label.join(',') : null;
  var keys = query.key ? query.key.join(',') : null;
  var value = query.value ? query.value[0] : null;
  var n = query.n ? query.n[0] : 10;
  var t = query.t ? query.t[0] : 15;
  var filter = query.filter ? query.filter[0] : null;
  var dropped = query.dropped ? "true" === query.dropped[0] : false;
  var aggMode = query.aggMode ? query.aggMode[0] : dropped ? 'sum' : 'max';
  var maxFlows = query.maxFlows ? query.maxFlows[0] : 20;
  var minValue = query.minValue ? query.minValue[0] : 0.1;
  var scale = query.scale ? parseFloat(query.scale[0]) : 1.0;

메트릭 값들과 default를 확인할 수 있다.

 

https://kakkotetsu.hatenablog.com/entry/2021/05/28/180516

어떤 일본인이 나랑 같은 고민을 한 흔적을 발견했는데 prometheus.yml을 수정하는데 큰 도움을 받았다.

심지어 이 글에서도 부족한 정보에 불평하는 어조를 확인할 수 있다.

 

http://<IP>:8008/app/prometheus/api/index.html 의 Flows 항목에 따르면

n: 유지하고싶은 가장 큰 플로우 엔트리의 개수

t: 평활화 수준(시간)

aggMode: 중복 플로우 records를 집계하는 방법. 값: sum, max, edge, core

maxFlow: 최대 플로우 record 개수

minValue: 집계할 플로우 바이트 최저치

라고 확인할 수 있다.

aggMode를 4개 다 확인해봤지만 뒤에 두개는 아예 작동을 안하고 (topology 관련된 것으로 추정) 정확한 바이트 측정은 실패했다.

 

집계 오차에 대해 sFlow-RT 책임자 Peter에게 직접 문의해본 결과

1. 평활화 수준 t는 최소한 Prometheus의 Scrape Interval 만큼 커야한다.

2. iPerf3로 60초 10Mbit/s를 전송하면 50000개의 1500바이트 패킷이 나오는데, 이를 128로 샘플링하면 400개의 표본이 나오고 공식에 대입해서 계산할 시 오차는 ±8.5% 정도이다. 매 초마다, 또는 매 15초(scrape interval)마다 상대 오차는 더 커진다. SDN 상에서 10Mbps를 감지하려면 샘플링 레이트를 10으로 조절해야한다.

3. sFlow-RT의 플로우 레이트는 신속한 탐지나 Large Flow 제어를 위한 것이다. (DDoS 탐지나 로드 밸런싱같은)
정확한 Flow Total을 알고싶다면 sFlow-RT를 flow records를 로깅하도록 설정해야한다. 로그에는 순간 속도가 아닌 flow의 전체 총량이 들어있다.

https://sflow-rt.com/writing_applications.php#handleflow

 

라는 답변을 받았고 이에 해결책으로 

1. sFlow → sFlow-RT exporter 수정: export.js 파일은 일부분에 불과하며 나머지 내용이 은닉돼있어 회의적임.

2. Handle flow records: flow record를 활용하는 커스텀된 프로그램 작성  다른 Exporter를 사용하면 되지않을까?

3. 다른 Exporter 사용: Goflow2 시도 예정

를 고려함.

 

출처

openvswitch.org/support/dist-docs/ovs-vsctl.8.txt

Configuring sFlow - PICOS-4.4.5_Configuration_Guide - PICOS Documentation

https://github.com/sflow-rt/prometheus

https://blog.sflow.com/2019/10/flow-metrics-with-prometheus-and-grafana.html

https://grafana.com/grafana/dashboards/11146-sflow-rt-countries-and-networks/

https://hub.docker.com/r/sflow/prometheus/

https://sflow-rt.com/define_flow.php

https://kakkotetsu.hatenablog.com/entry/2021/05/28/180516

https://sflow-rt.com/writing_applications.php#handleflow