▶︎ 개요
GlusterFS를 사용하여 Docker Swarm 클러스터에서 공유 볼륨(Shared Volume)을 생성하고 관리한다는 것은 데이터의 영속성을 보장하는 좋은 방법 중 하나이다.
GlusterFS는 분산 파일 시스템이라고 하며,
여러 서버에 걸쳐 파일을 저장하는데, 이 때 서버 중 하나가 실패해도 데이터에 계속 접근할 수 있게 해주는 장점이 있다.
공유 볼륨이란 여러 노드가 네트워크를 통해 동일한 데이터에 접근할 수 있도록 하는 저장 공간이라고 보면 된다.
이런 볼륨은 다양한 물리적 위치에 있는 여러 서버에서 동일한 파일 시스템을 사용할 수 있게 해준다.
▶︎ 사전 준비
작업을 진행하기 전에 각 GlusterFS를 구성하고자 하는 서버의 호스트 파일을 수정해주자.
# /etc/hosts
...
192.168.219.128 swarm-manager
192.168.219.198 swarm-worker1
192.168.219.159 swarm-worker2
위처럼 호스트 파일을 변경하고 ping
이 정상적으로 나오는지 테스트
ping -c 1 swarm-manager
ping -c 1 swarm-worker1
ping -c 1 swarm-worker2
▶︎ GlusterFS 설치
모든 노드(매니저노드/워커노드)에 GlusterFS를 설치해주자.
sudo apt-get update -y
sudo apt-get install -y glusterfs-server
‣ GlusterFS 서비스 시작 및 활성화
각 노드에서 GlusterFS 서비스를 시작하고, 부팅 시 자동 시작되도록 설정하자.
sudo systemctl enable --now glusterd
‣ 클러스터 구성
매니저 노드에서 다른 노드들을 클러스터에 추가하자. 이 때에는 각 노드의 IP 주소나 호스트 이름 사용이 가능하다.
나는 사전준비에서 각 노드들에 대한 호스트 정보를 정의해줬으니 해당 내용대로 클러스터를 추가해보겠다.
sudo gluster peer probe swarm-worker1
sudo gluster peer probe swarm-worker2
# 상태 확인
sudo gluster peer status
# output
Number of Peers: 2
Hostname: swarm-worker1
Uuid: e9cec62a-31b1-493b-acc6-87db93625f68
State: Peer in Cluster (Connected)
Hostname: swarm-worker2
Uuid: 18fd9515-f3e9-490d-8459-b8edf9ba7d88
State: Peer in Cluster (Connected)
‣ 볼륨 생성
- 클러스터가 구성되면, 분산 볼륨 생성이 가능하다.
1. GlusterFS 디렉토리 생성
- GlusterFS를 사용할 디렉토리를 각 노드에서 생성해주자(매니저 노드 포함). 이 예제에서는
/gfsvolume/gv0
디렉토리로 생성 - GlusterFS에서
Brick Directory
는 GlusterFS 볼륨이 실제 데이터를 저장하는 디렉토리이다. - 브릭 디렉토리는 GlusterFS 볼륨을 구성하는 서버의 로컬 디스크 또는 파일 시스템에 위치하며, 해당 볼륨의 데이터가 저장되는 장소로 사용된다.
브릭 디렉토리를 저장할 디렉토리 생성
sudo mkdir -p /gfsvolume/gv0
2. GlusterFS Volume 생성
- GlusterFS Volume은 여러 서버 사이의 볼륨을 나타낸다. 각 서버의 디렉토리를 볼륨에 연결하여 GlusterFS를 연결하자.
예를 들어, swarm-manager
, swarm-worker1
, swarm-worker2
서버를 이용하여 볼륨을 생성하는 방법은 다음과 같다.
sudo gluster volume create myvolume replica 3 transport tcp \
swarm-manager:/gfsvolume/gv0 \
swarm-worker1:/gfsvolume/gv0 \
swarm-worker2:/gfsvolume/gv0
myvolume
: 볼륨 이름replica 3
: 데이터를 3개의 서버에 복제함.transport tcp
: GlusterFS가 TCP를 사용하여 통신하도록 설정
‣ 볼륨 시작
sudo gluster volume start myvolume
‣ 볼륨 상태 확인
sudo gluster volume status
▶︎ GlusterFS 스웜 서비스에 연결하기
GlusterFS 공유 볼륨을 Docker Swarm 서비스의 컨테이너에 마운트해보도록 하자.
이렇게 하면 서비스를 이루는 모든 컨테이너가 공유 볼륨에 저장된 데이터를 읽고 쓸 수 있게 된다.
Docker에서는 --mount
옵션을 사용하여 서비스를 생성할 때 볼륨을 마운트 할 수 있다.
‣ 기존 서비스 삭제
- 새로운 서비스를 만들거나 서비스가 없는 상태라면 생략
sudo docker stack rm my-web-app
‣ GlusterFS 볼륨 마운트
모든 노드에서 GlusterFS 공유 볼륨(/gfsvolume/gv0
)을 마운트해야 한다.
마운트 포인트가 설정되어 있지 않다면, 먼저 마운트 포인트를 생성해주도록 하자.
예를 들어, 마운트 포인트를 /mnt/gluster-volume
으로 한다면 아래 명령어를 실행해주면 된다.
sudo mkdir /mnt/gluster-volume
각 노드에서 실행한다. 즉 공유볼륨을 마운트할 마운트 포인트를 각 노드에 만들어 주는 것이다.
이제 볼륨을 마운트 한다.
설정한 볼륨 이름(myvolume
)과 클러스터의 노드 IP가 필요하다.
아래 명령어를 모든 노드에서 실행한다. 각 노드에서 GlusterFS 볼륨을 마운트 한 후에는, 해당 노드에서 실행되는 Docker 컨테이너가 로컬 파일 시스템을 통해 마운트된 볼륨에 접근 가능해진다.
# swarm-manager 에서 진행
sudo mount -t glusterfs swarm-manager:/myvolume /mnt/gluster-volume
# swarm-worer1 에서 진행
sudo mount -t glusterfs swarm-worker1:/myvolume /mnt/gluster-volume
# swarm-worer2 에서 진행
sudo mount -t glusterfs swarm-worker2:/myvolume /mnt/gluster-volume
마운트가 성공적으로 되었는지 확인해보자.
mount | grep 'glusterfs'
# swarm-manager
swarm-manager:/myvolume on /mnt/gluster-volume type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)
# swarm-worker1
swarm-worker1:/myvolume on /mnt/gluster-volume type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)
# swarm-worker2
swarm-worker2:/myvolume on /mnt/gluster-volume type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)
‣ Swarm 서비스와 연결
이제 Docker Swarm 서비스를 생성하면서 GlusterFS 볼륨을 마운트할 수 있다.
Docker Swarm은 기본적으로 GlusterFS와 같은 외부 파일 시스템을 직접 마운트하지 않으므로, 볼륨 마운트는 컨테이너 시작 시 호스트 경로를 기반으로 수행된다.
아래 명령어를 통해 각 컨테이너의 /usr/share/nginx/html
디렉토리에 GlusterFS 공유 볼륨(/mnt/gluster-volume
)을 마운트 한다. 이는 nginx가 호스팅할 정적 파일들이 GlusterFS를 통해 관리되고 공유 될 수 있도록 한 것이다.
sudo docker service create \
--name nginx-service \
--replicas 3 \
--mount type=bind,src=/mnt/gluster-volume,dst=/usr/share/nginx/html \
--publish published=80,target=80 \
nginx:latest
‣ 데이터 쓰기 및 동기화 테스트
이제 마지막으로 클라이언트에서 데이터가 올바르게 동기화되는지 테스트 하면 된다.
먼저, 하나의 노드에서 /mnt/gluster-volume
에 데이터를 써보고, 다른 노드에서도 이 데이터가 보이는지 확인하여
동기화가 정상적인지 검증해볼 수 있다.
# 매니저 노드에서 GlusterFS 볼륨에 테스트 파일을 생성
echo "Test GFS" | sudo tee /mnt/gluster-volume/test-gfs.txt
다른 노드(예: swarm-worker1
, swarm-worker2
)에서 /mnt/gluster-volume/test-gfs.txt
파일이 보이는지 확인하자.
정상적으로 동기화가 되고 있다.
▶︎ Clean up
1. volume 삭제
sudo gluster volume stop <volume-name> force
sudo gluster volume delete <volume-name>
2. 잔여 메타데이터 삭제
sudo rm -rf /var/lib/glusterd/vols/*
# 모든 워커노드에서 위에서 생성한 디렉토리 볼륨 삭제
sudo rm -rf /myContainers/web
3. 볼륨 정보 확인
sudo gluster volume info