주녁, DevNote
article thumbnail

개요

On-premise에서 kubernetes(= k8s) 환경을 직접 구성해보며 학습하는 Hands On 시리즈입니다. 

목표

  • 쿠버네티스 클러스터 내 공유 디렉토리를 사용하기 위한 NFS(Network File System) 서버 설정
  • PV, PVC, NFS, StorageClass의 관계를 이해한다.

여정

PV와 PVC의 관계

쿠버네티스는 하나 이상의 컨테이너를 포함하는 Pod를 최소 단위로 동작한다.

이러한 Pod가 데이터를 저장하는 공간이 PV(Persistent Volume)이다.

 

하지만, 한 볼륨을 공유하거나, 다른 볼륨으로 변경해야 할 경우가 생긴다면 어떻게 해야할까?

PVC(Persistent Volume Claim)이라는 리소스가 이를 해결해준다.

Pod와 PV 간의 연결을 정의하여 PV가 제 역할을 할 수 있게 해준다.

 

PVC와 PV의 역할

어떻게 이런게 가능할까?

바로 PV와 PVC가 그 역할을 추상화했기 때문이다. (쿠버네티스는 모든 것이 추상화다!)

어떤 기기든지 데이터를 저장하는 역할(PV), 저장 위치를 알려주는 역할(PVC)만 하면 되도록 만들어졌다.

 

따라서 위 관계도처럼 PV를 Local에서 다른 서버, 클라우드 등으로 쉽게 변경할 수 있다.

여기서 등장하는 NFS(Network File System)는 네트워크로 파일을 공유하는 파일 시스템이다.

(물론, 쿠버네티스 이전부터 존재하던 개념이다.)

 

이번 시간에는 NFS를 설치하고 PV와 PVC를 이용해서 이를 연결해보도록 할 것이다.


마스터 서버

# 마스터 서버에서
# CentOS 7에 NFS 설치
sudo yum -y install nfs-utils

# Ubuntu
sudo apt install nfs-kernel-server

# NFS 서버 기동
systemctl start nfs-server

# 설치 확인
systemctl status nfs-server
# 마스터 서버에서 진행
# 공유 디렉토리 지정
sudo mkdir ~/nfs4share

# /etc/exports : NFS가 공유하는 디렉토리와 권한 설정 파일
sudo vi /etc/exports

# 맨 아래줄에 <디렉토리 경로> <IP>(<권한>) 항목 추가
# 권한 삽입 시 띄어쓰기 하지말것 (ro, rw) X → (ro,rw) O
~/nfs4share *(rw,sync,no_root_squash) # 모든 IP에 대해 권한 적용

# 서비스 재시작
sudo systemctl restart nfs-server

# 권한 적용 확인
sudo exportfs -v
showmount -e
공유 옵션(참고)

ro : 읽기 권한 부여 한다.

rw : 읽기 쓰기 권한 부여 한다.

root_squash : 클라이언트에서 root를 서버상의 nobody 계정으로 매핑한다.

no_root_squash : 클라이언트 및 서버 모두 root 계정 사용한다.

sync : 파일시스템이 변경되면 즉시 동기화한다.

all_squash : root 계정이 아닌 다른 계정도 사용 할  수 있게 한다.

 


클라이언트

# 클라이언트에서
rpm -qa | grep nfs
sudo yum -y install nfs-utils
# 클라이언트에서 진행
# 서버와 마운트할 디렉토리 생성
mkdir /data/nfs

# 마운트
sudo mount -t nfs ${서버 IP}:/${서버 공유 디렉토리} /${클라이언트 마운트 위치}

# 재부팅 시 자동 NFS 설정 (맨 아래줄에 추가)
# <file system>    <dir>       <type>   <options>   <dump>	<pass>
sudo vi /etc/fstab
...
${서버 IP}:/${서버 공유 디렉토리}   /${클라이언트 마운트 위치}   nfs   defaults   0 0

# 마운트 확인
df

StorageClass 설치(마스터 서버)

StorageClass는 Cloud 환경에서 PV가 요구하는 조건에 맞게 동적으로 Volume을 생성해주는 프로비저닝 방식이다.즉, PV가 Volume의 크기, SSD 여부, FileSystem Type, Zone 등을 지정하면 그에 맞는 Volume을 생성해준다.(순서상으로 PVC 다음에 동작한다.)

 

설치는 아래 항목을 반드시 지켜서 작성해야 동작한다.

  • --set 옵션에 /etc/exports 에 no_root_squash 옵션을 포함한 NFS 공유 디렉토리 위치 필요
  • 각 노드들에 NFS client 설치(참고)
  • 설치 - 마스터 노드
# StorageClass 설치
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
 --set nfs.server=${NFS 서버 IP} \
 --set nfs.path=${NFS 공유 디렉토리 위치} \
 --set storageClass.name=nfs \
 --set storageClass.defaultClass=true

# 설치 확인
kubectl get storageclasses.storage.k8s.io

리소스 작성

# hello-Deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      volumes:
        - name: app-storage
          persistentVolumeClaim:
                claimName: nfs-storage-claim
      containers:
        - name: hello-world
          image: gcr.io/google-samples/kubernetes-bootcamp:v1
          volumeMounts:
            - mountPath: "/app"
              name: app-storage
          ports:
            - containerPort: 80
# nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-storage-claim
spec:
  storageClassName: "" # 빈 문자열
  accessModes: ["ReadWriteOnce"] # 동시에 한 노드만 읽고 쓸수 있다.(PV와 동일하게 설정)
  resources:
    requests:
      storage: 4Gi
# volumeName: mongo-pv # 직접 PV를 지정할 수도 있다.
  selector:
    matchExpressions:
      - key: type
        operator: In
        values:
          - nfs
# nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-storage
  labels:
    type: nfs # 라벨 지정을 하지 않는다면 설정하지 않아도 된다.
spec:
  capacity:
    storage: 10Gi
  accessModes: ["ReadWriteOnce"] # 한 Pod만 읽고 쓸수 있다.
  persistentVolumeReclaimPolicy: Retain # 한번 연결이 끊어진 PVC와는 수동연결만 허용
  nfs:
    server: 211.39.140.43
    path: /home/nfs4share # NFS server's shared path

결과 확인

# 실행중인 Pod에 접속
kubectl exec -it <hello-world가 실행중인 Pod 이름> /bin/bash

# Volume Mount 디렉토리를 확인
cd /app
ls

Q&A

  • 마운트를 해제하고 싶어요
# 클라이언트에서 

# 자동등록된 마운트 위치 해제
# 등록했던 경로 삭제
vi /etc/fstab

# 해당 경로에 접근중인 프로세스 확인
fuser -m ${mount 경로}

# 없다면 마운트 해제
umount ${mount 경로}

 


마무리

오늘은 Pod가 사용하는 PV와 이를 연결해주는 PVC의 개념에 대해서 학습하였다.

또한, NFS를 이용해서 이를 간단하게 사용하는 실습도 진행하였다.

 

다음 시간에는 네트워크를 연결하는 Service와 핵심 리소스인 Ingress에 대해 학습해보자


참고자료

[Kubernetes기반 CI/CD환경설정 시리즈] 01. NFS 서버 구성 — 도움 안되는 개발 블로그 (tistory.com)

[kubernetes] Volume vs Persistent Volume vs Storage Class : 네이버 블로그 (naver.com)

profile

주녁, DevNote

@junwork

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!