K8s 볼륨 실습 - 실제 응답 로그 모음

실습 과정에서 확인한 실제 명령어 실행 결과로그 출력을 정리한 참고 자료입니다. 05_01_쿠버네티스_볼륨_기초_실습_가이드


🚀 환경 설정 단계

minikube 클러스터 시작

$ minikube start
* Darwin 15.6.1 (arm64) 의 minikube v1.37.0
* 기존 프로필에 기반하여 qemu2 드라이버를 사용하는 중
* "minikube" 클러스터의 "minikube" primary control-plane 노드를 시작하는 중
* bridge CNI (Container Networking Interface) 를 구성하는 중 ...
* Kubernetes 구성 요소를 확인...
  - 이미지 gcr.io/k8s-minikube/storage-provisioner:v5 사용
* 애드온 활성화 : default-storageclass, storage-provisioner
 
  - Want kubectl v1.34.0? Try 'minikube kubectl -- get pods -A'
* 끝났습니다! kubectl이 "minikube" 클러스터와 "default" 네임스페이스를 기본적으로 사용하도록 구성되었습니다
! /usr/local/bin/kubectl is version 1.32.2, which may have incompatibilities with Kubernetes 1.34.0.

실습 디렉터리 생성

$ mkdir -p ~/k8s-volume-lab && cd ~/k8s-volume-lab && pwd
/Users/a1234/k8s-volume-lab

📦 emptyDir 기본 실습 결과

Pod 배포 및 상태 확인

$ kubectl apply -f pod-emptydir-basic.yaml
pod/emptydir-basic-pod created
 
$ kubectl get pods
NAME                          READY   STATUS    RESTARTS        AGE
deploy-hn-86c77db884-74dnd    1/1     Running   1 (3m40s ago)   3d2h
deploy-hn-86c77db884-nrw9g    1/1     Running   1 (3m40s ago)   3d2h
deploy-hn-86c77db884-zmxxd    1/1     Running   1 (3m40s ago)   3d2h
deploy-ip-66696bd655-4pjdb    1/1     Running   1 (3m40s ago)   3d2h
deploy-ip-66696bd655-m54fg    1/1     Running   1 (3m40s ago)   3d2h
deploy-ip-66696bd655-xfcp8    1/1     Running   1 (3m40s ago)   3d2h
deploy-nginx-8cd7dd64-6922s   1/1     Running   1 (3m40s ago)   3d2h
deploy-nginx-8cd7dd64-sxzxs   1/1     Running   1 (3m40s ago)   3d2h
deploy-nginx-8cd7dd64-xjg5q   1/1     Running   1 (3m40s ago)   3d2h
emptydir-basic-pod            2/2     Running   0               9s

✅ 확인 포인트: Pod가 2/2 Ready 상태 (writer + reader 컨테이너)

reader 컨테이너 로그 - 공유 데이터 확인

$ kubectl logs emptydir-basic-pod -c reader --tail=15
=== Reading shared data ===
Hello from writer
Mon Nov 17 07:08:58 UTC 2025
 
=== Reading shared data ===
Hello from writer
Mon Nov 17 07:08:58 UTC 2025
Hello from writer
Mon Nov 17 07:09:03 UTC 2025
Hello from writer
Mon Nov 17 07:09:08 UTC 2025

✅ 동작 확인: reader가 writer가 작성한 데이터를 실시간으로 읽음

공유 파일 직접 접근

$ kubectl exec emptydir-basic-pod -c reader -- cat /shared/data.txt
Hello from writer
Mon Nov 17 07:08:58 UTC 2025
Hello from writer
Mon Nov 17 07:09:03 UTC 2025
Hello from writer
Mon Nov 17 07:09:08 UTC 2025
Hello from writer
Mon Nov 17 07:09:13 UTC 2025
Hello from writer
Mon Nov 17 07:09:18 UTC 2025
Hello from writer
Mon Nov 17 07:09:23 UTC 2025

✅ 핵심 확인: 5초마다 새로운 데이터가 추가되고 있음


💾 emptyDir 메모리 버전 실습 결과

Pod 배포 및 IP 확인

$ kubectl apply -f pod-emptydir-memory.yaml
pod/emptydir-memory-pod created
 
$ kubectl get pod emptydir-memory-pod -o wide
NAME                  READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
emptydir-memory-pod   1/1     Running   0          14s   10.244.0.36   minikube   <none>           <none>

볼륨 마운트 상태 확인

