GlusterFS 볼륨을 NFS-Ganesha 로 내보낼 때, 클라이언트가 특정 노드 IP 를 직접 바라보면 그 노드가 내려가는 순간 마운트가 멈춘다. 앞에 떠 있는 가상 IP 를 두고 살아 있는 노드가 그 IP 를 가져가게 만드는 것이 목적이다.
정석은 Pacemaker · Corosync 조합이고, 이 경우 ganesha-ha.sh 가 grace period 처리까지 함께 해 준다. keepalived 는 VRRP 로 IP 만 옮기는 훨씬 가벼운 방법이라 시험 환경이나 요구 수준이 낮은 구간에 쓸 만하다. 다만 잠금 상태는 옮겨지지 않는다는 점을 먼저 이해하고 써야 한다.
Ganesha 설정 자체와 Pacemaker 기반 구성은 아래 문서에 있다.
세 노드에 GlusterFS 와 Ganesha 가 올라가 있고, 같은 L2 구간에 가상 IP 를 하나 띄울 수 있어야 한다. VRRP 는 멀티캐스트(224.0.0.18) 를 쓰므로 노드가 서로 다른 서브넷에 있거나 스위치가 멀티캐스트를 막으면 동작하지 않는다. 클라우드 환경에서는 대부분 쓸 수 없다.
| 노드 | IP |
|---|---|
| gluster01 | 192.168.0.11 |
| gluster02 | 192.168.0.12 |
| gluster03 | 192.168.0.13 |
| 가상 IP | 192.168.7.1 |
Ganesha 는 세 노드 모두에서 같은 볼륨을 같은 Export_Id 와 Pseudo 로 내보내고 있어야 한다. 노드마다 설정이 다르면 IP 가 넘어간 뒤 클라이언트가 다른 경로를 보게 된다.
RHEL 계열에서는 배포판 저장소에 Ganesha 가 없거나 의존성이 맞지 않는 경우가 많다. EPEL 또는 CentOS Storage SIG(centos-release-gluster) 저장소를 쓴다.
# EPEL
dnf install -y epel-release
dnf install -y nfs-ganesha nfs-ganesha-gluster keepalived
# CentOS Stream / Rocky — Storage SIG
dnf install -y centos-release-gluster
dnf install -y nfs-ganesha nfs-ganesha-gluster keepalived
커널 NFS 서버와 포트가 겹치므로 반드시 내린다. GlusterFS 내장 NFS 도 꺼 둔다.
systemctl disable --now nfs-server
gluster volume set volume01 nfs.disable on
모든 노드에 같은 파일을 두고 priority 만 다르게 한다. state 는 전부 BACKUP 으로 두고 우선순위로 정하는 편이 부팅 순서에 덜 휘둘린다.
vrrp_script chk_ganesha {
script "/usr/bin/killall -0 ganesha.nfsd"
interval 2
weight -20
fall 2
rise 2
}
vrrp_instance VI_GANESHA {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass ${VRRP_AUTH_PASS}
}
virtual_ipaddress {
192.168.7.1/24 dev eth0
}
track_script {
chk_ganesha
}
}
systemctl enable --now keepalived
ip -4 addr show dev eth0 | grep 192.168.7.1
journalctl -u keepalived -f
설정에서 주의할 점이 몇 가지 있다.
weight 는 음수로 준다. 프로세스가 죽었을 때 우선순위를 깎아 다른 노드에 넘기는 것이 목적이다. 양수로 주면 정상일 때 가산되는 형태라 의도대로 동작하지 않는 경우가 생긴다.track_script 안에서 서비스를 재시작하지 않는다. VRRP 판정과 복구 동작을 한 스크립트에 섞으면 두 노드가 동시에 VIP 를 잡는 상태가 만들어질 수 있다. 재시작은 systemd 의 Restart=on-failure 에 맡긴다.virtual_router_id 는 같은 L2 에 있는 다른 VRRP 그룹과 겹치면 안 된다.nopreempt 를 주면 복구된 노드가 VIP 를 도로 뺏지 않는다. NFS 는 전환 자체가 비용이므로 불필요한 왕복을 막는 편이 낫다.showmount -e 192.168.7.1
mount -t nfs -o vers=4.1,hard,timeo=600,retrans=2 192.168.7.1:/volume01 /mnt/volume01
/etc/fstab 에 넣을 때는 _netdev 를 붙여 네트워크가 올라온 뒤 마운트되게 한다.
keepalived 는 IP 만 옮긴다. NFSv4 의 잠금과 열린 파일 상태는 서버 쪽 메모리와 복구 데이터베이스에 있으므로, VIP 를 넘겨받은 노드는 이전 노드가 관리하던 상태를 모른다. 클라이언트는 새 서버에 재연결하면서 잠금 복구를 시도하지만, 새 서버가 grace period 를 열어 주지 않으면 복구가 거부된다.
그래서 이 구성은 아래와 같은 성질을 갖는다.
Squash = No_root_squash 는 클라이언트 root 를 서버 root 로 그대로 통과시키므로 편리하지만, 그 클라이언트에서 root 를 얻은 사람이 공유 데이터 전체를 다룰 수 있게 된다. 워크로드가 요구하지 않으면 기본값인 root squash 로 둔다.