▶︎ PersistentVolume
컨테이너를 재시작하게 되면 이전 컨테이너에서 생성된 내부 데이터는 전부 사라지게 된다. 그렇기 때문에 호스트 서버의 볼륨과 컨테이너 내부의 볼륨을 마운트하여 유지하기 위해 사용하는 것이 **PersistentVolume(=PV)**이다.
호스트 서버의 공간 일부를 PV 볼륨으로 할당하여 사용하는 것이 가장 간단하지만 이 경우 하나의 노드만 PV를 사용할 수 있기 때문에 애플리케이션의 수평 확장은 불가능하다.(=hostPath)
그렇다고 저장소 서비스를 가져다 쓰기에는 많이 부담스러운 상황이라면 **NFS(Network File System)**를 사용하여 한 번에 여러 노드의 접근을 가능하게 하는 nfs 타입의 PV를 사용하면 된다.
▶︎ NFS 서버 구성
- 모든 설치 작업은 Master Node에서 진행
- 리눅스 배포판 : Rocky
1. Rocky OS 환경에서 NFS 서버를 구성하기 위해서는 다음 패키지가 필요하다.
yum update -y
yum install -y nfs-utils rpcbind portmap
2. NFS 서버에서 공유할 마운트포인트 지정
mkdir /mnt/shared
chmod -R 777/mnt/shared
3. NFS 서비스 설정파일을 수정. 공유할 디렉토리 경로와 현재 사용하고 있는 서버 인스턴스의 서브넷 범위 지정
echo '/mnt/shared 192.168.56.0/24(rw,sync,no_subtree_check)' | tee -a /etc/exports
4. 설정을 적용하고 서비스 재시작
exportfs -a
systemctl enable --now nfs-server.service
▶︎ NFS 클라이언트 구성
- 워커 노드에서 진행
NFS 서버에 접속하는 노드에는 'nfs-utils' 패키지만 설치하면 된다.
▶︎ Manifest 작성
NFS 서버의 Private IP를 사용하여 PV
, PVC
를 작성 및 생성 해보자.
‣ PV 생성
nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-storage
labels:
type: nfs
spec:
capacity:
storage: 10Gi
accessModes: ["ReadWriteMany"]
nfs:
server: "192.168.56.30" # NFS servers' IP
path: /mnt/shared # NFS server's shared path
$ kubectl apply -f ./nfs-pv.yaml
‣ PVC 생성
nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-storage-claim
spec:
storageClassName: "" # 빈 문자열 줘야함 (중요)
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 3Gi
selector:
matchExpressions:
- key: type
operator: In
values:
- nfs
$ kubectl apply -f ./nfs-pvc.yaml
▶︎ NFS Volume 테스트
NFS 파일 공유가 정상적으로 처리되는지 확인하기 위해 간단하게 테스트해보자.
우선 nginx 이미지 기반의 Deployment를 배포해보자.
nginx-pod.yaml
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
labels:
role: web
spec:
ports:
- name: nginx-port
protocol: TCP
port: 80
targetPort: 80
selector:
role: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
selector:
matchLabels:
role: web
template:
metadata:
labels:
role: web
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- name: web-storage
mountPath: /usr/share/nginx/html/
volumes:
- name: web-storage
persistentVolumeClaim:
claimName: nfs-storage-claim # 위에서 생성한 PVC name 키 값 입력 (name: nfs-storage-claim)
kubectl apply -f ./nginx-pod.yaml
이제 NFS가 정상적으로 동작하는지 테스트해보자.
먼저 마스터 노드의 /mnt/shared 디렉토리에 index.html을 하나 새로 만들자.
$ echo '<h1>Hello! NFS is Success!</h1>' > /mnt/shared/index.html
그리고 web-svc 서비스의 CLUSTER-IP를 조회하자
$ kubectl get svc web-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-svc ClusterIP 10.98.149.103 <none> 80/TCP 7m11s
curl로 웹 페이지를 조사해보자.
$ curl -X GET 10.98.149.103:80
<h1>Hello! NFS is Success!</h1>
짜잔. 로컬에서 작성한 /mnt/shared/index.html 파일이 컨테이너에서 실시간으로 반영되는 것을 확인할 수 있었다!.
컨테이너의 마운트 경로를 /usr/share/nginx/html 로 잡았던 이유는 nginx 이미지의 기본 html을 읽어들이는 경로가 /usr/share/nginx/html 이었기 때문이다!