$ kubectl exec emptydir-memory-pod -- df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                  16.9G      2.3G     13.7G  14% /
tmpfs                    64.0M         0     64.0M   0% /dev
shm                      64.0M         0     64.0M   0% /dev/shm
/dev/vdb1                16.9G      2.3G     13.7G  14% /dev/termination-log
/dev/vdb1                16.9G      2.3G     13.7G  14% /etc/resolv.conf
/dev/vdb1                16.9G      2.3G     13.7G  14% /etc/hostname
/dev/vdb1                16.9G      2.3G     13.7G  14% /etc/hosts
tmpfs                   100.0M         0    100.0M   0% /var/cache/nginx
/dev/vdb1                16.9G      2.3G     13.7G  14% /usr/share/nginx/html
tmpfs                     2.8G     12.0K      2.8G   0% /run/secrets/kubernetes.io/serviceaccount
tmpfs                     1.4G         0      1.4G   0% /proc/acpi
tmpfs                    64.0M         0     64.0M   0% /proc/interrupts
tmpfs                    64.0M         0     64.0M   0% /proc/keys
tmpfs                    64.0M         0     64.0M   0% /proc/timer_list
tmpfs                     1.4G         0      1.4G   0% /sys/firmware

✅ 메모리 볼륨 확인: tmpfs 100.0M at /var/cache/nginx

tmpfs 마운트 상세 정보

$ kubectl exec emptydir-memory-pod -- mount | grep tmpfs
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
tmpfs on /var/cache/nginx type tmpfs (rw,relatime,size=102400k,noswap)
tmpfs on /run/secrets/kubernetes.io/serviceaccount type tmpfs (ro,relatime,size=2986964k,noswap)
tmpfs on /proc/acpi type tmpfs (ro,relatime)
tmpfs on /proc/interrupts type tmpfs (rw,nosuid,size=65536k,mode=755)
tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755)
tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755)
tmpfs on /sys/firmware type tmpfs (ro,relatime)

✅ 핵심 확인: tmpfs on /var/cache/nginx type tmpfs (size=102400k,noswap)


🏠 hostPath 실습 결과

Deployment와 DaemonSet 배포

$ kubectl apply -f deploy-hostpath.yaml && kubectl apply -f ds-hostpath.yaml
deployment.apps/deploy-hostpath created
daemonset.apps/ds-hostpath created

Pod 분산 패턴 확인

$ kubectl get pods -o wide | grep -E "(deploy-hostpath|ds-hostpath)"
deploy-hostpath-69889dc4dd-7kp4k   1/1     Running   0               15s     10.244.0.42   minikube   <none>           <none>
deploy-hostpath-69889dc4dd-bftb5   1/1     Running   0               15s     10.244.0.44   minikube   <none>           <none>
deploy-hostpath-69889dc4dd-wnhdw   1/1     Running   0               15s     10.244.0.41   minikube   <none>           <none>
ds-hostpath-27wx2                  1/1     Running   0               15s     10.244.0.43   minikube   <none>           <none>

✅ 패턴 확인: Deployment 3개 vs DaemonSet 1개 (노드당)

Deployment Pod 로그 - 호스트 로그 접근

$ kubectl logs deploy-hostpath-69889dc4dd-7kp4k --tail=10
Checking host logs...
total 28
drwxr-xr-x    5 root     root          4096 Nov 13 08:34 .
drwxr-xr-x    1 root     root          4096 Nov 17 07:11 ..
drwxr-xr-x    2 root     root         12288 Nov 17 07:11 containers
drwx------    3 root     root          4096 Nov 13 08:34 crio
drwxr-x---   27 root     root          4096 Nov 17 07:11 pods

DaemonSet Pod 로그 - 동일한 호스트 로그 접근

$ kubectl logs ds-hostpath-27wx2 --tail=10
DaemonSet monitoring host logs...
total 28
drwxr-xr-x    5 root     root          4096 Nov 13 08:34 .
drwxr-xr-x    1 root     root          4096 Nov 17 07:11 ..
drwxr-xr-x    2 root     root         12288 Nov 17 07:11 containers
drwx------    3 root     root          4096 Nov 13 08:34 crio
drwxr-x---   27 root     root          4096 Nov 17 07:11 pods

✅ 중요 확인: 두 타입 모두 동일한 호스트 /var/log 디렉터리 접근

노드별 분산 패턴 비교

$ echo "=== 노드 수 확인 ===" && kubectl get nodes && echo -e "\n=== Deployment Pod 분산 ===" && kubectl get pods -l app=deploy-hostpath -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers && echo -e "\n=== DaemonSet Pod 분산 ===" && kubectl get pods -l app=ds-hostpath -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers
 
=== 노드 확인 ===
NAME       STATUS   ROLES           AGE     VERSION
minikube   Ready    control-plane   3d22h   v1.34.0
 
=== Deployment Pod 분산 ===
deploy-hostpath-69889dc4dd-7kp4k   minikube
deploy-hostpath-69889dc4dd-bftb5   minikube
deploy-hostpath-69889dc4dd-wnhdw   minikube
 
=== DaemonSet Pod 분산 ===
ds-hostpath-27wx2   minikube

✅ 핵심 차이:

  • Deployment: replicas 수만큼 생성 (3개)
  • DaemonSet: 노드당 정확히 1개씩 생성

🔍 실제 로그 수집 시나리오 결과

Nginx + 사이드카 로깅 Pod 배포

