Why??
Kubernetes
환경에서는 우리가 사용하고 싶은 application
을 이미지화해서 쉽게 배포하고 관리할 수 있습니다.
하지만, Storage
에 대한 문제가 있는데요.
우리 컨테이너화해서 사용하고 있는 Pod에 쇼핑몰 홈페이지가 있다고 가정해봅시다.
우리는 쇼핑몰 홈페이지에서 등록하는 상품을 100개 등록했고, 해당 상품마다 이미지가 20개씩 들어있다고 해봅시다.
분산화한 개발이 아닐 경우, 우리는 해당 프로젝트가 있는 host의 어딘가에 저장을 하게됩니다. 예를 들면 /project/image
라는 폴더에 저장을 하겠죠.
하지만, 분산화시켜 사용 중 해당 Pod이 알 수 없는 이유 때문에 깨져 Pod이 내려갔다가 다시 생성되었다고 가정해 봅시다.
그러면 우리가 처음에 배포한 이미지를 바탕으로 쇼핑몰 홈페이지 프로젝트가 배포되기 때문에 우리가 작성해 두었던 상품 100개에 대한 각각의 이미지 20개들은 없는 상태로 운영이 될겁니다.
이를 방지하기 위해 Kubernetes
에서는 PV
, PVC
라는 개념을 사용합니다.
PV
PV
란 Persistent Volume
의 약자로 볼륨을 영구적으로 사용하는 것이죠.
볼륨을 영구적으로 사용한다는 것은 pod에서 생성한 데이터를 영구적으로 보관한다는 뜻입니다.
PVC
PVC
란 Persistent Volume Claim
의 약자로 볼륨을 영구적으로 사용할 곳에 요청을 보내는 정보입니다.
NFS
NFS
란 Network File System
의 약자로 네트워크를 통한 파일을 통신하는 것입니다.
예를 들면 우리는 samba
를 통해 smb
프로토콜을 사용해서 네트워크를 통해 공유폴더를 지정하고 binding시킬 수 있습니다.
이것을 가능하게 해주는 것이라고 생각하면 됩니다.
IBM의 문서에서는 다음과 같이 정의합니다.
- 서버가 반출한 파일 시스템을 개인용 컴퓨터가 마운트할 수 있도록 해주는 개인용 컴퓨터를 위한 프로그램
Setting
NFS 관련 패키지 설치
우선 가장 먼저 모든 노드에 NFS 설치를 해주어야 합니다.
단, 서버에 접근을 하는 노드들(worker)의 경우에는 nfs-common
만 설치하면 됩니다.
sudo apt-get update
sudo apt-get install -y nfs-common nfs-kernel-server rpcbind portmap
NFS 서버에서 공유할 디렉터리를 생성
이제 공유폴더를 생성하고 권한을 변경해주어야 합니다.
# /mnt 폴더로 이동
cd /mnt
# /mnt 폴더에 `share`폴더 생성
shdu mkdir share
# `share`폴더의 권한을 전체허용으로 변경
sudo chmod 777 share
NFS 서비스 설정파일 수정
공유할 디렉터리 경로와 현재 사용하고 있는 서버 인스턴스의 서브넷 범위를 지정합니다.
sudo echo '/mnt/share ${host-ip}/${subnet-range}(rw,sync,no_subtree_check)' >> /etc/exports
예를 들어 보겠습니다.
sudo echo '/mnt/share 172.26.0.0/16(rw,sync,no_subtree_check)' >> /etc/exports
작성한 내용을 확인해 보겠습니다.
아래 명령어 입력후 아래와 같이 나온다면 정상적으로 등록된 것입니다.
$ cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/mnt/share 172.26.0.0/16(rw,sync,no_subtree_check)
설정을 적용하고 재시작합니다.
sudo exportfs -a
sudo systemctl restart nfs-kernel-server
테스트 html 파일 생성
echo 'hello Persistent Volume!!' >> /mnt/share/index.html
pv.yaml 파일 생성
이제 Persistent Volume
을 생성하기 위해 파일을 생성해 주어야 합니다.
제가 작성한 예시로 예시를 보여드릴게요.
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
labels:
type: nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
server: ${nfs-server-ip} # nfs서버로 사용할 ip
path: /mnt/share
mountOptions:
- nfsvers=4.1 # nfsstat -s를 통해 버전을 확인해보자.
pvc.yaml
Persistent Volume
설정 파일을 생성했습니다.
이제 해당 Volume
으로 요청을 보낼 수 있는 Claim
파일을 생성할 차례입니다.
selector
하위의 matchExpresstions
의 설정으로 pv.yaml
파일의 meatadata
에서 labels
를 찾아 key: value
값으로 매칭시킵니다. 그리고 operator
로 그 관계를 정의하게 됩니다.
In
의 경우 무조건 해당 값과 일치해야한다고 선언하는 것입니다. 다음 문서를 통해 상세하게 알 수 있습니다. 참고
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc
spec:
storageClassName: "" # 공백으로 설정시 자동으로 default 잡아줍니다.
accessModes:
- ReadWriteMany
resources:
requests:
storage: 4Gi
selector:
matchExpressions:
- key: type
operator: In
values:
- nfs
nginx.yaml
테스트용 nginx.yaml 파일을 생성해 보겠습니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nfs-nginx
spec:
containers:
- name: nfs-nginx
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- name: nginx-storage
mountPath: "/usr/share/nginx/html"
volumes:
- name: nginx-storage
persistentVolumeClaim:
claimName: pvc
테스트
이제 테스트를 해보겠습니다. 위에서 작성한 .yaml
파일을 적용시켜 줍니다.
kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
kubectl apply -f nginx.yaml
이제 해당 Pod에 접속해서 파일이 온전해 존재하는게 보이는지 확인하면 됩니다.
kubectl exec -it ${pod-name} -- bash
# 접속후 해당 파일 읽기
cat /usr/share/nginx/html/index.html
위의 두 명령어 실행 후 우리가 처음에 작성한 hello Persistent Volume!!
가 나온다면 성공적으로 설치가 완료된 것입니다.
Issue
Pod의 status가 Pending상태로 지속되는 문제 발생(storage class관련 이슈)
pvc,yaml
파일을 생성할 때 설정한 storageClass
가 보일겁니다.
공식문서나 다른 글들을 보면 이 값을 공백(""
)으로 넣으면 디폴트로 자동으로 잡아준다고 적혀있는걸 확인할 수 있습니다.
바로~ 위의 과정을 진행했지만, Pod
이 Pending
상태로 지속되는 현상이 발생하였습니다.
로그를 확인해보니 pod 생성을 기다리는 중이라는 메시지만 나옵니다.
그래서 describe
를 통해 envent
를 확인해 보았습니다.
확인해보니 Persistent Volume
이 생성하는 과정에서 실패하는 문제가 발생.
kubectl get sc
위 명령어를 실행시켜보니 아무것도 나오지 않는겁니다...
문제는 바로... Storage Class
가 없어서 발생하는 문제였습니다.
디폴트로 자동으로 잡아주지만, 그마저 무엇인가 하나라도 있어야 가능했던 겁니다.
그래서 storage class
를 생성하고 해결하였습니다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
kubectl apply -f storage-class.yaml
kubectl get sc
정상적으로 생성된 모습을 확인할 수 있습니다.
kube@kube01:~$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) kubernetes.io/aws-ebs Delete Immediate false 167m
Pod의 상태가 ContainerCreating으로 지속되는 문제 발생
위의 문제로 Pending
상태에서는 벗어났습니다.
하지만, 바로 다음 문제에 봉착하고 말았죠.
이번엔 무한으로 컨테이너생성중... 이라는 메시지...
이 문제를 해결하기 위해 수많은 고민을 해본 결과 도출한 가능성은 바로!!!!!
'NFS가 통신을 해서 디스크를 마운트 시킬텐데, 접속하려는 노드에서도 NFS를 설치해야 하지 않을까??' 였습니다.
단순히 ip를 통해 알아서 가져올 수 있을 줄 알았던 생각이 무색하게 바로 설치를 진행... 바로 해결되었습니다.
필자의 경우에는 서버에서 설치한 패키지를 전부 설치하였지만, 나중에 찾아본 결과 서버로 접근하려는 컴퓨터의 경우에는 nfs-common
만 설치해도 가능하다는 것을 알았습니다.
그렇기 때문에 NFS 서버에 접속을 하려는 PC의 경우는 아래 명령어로 설치합니다.
sudo apt-get update
sudo apt-get install -y nfs-common
'Study > Kubernetes' 카테고리의 다른 글
kubernetes Control-plane(Master Node)도 일을 시켜보자!! (0) | 2024.06.23 |
---|---|
kubernetes 환경 구성하기(feat. cri-o, Utuntu 22.04, calico) (0) | 2024.06.23 |
Kubernetes 구성중 Swap Memory를 Off 해야하는 이유!! (0) | 2024.06.23 |
댓글