Profile picture

[Docker Swarm] 분산 파일 시스템 GlusterFS 도입하기

JaehyoJJAng2024년 04월 10일

▶︎ 개요

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

image


▶︎ 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 파일이 보이는지 확인하자.
image
정상적으로 동기화가 되고 있다.


▶︎ 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

Loading script...