$ kubectl apply -f nginx-logging-pod.yaml
pod/nginx-with-logging created
 
$ kubectl get pod nginx-with-logging -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
nginx-with-logging   2/2     Running   0          31s   10.244.0.45   minikube   <none>           <none>

HTTP 트래픽 발생

$ kubectl get pod nginx-with-logging -o jsonpath='{.status.podIP}'
10.244.0.45
 
$ for i in {1..5}; do kubectl exec deploy-hostpath-69889dc4dd-7kp4k -- wget -qO- http://10.244.0.45/ > /dev/null && echo "Request $i sent"; sleep 1; done
Request 1 sent
Request 2 sent
Request 3 sent
Request 4 sent
Request 5 sent

사이드카 로그 수집 결과 확인

$ kubectl logs nginx-with-logging -c log-collector --tail=15
2025/11/17 07:14:02 [notice] 1#1: start worker processes
2025/11/17 07:14:02 [notice] 1#1: start worker process 31
2025/11/17 07:14:02 [notice] 1#1: start worker process 32
 
=== Nginx Access Logs ===
10.244.0.42 - - [17/Nov/2025:07:14:28 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:38 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:40 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:41 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:42 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
=== Nginx Error Logs ===
2025/11/17 07:14:02 [notice] 1#1: start worker processes
2025/11/17 07:14:02 [notice] 1#1: start worker process 31
2025/11/17 07:14:02 [notice] 1#1: start worker process 32

실제 로그 파일 직접 확인

$ kubectl exec nginx-with-logging -c log-collector -- cat /logs/access.log
10.244.0.42 - - [17/Nov/2025:07:14:28 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:38 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:40 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:41 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:42 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.244.0.42 - - [17/Nov/2025:07:14:43 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"

✅ 완벽한 동작:

  • Nginx가 HTTP 요청 처리 → 로그 생성
  • log-collector 사이드카가 실시간 로그 수집
  • emptyDir 볼륨을 통한 컨테이너간 로그 공유

🐛 실습 중 발생한 문제와 해결

1. sysnet4admin/sleepy:2.0 이미지 pull 실패

$ kubectl get pods -o wide -l app=deploy-hostpath
NAME                               READY   STATUS         RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
deploy-hostpath-85ddfcddf5-k26tj   0/1     ErrImagePull   0          10s   10.244.0.39   minikube   <none>           <none>

해결방법: busybox:1.35로 이미지 변경 + 명령어 추가

image: busybox:1.35
command: ["/bin/sh"]
args: ["-c", "while true; do echo 'Checking host logs...'; ls -la /host-log/ | head -10; sleep 30; done"]

2. 클러스터 연결 타임아웃

$ kubectl cluster-info
E1117 16:01:42.334795    2205 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://192.168.56.10:6443/api?timeout=32s\": dial tcp 192.168.56.10:6443: i/o timeout"

해결방법: minikube 재시작

$ minikube start

📊 실습 결과 요약 테이블

볼륨 타입테스트 시나리오결과 상태확인된 특성
emptyDirPod 내 컨테이너간 공유✅ 성공5초마다 데이터 기록/10초마다 읽기
emptyDir (Memory)tmpfs 메모리 볼륨✅ 성공100MB tmpfs 마운트 확인
hostPath (Deployment)3개 Pod가 호스트 로그 접근✅ 성공모든 Pod가 동일한 /var/log 접근
hostPath (DaemonSet)노드당 1개 Pod가 호스트 로그 접근✅ 성공노드별 정확히 1개 Pod 배치
사이드카 로깅Nginx + 로그수집 컨테이너✅ 성공실시간 HTTP 로그 수집 동작

🎯 핵심 학습 포인트

1. emptyDir 동작 패턴

  • 생명주기: Pod와 동일 (Pod 삭제 시 데이터 손실)
  • 공유 범위: 같은 Pod 내 모든 컨테이너
  • 성능: 로컬 스토리지 기반으로 빠름
  • 메모리 옵션: medium: Memory로 tmpfs 사용 가능

2. hostPath 주의사항

  • 노드 종속성: 특정 노드의 파일시스템에 의존
  • 보안 위험: 호스트 파일시스템 직접 노출
  • 이식성 부족: 다른 환경으로 이동 시 문제 가능성

3. 사이드카 패턴의 위력

  • 관심사 분리: 애플리케이션과 로그 처리 분리
  • 실시간 처리: 로그 생성과 동시에 수집/처리
  • 확장성: 로그 처리 로직 독립적 관리

4. Deployment vs DaemonSet

  • Deployment: 복제본 수 기반 배치
  • DaemonSet: 노드당 1개씩 보장된 배치
  • 사용 사례: 로그 수집은 DaemonSet이 더 적합

실습 완료일: 2025-11-17
총 소요 시간: 약 45분
확인된 Pod 수: 총 8개 (emptyDir 2개, hostPath 4개, 로깅 2개)