라즈베리파이 4를 활용한 NFS서버 구축 및 Kubernetes Persistent Volume으로 간단히 활용해보기

Hoplin·2023년 6월 28일
0
post-thumbnail

NFS : Network File System

NFS는 네트워크 상에서 다른 PC 혹은 서버의 파일 시스템을 mount 하여 공유하는것을 의미한다. 사용자는 원격 컴퓨터에 있는 파일 및 디렉토리에 액세스할 수 있도록 하는 일종의 분산 파일 시스템이다.

물론 NFS는 네트워크에 파일시스템을 유출시키므로 위험은 당연히 존재한다.

라즈베리파이4 NFS 설정

라즈베리파이4는 결국 NFS 서버, 즉 원격 컴퓨터가 된다. 라즈베리파이에 설치된 운영체제는 Raspbian OS이다.

sudo apt update

sudo apt upgrade
  1. NFS 서버 관련 패키지를 설치한다

    sudo apt install nfs-kernel-server -y
  2. 공유할 디렉토리를 생성해준다. 여기서는 /mnt디렉토리의 하위디렉토리 /share 하나를 만들겠다.(일반적으로 여러 기타 파일 시스템을 마운트 하는곳이 /mnt디렉토리이기 때문이다.

    sudo mkdir /mnt/share
  3. 라즈베리파이는 기본적으로 vim이 설치되어있지 않다. vim을 설치해주자

    sudo apt install vim
  4. /etc/exports파일을 vim을 통해 연다. /etc/exports 파일은 NFS 서비스를 설정할때 사용하는 파일이다. 서버가 클라이언트에 반출하는 모든 디렉토리를 표시한다.

    sudo vim /etc/exports
  5. 위에서 공유하기위해 만들었던 디렉토리를 접속허용할 주소, 옵션과 함께 명시해 주어야 한다. 기본적인 포맷은 아래를 따른다

    `반출할-디렉토리` `접속허용할ip 혹은 와일드카드`(`옵션`)

    옵션에는 아래와 같은것들이 있다.

    옵션의미
    ro읽기 전용으로 지정(기본값)
    rw읽기 및 쓰기 가능으로 지정
    root_squashNFS클라이언트에서 접근하는 root 사용자를 무시하고, nfsnobody로 매핑.일반사용자의 권한은 그대로 인정된다.
    no_root_squashNFS클라이언트에서 접근하는 root 사용자를 무시하지 않고 root로 인정
    all_squashroot, 일반사용자를 포함하여 권한을 nobody로 매핑
    no_subtree_check하위 디렉토리를 검사하지 못하도록 한다
    secure포트번호가 1024 이하인 요청만 허가할때 사용한다. 기본값
    insecuresecure의 반대이다
    sync변경사항이 안정적으로 저장된 경우에만 관련 요청에 응하도록 한다. 기본값
    async쓰기가 설정된 디스크 스토리지에 사용하면 유용하다.데이터 변경에 대해 비동기 처리가 가능하다
    no_wdelay쓰기 지연을 적용하지 않는다. NFS는 기본적으로 성능향상을 위해 쓰기 요청을 모아서 일괄처리한다. 이를 끄는 옵션이다.
    fsid공유 디렉토리에 대한 고유 식별자를 설정한다.이를 통해 서버는 어떤 디렉토리가 클라이언트와 공유되어야하는지 알 수 있다.fsid=0으로 설정하면 루트파일 시스템을 공유할 수 있다.(보안 취약점이 있으므로 신중히 고려해야한다)

    여기서는 아래와 같이 작성하였다. 접속허용 IP는 와일드 카드 *를 사용하였는데, 모든 IP애서 접속할 수 있음을 의미한다. 필요에 따라 IP를 지정할 수 있다.

    /mnt/share *(rw,sync,no_subtree_check,no_root_squash,no_wdelay,fsid=0)
  6. 변경한 NFS 설정을 적용하고 재시작해준다.

    sudo exportfs -a
    sudo service nfs-kernel-server restart
  7. rpc-statd를 시작해준다. statd는 시스템 장애시, NFS에서 파일 복구를 위해 제공하는 lockd(원격데이터에 대한 잠금 요청) 프로그램을 지원하는 도구로서, 클라이언트와 서버 상태를 모니터링하는 rpc 프로그램이다.

    systemctl start rpc-statd

로컬에 NFS 마운트하기

제대로 적용이 됐는지 확인해본다. 아래 예시는 모두 Mac OS 기준이다. 포맷은 아래와 같다

sudo mount -t nfs (nfs server IP):(nfs server 공유 디렉토리) (로컬 디렉토리)

필자의 라즈베리파이 내부 IP는 172.30.1.91이다. 각자 내부 IP는 다르므로 ifconfig를 통해 확인한다

sudo mount -t nfs 172.30.1.91:/mnt/share ~/nfs-test

그리고 b.txt라는 파일을 만들어본다.

라즈베리파이의 /mnt/share를 보면 b.txt가 잘 생성된것을 볼 수 있다.

이제 다시 unmount를 한다. unmount가 안되는 경우, 해당 디렉토리에 접근하고 있는 프로세스가 있는지 확인해 봐야한다.

sudo diskutil unmount ~/nfs-test

Kubernetes Persistent Volume으로 사용하기

위에서 만든 라즈베리파이 NFS를 통해 Kubernetes Persistent Volume으로 사용할 수 있다. 대표적으로 로컬디스크, temporary disk인 emptyDir, hostPath가 있다. 하지만 Kubernetes에서 Pod는 다른 호스트 머신에서 재시작되더라도 특정 Pod에 종속적인 데이터가 필요한 경우가 많다. 이 한계점을 극복하기 위해서 AWS EBS, Azure Disk, iSCSI와 같은 퍼블릿 클라우드, 표준 프로토콜 기반의 네트워크 스토리지를 사용할 수 있으며, NFS 또한 네트워크 스토리지 한 종류이다.

여기서는 NFS PV와 Pod의 연결을 해보는것이 주 목적이므로 이외 쿠버네티스 개념설명은 생략한다. Pod의 yaml은 아래와 같다.

주의할 점은 NFS를 사용하기 위해서는 Pod가 실행되는 각각의 Node에는 nfs 유틸리티가 설치되어있어야 한다

# Ubuntu
sudo apt install nfs-common -y

# CentOS
yum install nfs-utils -y

만약 유틸리티가 설치되지 않으면 아래와 같은 오류가 발생한다

kubernetes nfs ~~ you might need a /sbin/mount helper program
# nfs-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nfs-test
spec:
  volumes:
    - name: "nfs-data"
      nfs:
        server: 172.30.1.91
        path: "/mnt/share"
  containers:
    - name: api-server
      image: hoplin/simple-api
      resources:
        requests:
          cpu: "500m"
          memory: "300Mi"
        limits:
          cpu: "800m"
          memory: "600Mi"
      volumeMounts:
        - mountPath: "/api/nfs-mount-example"
          name: "nfs-data"
      livenessProbe:
        httpGet:
          path: /health
          port: 3000
        initialDelaySeconds: 5
        timeoutSeconds: 1
        periodSeconds: 10
        failureThreshold: 3
      ports:
        - containerPort: 3000
          name: http
          protocol: TCP

spec.volumes.nfs.server부분을 자신의 라즈베리파이 내부 IP로 바꿔준다. 이제 Pod를 실행시켜준다. 약간의 설명을 하자면, 해당 컨테이너 이미지는 필자가 예시로 만들어 놓은 이미지이며, (링크) NFS 테스트를 위해 /api/nfs-mount-example 디렉토리가 생성되어있다. /api/nfs-mount-example 디렉토리에 NFS와 연동할 것이다.

kubectl apply -f nfs-test-pod.yaml 

꽤 시간이 걸리니 기다리자(라즈베리파이 성능이 그렇게 좋지 않으며, 환경에 따라 네트워크도 영향을 미친다)

Pod가 잘 생성된것을 볼 수 있다. 하지만 정말 연결이 제대로 된것인지 확인해 봐야한다. 해당 Pod의 컨테이너 터미널에 접속해본다.

kubectl exec -it nfs-test -- bash

/api/nfs-mount-example디렉토리에 접속하면 앞서 생성한 a.txt, b.txt가 존재하는것을 볼 수 있다.

그리고 나서 c.txt를 생성하고 라즈베리파이에서도 생성된것으로 보이는지 확인해본다.

profile
더 나은 내일을 위해 오늘의 중괄호를 엽니다

0개의 댓글