CloudStack의 각 node에서 NFS 연결 모니터링

CloudStack 노드의 NFS primary/secondary storage 연결을 timeout 기반으로 점검하는 스크립트입니다. findmnt, mountpoint, stat/write 테스트, NFS 로그 진단을 정리했습니다.

CloudStack에서 NFS 스토리지는 primary 또는 secondary storage로 사용될 수 있고, 특히 secondary storage는 NFS 접근이 기본 전제입니다. 각 KVM 노드에서 NFS가 멈추면 VM 생성, 템플릿 복사, 스냅샷, 볼륨 작업이 지연되거나 실패할 수 있으므로 단순 touch보다 안전한 타임아웃 기반 모니터링이 필요합니다.

먼저 현재 마운트 확인

각 노드에서 CloudStack 스토리지 마운트가 실제로 어디에 붙어 있는지 확인합니다.

findmnt -t nfs,nfs4
mount | grep -E ' type nfs| type nfs4'
df -hT | grep -E 'nfs|nfs4'

Apache CloudStack 문서는 primary storage가 NFS 또는 iSCSI 등을 사용할 수 있고, secondary storage는 NFS로 접근한다고 설명합니다. 따라서 환경별로 primary/secondary 마운트 경로를 명확히 분리해서 봐야 합니다.

대상 파일 구성

모니터링할 마운트포인트를 파일로 관리합니다.

sudo install -d -m 755 /etc/cloudstack-monitor
sudo tee /etc/cloudstack-monitor/nfs-mounts.conf >/dev/null <<'EOF'
# label mountpoint nfs_server
primary-a /mnt/primary01 192.168.100.20
secondary-a /mnt/secondary01 192.168.100.21
EOF

NFS 응답 확인 스크립트

NFS 장애 시 파일 작업이 hang될 수 있으므로 모든 파일 접근에 timeout을 겁니다. 테스트 파일은 숨김 파일로 만들고 즉시 삭제합니다.

#!/usr/bin/env bash
set -Eeuo pipefail

TARGET_FILE="${1:-/etc/cloudstack-monitor/nfs-mounts.conf}"
LOG_FILE="/var/log/cloudstack-nfs-monitor.log"
TIMEOUT_SEC=5
ALERT_TO="cloud-ops@example.com"

log() {
  printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" | tee -a "${LOG_FILE}"
}

alert() {
  local subject="$1"
  local body="$2"
  log "ALERT ${subject} ${body}"
  if command -v mailx >/dev/null 2>&1; then
    printf '%s\n' "${body}" | mailx -s "${subject}" "${ALERT_TO}" || true
  fi
}

check_mount() {
  local label="$1"
  local mountpoint="$2"
  local nfs_server="$3"
  local test_file="${mountpoint}/.cloudstack-nfs-monitor-$(hostname)-$$"

  if ! mountpoint -q "${mountpoint}"; then
    alert "CloudStack NFS not mounted: ${label}" "${mountpoint} is not a mountpoint"
    return 1
  fi

  if ! timeout "${TIMEOUT_SEC}" stat "${mountpoint}" >/dev/null 2>&1; then
    alert "CloudStack NFS stat timeout: ${label}" "stat timed out on ${mountpoint}"
    return 1
  fi

  if ! timeout "${TIMEOUT_SEC}" sh -c "printf test > '${test_file}' && sync -f '${test_file}' && rm -f '${test_file}'"; then
    alert "CloudStack NFS write timeout: ${label}" "write/remove failed on ${mountpoint} server=${nfs_server}"
    return 1
  fi

  log "OK nfs label=${label} mount=${mountpoint} server=${nfs_server}"
  return 0
}

overall=0
while read -r label mountpoint nfs_server; do
  [ -z "${label:-}" ] && continue
  [[ "${label}" =~ ^# ]] && continue
  check_mount "${label}" "${mountpoint}" "${nfs_server}" || overall=1
done < "${TARGET_FILE}"

exit "${overall}"

부가 진단 명령

장애가 감지되면 NFS 서버 접근, RPC, 커널 로그를 함께 봅니다.

rpcinfo -t 192.168.100.20 nfs
showmount -e 192.168.100.20
nfsstat -m
dmesg -T | egrep -i 'nfs|server not responding|not responding|timed out|stale file handle' | tail -n 80
journalctl -k -S -30min --no-pager | egrep -i 'nfs|blocked|I/O error|timeout'

cron 등록

sudo install -m 755 cloudstack-nfs-monitor.sh /usr/local/sbin/cloudstack-nfs-monitor.sh
sudo touch /var/log/cloudstack-nfs-monitor.log
sudo chmod 640 /var/log/cloudstack-nfs-monitor.log
* * * * * /usr/local/sbin/cloudstack-nfs-monitor.sh >/dev/null 2>&1

운영 주의사항

운영 중인 CloudStack storage pool에 직접 임의 파일을 많이 만들면 혼선을 줄 수 있습니다. 위 스크립트처럼 고정 prefix의 숨김 테스트 파일을 즉시 삭제하고, 가능하면 모니터링 전용 디렉터리를 NFS export 안에 따로 두는 것이 좋습니다. 반복 장애가 잡히면 CloudStack agent 로그, management-server 로그, 스토리지 서버의 NFS 로그를 같은 시간대 기준으로 대조합니다.

공식 문서

BGM EVER