k8s_cloudwave: 볼륨

볼륨 왜 필요한가?

  • 기본 이미지 레이어 맨 위는 readonly
  • 컨테이너 실행하면 이미지 레이어 맨 위에 readwrite 레이어 생성됨 (이게 이미지 통해 컨테이너 run 해줌)
  • readwrite 레이어는 디스크에 존재하긴 함. 하지만 컨테이너가 종료되면 없어짐
  • 컨테이너 종료되면 데이터 다 사라짐
  • 그래서 외부 볼륨에 마운트해서 데이터 관리해야 함
  • 쿠버네티스에서 볼륨 설정할때 ReadOnly=true를 해놓으면 감시를 안하기에 효율이 올라감

볼륨 종류

EmptyDir

  • pod가 종료되면 영구적으로 삭제. 즉 pod와 Lifecycle이 동일
  • 그럼 왜쓰냐? 대규모 기반 sorting작업에서 공간 확보 위해서

HostPath

  • pod가 죽어도 데이터 살아있음
  • 상태가 유지되긴 하지만 pod는 항상 다른 노드로 이동 가능성이 존재
  • 뭔말이냐 즉, 만약 노드 1에 있던 pod가 죽고 노드 2에 pod가 생성되면 어뜩할거냐?
  • 그래서 이런 문제를 해결하기 위해 Persistent Volume이 존재

Persistent Volume

  • 외부의 볼륨을 가져와서 쿠버네티스에 붙여 사용
  • 디스크는 3가지로 나뉘어짐
    1. Block 디스크 (AWS EBS, RDS): 포멧이 안되어 있음, 여러 노드에서 쓰기 X
    2. NFS (AWS NFS): 포멧이 되어있음, 여러 노드에서 쓰기 O
    3. Object 디스크 (AWS S3):
      • Append Only임
      • 파일 수정 불가능
      • 파일 추가만 가능
      • 업데이트 X
      • Http/Https 프로토콜 사용
      • 청크 단위로 파일을 쪼개서 저장함 (그래서 큰 작업 연산에서 병렬 처리로 유리)
      • 파일 업데이트 할때마다 history를 저장

특별한 볼륨

  • ConfigMap Volume: 설정파일 및 환경 변수 보관 하는 볼륨
  • Secret Volume: 보안이 필요한 설정 파일이나 키를 보관하는 볼륨
  • 배포 편의를 위해 사용

볼륨 접근 모드

  • ReadWriteOnce: 한 노드만 읽을 수 있음
  • ReadOnlyMany: 여러 노드가 읽는것만 가능
  • ReadWriteMany: 여러 노드가 읽기, 쓰기가 가능
  • ReadWriteOncePod: 하나의 특정 pod에서만 읽고 쓰기가 가능

Empty 스토리지 실습

  • pod 안에 컨테이너 두개 생성(하나는 명언을 생성하는 컨테이너, 하나는 웹 서버 역할)
  • Emptydir 스토리지를 생성해서, 컨테이너 2개가 서로 다른 디렉토리에 마운트
  • 한놈은 htdocs에 명언을 가져다 write하고 한놈은 read로 읽고 서비스함

Empty 스토리지 특징

  1. 컨테이너간의 공유
  2. 성능 선택가능
  3. 연결 끊어지면 볼륨 삭제

LoadBalancer

  • 퍼블릭 클라우드 아닌 환경은 로드밸런서가 없다.
  • 로컬일때는 콘트롤러가 로드밸런서 환경을 제공 (로컬에서 컨트롤러란? LB Ingress 컨트롤러를 의미)
  • 로컬에있는 쿠버네티스는 컨트롤플레인을 제어가능
  • 클라우드에 있는 쿠버네티스는 컨트롤 플레인 제어 불가능
  • 로컬에서 LB는 쿠버네티스 밖에 노드 안에 생성됨 / 클라우드에서는 외부에서 LB가 생성됨

  • AWS로 쿠버네티스 로드밸런서를 실습할때는 ExternalIP 부분을 지워줘야한다. 그리고 annotation을 추가해줘야 함. 

  • 해당 내용을 LoadBalancer 생성 파일에 넣어줌

GitRepo 연결

git에 연동하려면 (init 컨테이너 방법)

- init 컨테이너를 하나 생성

- init 컨테이너를 empty dir로 git에서 clone을 받아

- 그리고 서비스 컨테이너가 empty dir을 마운트해서 사용

- init 컨테이너는 한번만 수행하고 종료

 

git에 연동하려면 (side-car 방법)

- side-car 컨테이너를 생성 (계속 떠있음)

- side-car 컨테이너가 empty dir 에git clone을 받고, 서비스 컨테이너가 emptydir에 마운트

- side-car 컨테이너는 계속 떠있어서 git Repo가 수정되면 다시 clone을 받아옴

- 외부에 물리적인 볼륨(ex: NFS)을 쿠버네티스가 사용하고 인지하기 위해 PV라는 객채가 반드시 필요

- 쿠버네티스의 디스크 볼륨은 PV라고 생각하면 됨. 그 뒤에 외부 디스크를 입맛에 맞게 Mapping 시키면 됨

- 중간에 PVC는 뭐냐? 요청서다. 

