Monitoring

GPFS Client side monitoring on k8s

토마스.dev 2019. 12. 10. 14:53

GPFS(General Parallel File System)는 IBM에서 개발된 파일시스템으로 1998년에 1.1버전이 최초 출시하면서 계속해서 발전해 온 것으로 알고 있다. 

 

https://www.ibm.com/support/knowledgecenter/ko/SSH2TE_1.1.0/com.ibm.7700.r2.common.doc/doc/c00000085.html

 

IBM Knowledge Center

Please note that DISQUS operates this forum. When you sign in to comment, IBM will provide your email, first name and last name to DISQUS. That information, along with your comments, will be governed by DISQUS’ privacy policy. By commenting, you are accept

www.ibm.com

시간이 되면 좀 더 자세히 공부해볼 필요가 있겠지만, 일단 GPFS를 마운트해서 사용하는 k8s node 에서 필요 Metric을 수집하는 방법을 공유해보고자 한다. 

 

사실 이 metric은 GPFS 서버쪽에서 하면 될 일이나 업무분장상 서버쪽 모니터링 데이터에 접근하기가 어려웠고, 기존 다른 metric과 통합하여 사용할 필요가 있어 Client쪽에서 수집하였다.

 

GPFS 마운트된 볼륨들은 Block Device 가 아니기 때문에 node_disk_* metric에는 나타나지 않는다. GPFS에서 제공하는 모니터링을 툴을 이용해야 한다.

 

GPFS을 모니터링하는 CLI는 mmpmon으로 /usr/lpp/mmfs/bin 에 위치하고 있으며 실제 파일타입은 파이썬으로 되어 있다.

 

필자는 node-exporter의 textfile collector기능을 이용하여, mmpmon을 실행해 prometheus data model로 변경해주는 쉘스크립트를 sidecar로 붙여서 사용했다.

 

먼저, mmpmon을 실행하기 위해서 Base 컨테이너를 python:3.7 로 사용하였고 mmpmon이 위치한 hostpath를 설정해 주어야 한다. (mmpmon 등 gpfs관련 파일들이 전부 host에 존재하고 있어야 한다)

 

붙여야 하는 볼륨은 두가지 인데, /usr/lpp/mmfs와 /var/mmfs 이며, 이중 /var/mmfs에는 daemon과의 통신을 위한 소켓파일을 생성하므로 쓰기모드로 되어있어야 한다. 

 

volumes:
- hostPath:
  path: /usr/lpp/mmfs
  type: ""
  name: gpfs
- hostPath:
  path: /var/mmfs
  type: ""
  name: gpfsvar
- emptyDir: {}
  name: textfiles


보안상 관련된 스크립트만 마운트 해야하겠지만, 일일히 추적해서 나열하기가 번거로운 관계로 위 2개 볼륨을 마운트하였다.(스크립트 들이 대부분 절대경로로 실행되므로 컨테이너에 마운트되는 경로도 동일하게 해준다)

 

그리고 node-exporter에서 textfile을 읽기위해 공통으로 사용할 emptyDir 볼륨을 하나 생성하여 양 컨테이너에 모두 마운트 시켜주었다.

 

마지막으로 runAsUser를 root로 해줘야 한다. 해당 스크립트들이 보통 root로만 실행할수 있기 때문이다.

 

다음으로 mmpmon으로부터 Metric을 parsing 처리해야 하는 컨테이너 이미지를 만들어야하는데, -p 와 -s 옵션을 이용하며 readable한 결과가 아닌 수치만 열거된 결과를 처리하면 된다. 참고로 while loop로 매번 mmpmon을 실행한다면 임시 디렉토리/파일이 지속적으로 생성되므로 커널 dentry cache가 급격히 올라갈수 있다. 그래서 mmpmon 을 계속 켜둔 상태에서 파이프라인을 이용하는 것이 바람직하다. 

 

필자는 read/write bytes만 수집하면 되서 아래와 같은 스크립트만 넣어 만든 이미지를 사용하였다.

 

parse_result() {

  start="$(date -u +%s)"
  end=$start

  touch $TARGET_PATH/gpfs_read_bytes_total.prom
  touch $TARGET_PATH/gpfs_write_bytes_total.prom

  echo "Start parsing..."

  while read line; do
    start="$(date -u +%s)"
    duration=$((start - end))
    if (( duration > CLEANUP_TIMEOUT_S )); then
      cat /dev/null > $TARGET_PATH/gpfs_read_bytes_total.prom
      cat /dev/null > $TARGET_PATH/gpfs_write_bytes_total.prom
    fi

    data=($line)
    addr=${data[2]}
    node=${data[4]}
    gc=${data[12]}
    fs=${data[14]}
    br=${data[18]}
    bw=${data[20]}

    echo 'node:gpfs_read_bytes_total{address="'$addr'", node="'$node'", gpfs_cluster="'$gc'", filesystem="'$fs'"} '$br >> $TARGET_PATH/gpfs_read_bytes_total.prom
    echo 'node:gpfs_write_bytes_total{address="'$addr'", node="'$node'", gpfs_cluster="'$gc'", filesystem="'$fs'"} '$bw >> $TARGET_PATH/gpfs_write_bytes_total.prom
    end="$(date -u +%s)"
  done
}

# mmpmon [-i CommandFile] [-d IntegerDelayValue] [-p]
#   [-r IntegerRepeatValue] [-s] [-t IntegerTimeoutValue]

echo "Start gpfs-exporter..."
echo fs_io_s | $MMFS_PATH/bin/mmpmon -p -s -r 0 -d $INTERVAL_MS -t 10 | parse_result