목차

Kubernetes Volume - NFS

  • Kubernetes는 Storage Volume 정의를 통해 Pod의 Volume을 정의한다
  • Pod컨테이너 내에 저장된 파일은 별도 설정이 없으면 Host의 임시 디스크에 보관
    • Pod 삭제 및 재시작 시 임시 디스크의 데이터 함께 소실
    • 멀티 컨테이너 Pod는 내부 컨테이너 간 데이터 공유 수행 필요
    • Volume 추상화는 이러한 문제를 해결하는 매커니즘을 제공
    • Volume은 Pod.spec에 포함하여, Pod내 filesystem에 mount됨
      • Pod.spec → .spec.volumes 구문으로 볼륨기술 및 이름 지정
      • .spec.containers[*].volumeMounts. 컨테이너 내부 FS에 mount → df -h 확인
      • 데이터 공유 및 지속성, API 기능을 통한 데이터 이전효과 지원

임시 volume

  • Tomcat의 /usr/local/tomcat/logs 와 emptyDir 볼륨연결
  • emptyDir을 Logstash /mnt에 마운트 하여 Tomcat 로그 Elasticsearch App로 보냄
  • 로그를 보내기위한 공유 → 임시 볼륨처리

영구 volume

  • Elasticsearch App는 LogStash로 받은 데이터를 기록 분석 할 수 있음
  • 상태 저장데이터는 Pod가 비정상 종료가 되어 재시작 되더라도 보존되어야 함

이름설명
emptyDirPod가 생성될 때 생성되고 Pod가 삭제될 때 삭제
hostPathNode의 로컬 볼륨
awsElasticBlockStoreAWS EBS 볼륨
azureDiskMicrosoft Azure 볼륨
cephfsCeph 볼륨
cinder오픈스택 Cinder 볼륨
gcePoesistentDiskGCE 볼륨
gitRepoGit Repository의 콘텐츠를 생성 초기에 저장한 볼륨
iSCSIiSCSI 볼륨
NFSNFS(네트워크 파일시스템) 볼륨

#emptyDir
apiVersion: v1
kind: Pod
metadata:
  name: temp-pod1
spec:
  volumes:
  - name: temp-vol
    emptyDir: {}
  containers:
  - image: nginx:1.24.0
    name: temp-container1
    volumeMounts:
    - name: temp-vol
      mountPath: /mount1
  - image: nginx:1.24.0
    name: temp-container2
    volumeMounts:
    - name: temp-vol
      mountPath: /mount2
  • Pod 생성시 Podspec에 의해 Pod내부에 존재하는 Volume 생성
  • 임시 데이터(ephemeral Data)를 저장을 위한 빈디렉토리 제공
  • 동일 Pod내의 모든 컨테이너의 접근이 가능하면 내부 데이터 공유를 위해 사용 → Pod와 lifecycle이 같다
  • Pod를 실행하는 Node환경에 따라 성능 변화(HDD, SSD, Network Storage 등)
  • 디스크 대신 메모리 사용 가능(최대 2G)
#emptyDir Memory
...
spec:
  volumes:
  - name: memory-vol
    emptyDir:
      medium: Memory
      sizeLimit: 1Gi    # sizeLimit 미 설정 시 기본 2G로 설정 및 제한
  containers:
  ...

경고: HostPath 볼륨에는 많은 보안위험 있음 가능하면 HostPath 볼륨을 사용해야 하는 경우, 필요한 파일 또는 디렉토리만 범위를 지정하고 ReadOnly로 마운트 해야함 AdmissionPolicy를 사용하여 특정 디렉토리로 HostPath 엑세스를 제한하는 경우, readOnly 마운트 정책이 유효할려면 volumeMounts가 반드시 지정되야 한다.

  • Pod가 생성된 Node File System의 파일 및 디렉토리를 mount
  • 데이터가 특정 Node에 종속되어 Pod가 재생성될때 Node가 바뀌면 데이터를 읽지 못함
  • 단일 Node에 생성 테스트에 적합
  • Pod가 삭제 되어도 내용이 삭제 되지 않음 → Node에 귀속된 영구볼륨
설명
(빈 문자열)기본값. 이전버전과의 호환성을 위한 것, hostPath 볼륨은 마운트 전 검사 수행 안함
DirectoryOrCreate경로에 존재하지 않으면 Kublet이 가지고있는 동일한 그릅과 소유권,권한을 0755로 설정한 빈디렉토리 생성
Directory주어진 경로에 디렉토리 있어야함
FileOrCreate경로에 존재하지 않으면 Kublet이 가지고있는 동일한 그릅과 소유권,권한을 0644로 설정한 빈 파일 생성
File주어진 경로에 파일이 있어야함
Socket주어진 경로에 UNIX 소켓이 있어야함
CharDevice주어진 경로에 문자 디바이스가 있어야함
BlockDevice주어진 경로에 블록 디바이스가 있어야함
apiVersion: v1
kind: Pod
metadata:
  name: host-pod1
spec:
  nodeSelector:
    #노드 지정하여 접속하는 방법도 있음
    kubernetes.io/hostname: k8s-node1
  containers:
  - name: container
    image: nginx:1.24.0
    volumeMounts:
    - name: host-path
      mountPath: /mount1
  volumes:
  - name: host-path
    hostPath:
      path: /DATA/ubuntuConfig #Node에 마운트
      type: DirectoryOrCreate
  • 추가사항 - NFS 구성(노드간 디스크 공유)
  • 모든 노드에서 동일한 접근 가능
#공유하고자 하는 모든 노드에서 실행
$ sudo apt -y install nfs-kernel-server

$ sudo systemctl enable --now nfs-server

$ sudo systemctl restart nfs-server

$ sudo systemctl status nfs-server

$ sudo mkdir /data


#NFS server 디스크를 공유할 노드
kuber@k8s-master:/$ sudo mkdir /data #아래의 내용 추가
/data *(rw,sync,no_root_squash,no_subtree_check,insecure)

kuber@k8s-master:/$ sudo netstat -nlp | grep 2049 # NFS port open 확인 (2049)
tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN

kuber@k8s-master:/$ sudo chown -R kuber:kuber /data
#sudo chown -R 쿠버네티스:쿠버네티스그룹명 /data


#공유 받을 node
kuber@k8s-node1:/$ sudo mount -t nfs k8s-master:/data /data

kuber@k8s-node1:/$ df -h
....
k8s-master:/data   98G   15G   78G  16% /data

kuber@k8s-node1:/$ mount | grep nfs
nfsd on /proc/fs/nfsd type nfsd (rw,relatime)
k8s-master:/data on /data type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.10.10.91,local_lock=none,addr=10.10.10.90)

kuber@k8s-node1:/$ cd /data

kuber@k8s-node1:/data$ touch test.txt

#서버에서 파일 생성 됐는지 확인
kuber@k8s-master:/$ cd /data

kuber@k8s-master:/data$ ls
test.txt

사용

nfs-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nfs-nginx
spec:
  containers:
  - name: nfs-nginx
    image: nginx:1.24.0
    volumeMounts:
    - name: nfs-vol
      mountPath: /usr/share/nginx/html
  volumes:
  - name : nfs-vol
    nfs:
      path: /data
      server: 10.10.10.90 #공유한 노드 IP k8s-master:10.10.10.90