볼륨 왜 필요한가?
- 기본 이미지 레이어 맨 위는 readonly
- 컨테이너 실행하면 이미지 레이어 맨 위에 readwrite 레이어 생성됨 (이게 이미지 통해 컨테이너 run 해줌)
- readwrite 레이어는 디스크에 존재하긴 함. 하지만 컨테이너가 종료되면 없어짐
- 컨테이너 종료되면 데이터 다 사라짐
- 그래서 외부 볼륨에 마운트해서 데이터 관리해야 함
- 쿠버네티스에서 볼륨 설정할때 ReadOnly=true를 해놓으면 감시를 안하기에 효율이 올라감
볼륨 종류
EmptyDir
- pod가 종료되면 영구적으로 삭제. 즉 pod와 Lifecycle이 동일
- 그럼 왜쓰냐? 대규모 기반 sorting작업에서 공간 확보 위해서
HostPath
- pod가 죽어도 데이터 살아있음
- 상태가 유지되긴 하지만 pod는 항상 다른 노드로 이동 가능성이 존재
- 뭔말이냐 즉, 만약 노드 1에 있던 pod가 죽고 노드 2에 pod가 생성되면 어뜩할거냐?
- 그래서 이런 문제를 해결하기 위해 Persistent Volume이 존재
Persistent Volume
- 외부의 볼륨을 가져와서 쿠버네티스에 붙여 사용
- 디스크는 3가지로 나뉘어짐
- Block 디스크 (AWS EBS, RDS): 포멧이 안되어 있음, 여러 노드에서 쓰기 X
- NFS (AWS NFS): 포멧이 되어있음, 여러 노드에서 쓰기 O
- 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 스토리지 특징
- 컨테이너간의 공유
- 성능 선택가능
- 연결 끊어지면 볼륨 삭제
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 |