- disk같은 민감한 것들은 쿠버네티스 관리자가, 개발자는 pvc만 가능하도록 권한을 분리시키는 것이 안전하다.

- 개발자가 PVC로 요청서를 작성을 하면 PV가 있는지 찾고 있다면 할당해줌

- 볼륨과 pod와 연결이 끊어졌을때 어떻게 해결하겠냐? 그것이 바로 PersistentVolumeReclaimPolicy

- 데이터베이스는 Retain, 애플리케이션은 Delete을 하는 것이 일반적이다.

# EC2에 새 EBS 볼륨 생성 요청 (80GB)
aws ec2 create-volume --volume-type gp2 --size 80 --availability-zone ap-northeast-2a

# 조회
aws ec2 describe-volumes --filters Name=status,Values=available Name=availability-zone,Values=ap-northeast-2a

- aws에서는 40기가 단위로 컨트롤러가 역할을 함

- 따라서 40G 이상으로 볼륨을 생성할것이 권장됨

# pv.yml (AWS 생성하기)
apiVersion: v1
kind: PersistentVolume
metadata:
   name: mongodb-pv
spec:
  capacity:
    storage: 1Gi
  csi:
    driver: ebs.csi.aws.com
    fsType: ext4
    volumeHandle: vol-xxxxxxxxxxxxx
  accessModes:
  - ReadWriteOnce
  - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain
  nodeAffinity: 
    required: # 강제 조항임
      nodeSelectorTerms:
        - matchExpressions:
            - key: topology.ebs.csi.aws.com/zone
              operator: In
              values:
                - ap-northeast-2a # 이곳에만 볼륨 생성해라

- 존을 여러개 주고 노드 2개 생성하라고 하면, 노드 각각이 서로 다른 zone에 각각 생성됨 (가용성을 위해서) 

- pod가 뜰때 pv.yml에 써있는 nodeAffinity를 본다. 

- 같은 EBS 볼륨(PV)을 사용하는 Pod는 반드시 그 EBS가 있는 Zone의 노드에서 생성된다

# pvc.yml (PVC 생성하기)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc
spec:
  resources:
    requests:
      storage: 1Gi
  accessModes:
  - ReadWriteOnce, ReadOnlyMany
  storageClassName: ""

- Mondgodb pv라는 이름의 pv가 있어야 해당 PVC가 작동함


k8s의 Provider 방식 

- k8s는 Interface 규약만 만듦

- 외부 업체들이 해당 k8s의 규약을 보고 API 구현 

 

Devops의 기본 소양: AI의 파라미터란?

- AI의 가중치다. (20B = 20억개)

- 인간이 가지는 편견과 생각도 다 뉴런에 해당 가중치가 존재한다 (인간은 파라미터 최소 10조개. gpt의 최소 5배)

- 강사님 후배가 대학원 졸업하고 신입으로 Deepseek 들어갔는데 4억 받았다. 

- Deployment는 똑같은 pod 이름이 뜨면 PV가 동일했던 스토리지로 연결 (PV의 한곳에 pod의 이름이 들어가있기 때문)

- Statefulset은 (0,1,2) 이런식으로 pod 이름이 붙고 디스크도 다 따로 붙어있다. 고정되어있다.

- 여기서 마지막줄에 표현한 방식에서 SC는 뭐냐 Storage Class이다.

- 왜 SC가 필요하냐? 서비스마다 각각 서로 다른 성능의 디스크가 필요한데 그때마다 수작업 힘듦

- 그것을 SC가 해결. (AWS에서 어떤 볼륨 고를지 선택하면 그에 맞게 디스크가 자동 셋팅되는 그런느낌)


위 그림의 마지막줄 sc 생성하는거 실습

# sc.yml (SC 생성)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
# volumeBindingMode: Immediate
reclaimPolicy: Delete
parameters:
  csi.storage.k8s.io/fstype: ext4  #format하세요
  type: gp2
allowedTopologies:
  - matchLabelExpressions:
    - key: topology.ebs.csi.aws.com/zone
      values:
      - ap-northeast-2a
      - ap-northeast-2b
      - ap-northeast-2c

 

- Immediate: PVC를 생성하는 즉시 EBS가 아무 AZ나 랜덤으로 생성되며, 이후 Pod이 해당 AZ에 없는 노드에 스케줄되면 AZ mismatch 에러 발생할 수 있음 (아무 노드에 붙어도 상관 없는 스토리지일때만 사용, 바로 생성하기에 ↓방법보다 빠름)
- WaitForFirstConsumer: Pod이 먼저 스케줄된 후, 해당 노드의 AZ를 기준으로 EBS 생성 

# pvc.yml (pvc 생성)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
   name: mongodb-pvc
spec:
  storageClassName: fast
  resources:
    requests:
      storage: 2Gi
  accessModes:
    - ReadWriteOnce

 

'K8s' 카테고리의 다른 글

K8s_Cloudwave: CI/CD  (0) 2026.01.12
K8s_Cloudwave: ConfigMap & Secret  (0) 2026.01.12
K8s_Cloudwave: K8s 기본 리소스  (0) 2026.01.09
K8s_Cloudwave: Terraform 활용 EKS 생성  (0) 2026.01.09
K8s-Cloudwave: 로컬 K8s 생성  (0) 2026.01.08