Rook-Ceph -> Host-Path -> Local-Storage -> NFS

쿠버네티스 스토리지 진화의 여정: Rook-Ceph부터 NFS까지 🚀

안녕하세요, 여러분! 오늘은 제가 물뮤(MoolMeow) 프로젝트에서 겪은 쿠버네티스 스토리지 시스템의 진화 과정을 공유하려고 해요. 이 여정은 마치 롤러코스터 같았어요! 🎢 

1️⃣ 첫 번째 선택: Rook-Ceph – “엔터프라이즈급 스토리지 솔루션” 🌟

처음에는 운영 환경에서 검증된 안정적인 스토리지 솔루션이 필요했습니다. 실무에서 많이 사용되고 있는 Rook-Ceph은 논리적인 선택이었죠.

Rook-Ceph을 선택한 실질적인 이유 ✨

  • 엔터프라이즈 환경에서 검증된 안정성과 신뢰성
  • 강력한 데이터 보호 기능과 데이터 일관성 보장
  • 스냅샷, 복제 등 고급 기능 기본 제공
  • 보안 기능이 탁월하고 감사(audit) 기능 지원
  • 자체 복구 메커니즘으로 장애 상황에서 데이터 안전성 확보

현실의 벽 🧱

$ helm install rook-ceph rook-release/rook-ceph
Error: failed to download "rook-release/rook-ceph"... resources exhausted...

Mac Mini(M2, 16GB RAM)에 Rook-Ceph를 설치하려니 리소스가 부족했어요. 메모리 사용량이 폭발적으로 증가하고, CPU는 계속 100%를 찍었죠. 게다가 설정이 너무 복잡했어요! 😱

# 수십 줄의 복잡한 YAML 설정...
rook-ceph:
  resources:
    requests:
      memory: "2Gi" # 이것만으로도 제 Mac Mini의 1/8을 사용!

결론: “이건 데이터센터용이지, 내 Mac Mini용이 아니었어…” 😓

2️⃣ 두 번째 선택: hostPath – “단순하게 가자!” 🏠

Rook-Ceph이 너무 무거워서 가장 단순한 방법인 hostPath로 전환했어요.

hostPath의 장점 👍

  • 설정이 매우 간단함
  • 추가 리소스가 거의 필요 없음
  • 호스트 시스템의 경로를 그대로 사용할 수 있음
apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/services/jenkins
    type: DirectoryOrCreate

정말 단순하고 쉽게 설정했어요! 그런데…

문제 발생 💥

Vagrant와 VirtualBox를 사용하면서 호스트(Mac)와 VM 간에 디렉토리를 공유하기 위해 VirtualBox 공유 폴더(vboxsf)를 사용했는데, 이게 화근이었어요!

Error: jenkins-0 pod failed: CrashLoopBackOff
$ kubectl logs jenkins-0
java.io.IOException: Invalid argument
  at java.base/sun.nio.ch.FileDispatcherImpl.force0(Native Method)
  at java.base/sun.nio.ch.FileDispatcherImpl.force(FileDispatcherImpl.java:77)
  at java.base/sun.nio.ch.FileChannelImpl.force(FileChannelImpl.java:376)

Jenkins가 fsync 시스템 호출을 사용하려 했는데, VirtualBox 공유 폴더는 이 기능을 제대로A 지원하지 않았던 거예요! 😡

3️⃣ 세 번째 선택: local-storage – “VM 내부에 저장하자” 🖥️

호스트와 VM 간 공유 폴더가 문제를 일으키니, VM 내부 경로를 사용하는 local-storage로 전환했어요.

local-storage 구성 ⚙️

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: /var/lib/jenkins-data  # VM 내부 경로로 변경!
    type: DirectoryOrCreate
  nodeAffinity:  # 특정 노드에 바인딩
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-master

Jenkins가 드디어 정상적으로 작동! 🎉 하지만 새로운 문제가 생겼어요…

새로운 문제 🤔

VM 내부에 저장하니 호스트(Mac)에서 데이터를 볼 수 없게 되었어요. 우리 프로젝트는 호스트에서 데이터를 바로 확인하고 수정해야 할 일이 많았거든요.

# 호스트에서
$ ls ~/Desktop/moolmeow/services/jenkins
# 아무것도 없음! 데이터는 VM 내부에만 있으니까요 😭

4️⃣ 최종 선택: NFS – “최고의 타협점” 🤝

실시간으로 호스트와 VM 간에 데이터를 공유하면서도 파일 시스템 기능을 모두 지원하는 방법이 필요했고, 그 해답은 NFS였어요!

NFS란 무엇인가요? 📚

NFS(Network File System)는 1984년 Sun Microsystems에서 개발한 분산 파일 시스템 프로토콜이에요. 거의 40년이 된 기술이지만, 여전히 널리 사용되는 이유가 있답니다!

  • 기본 개념: 원격 컴퓨터의 파일 시스템을 로컬 시스템에 마운트하여 마치 로컬 파일처럼 접근할 수 있게 해줍니다.
  • 작동 방식: RPC(Remote Procedure Call)를 기반으로 클라이언트-서버 모델로 동작해요.
  • 버전: 현재 주로 NFSv3, NFSv4가 사용되며, NFSv4.2까지 나왔어요.

NFS의 장점 🌟

  • 표준 Linux 파일 시스템 호환성: fsync, flock 등 모든 시스템 호출을 제대로 지원해요.
  • 네트워크 효율성: 최적화된 프로토콜로 네트워크를 통한 파일 접근이 효율적이에요.
  • 보안 옵션: NFSv4부터는 Kerberos 인증을 지원하여 보안성이 향상되었어요.
  • 성숙한 기술: 오랜 시간 검증된 안정적인 솔루션이에요.

NFS의 단점 ⚠️

  • 네트워크 의존성: 네트워크가 불안정하면 파일 시스템 접근도 영향을 받아요.
  • 성능 제한: 대량의 작은 파일을 다룰 때는 성능이 저하될 수 있어요.
  • 기본 설정의 보안: 기본 설정은 보안이 약할 수 있으니 추가 설정이 필요해요.

Mac에서 NFS 서버 설정 🍎

# /etc/exports 파일 편집
sudo vi /etc/exports

# 공유할 디렉토리 추가
/Users/myname/Desktop/moolmeow -network 192.168.56.0 -mask 255.255.255.0 -mapall=501:20

# NFS 서버 재시작
sudo nfsd restart

VM에서 NFS 마운트 🖥️

# NFS 클라이언트 설치
sudo apt-get install -y nfs-common

# NFS 마운트
sudo mount -t nfs 192.168.56.1:/Users/myname/Desktop/moolmeow/services /mnt/nfs/services

Kubernetes PV 수정 ⚙️

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs-storage
  nfs:
    server: 192.168.56.1
    path: /Users/myname/Desktop/moolmeow/services/jenkins

결론: 교훈과 성찰 🧠

이 여정에서 배운 점들이에요:

  1. 과도한 엔지니어링 피하기 🚫

    • 가정용 Mac Mini에 Rook-Ceph은 오버엔지니어링이었어요
    • 환경에 맞는 적절한 기술 선택이 중요해요
  2. 가상화 환경의 함정 조심하기 ⚠️

    • VirtualBox 공유 폴더는 편리하지만 표준 Linux 파일 시스템 기능을 모두 지원하지 않아요
    • Jenkins, MinIO 같은 애플리케이션은 fsync 같은 시스템 호출이 필요해요
  3. 실용적인 접근이 중요해요 💡

    • 최신 기술보다는 실제로 안정적으로 작동하는 솔루션을 선택하세요
    • NFS는 오래된 기술이지만, 여전히 Kubernetes에서 신뢰할 수 있는 스토리지 솔루션이에요
  4. 테스트가 필수예요 🧪

    • 실제로 애플리케이션을 실행해보기 전까지는 문제를 발견하기 어려워요
    • Jenkins가 없었다면 파일 시스템 호환성 문제를 뒤늦게 발견했을 거예요

물뮤 프로젝트의 스토리지 여정은 Rook-Ceph → hostPath → local-storage → NFS로 진화했어요. 마치 트렌디한 클라우드 기술에서 시작해 전통적이지만 신뢰할 수 있는 솔루션으로 회귀한 느낌이죠. 결국 가장 중요한 것은 화려한 기술이 아니라 실제로 작동하는 시스템이라는 걸 다시 한번 깨달았습니다. 🌈

여러분의 쿠버네티스 여정도 순탄하길 바라요! 질문이나 의견이 있으시면 댓글로 남겨주세요~ 🙌

#쿠버네티스 #스토리지 #HomeLabK8s #DevOps #NFS

The Evolution of Kubernetes Storage: From Rook-Ceph to NFS 🚀

Hello everyone! Today I want to share my journey with Kubernetes storage systems in the MoolMeow project. This journey was like a roller coaster! 🎢 

1️⃣ First Choice: Rook-Ceph – “Enterprise-grade Storage Solution” 🌟

Initially, I needed a storage solution that was proven in production environments. Rook-Ceph was a logical choice as it’s widely used in professional settings.

Practical Reasons for Choosing Rook-Ceph ✨

  • Proven reliability and stability in enterprise environments
  • Strong data protection features and consistency guarantees
  • Advanced features like snapshots and replication built-in
  • Excellent security features with audit capabilities
  • Self-healing mechanisms for data safety during failures

Reality Check 🧱

$ helm install rook-ceph rook-release/rook-ceph
Error: failed to download "rook-release/rook-ceph"... resources exhausted...

When I tried to install Rook-Ceph on my Mac Mini (M2, 16GB RAM), there weren’t enough resources. Memory usage exploded, and CPU constantly hit 100%. Plus, the configuration was incredibly complex! 😱

# Dozens of lines of complex YAML configuration...
rook-ceph:
  resources:
    requests:
      memory: "2Gi" # This alone uses 1/8 of my Mac Mini's memory!

The conclusion: “This is meant for data centers, not for my Mac Mini…” 😓

2️⃣ Second Choice: hostPath – “Let’s Keep It Simple!” 🏠

Since Rook-Ceph was too heavyweight, I switched to the simplest approach: hostPath.

Benefits of hostPath 👍

  • Extremely simple configuration
  • Almost no additional resources required
  • Uses host system paths directly
apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/services/jenkins
    type: DirectoryOrCreate

It was so simple and easy to set up! But then…

Problems Emerged 💥

While using Vagrant and VirtualBox, I used VirtualBox shared folders (vboxsf) to share directories between the host (Mac) and VM, and this became the root of the problem!

Error: jenkins-0 pod failed: CrashLoopBackOff
$ kubectl logs jenkins-0
java.io.IOException: Invalid argument
  at java.base/sun.nio.ch.FileDispatcherImpl.force0(Native Method)
  at java.base/sun.nio.ch.FileDispatcherImpl.force(FileDispatcherImpl.java:77)
  at java.base/sun.nio.ch.FileChannelImpl.force(FileChannelImpl.java:376)

Jenkins was trying to use the fsync system call, but VirtualBox shared folders don’t properly support this feature! 😡

3️⃣ Third Choice: local-storage – “Let’s Store Inside the VM” 🖥️

Since shared folders between host and VM were causing problems, I switched to local-storage using VM internal paths.

local-storage Configuration ⚙️

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: /var/lib/jenkins-data  # Changed to VM internal path!
    type: DirectoryOrCreate
  nodeAffinity:  # Binding to specific node
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-master

Jenkins finally worked properly! 🎉 But a new problem emerged…

New Problem 🤔

By storing inside the VM, I couldn’t see the data from the host (Mac). Our project often needed to check and modify data directly from the host.

# On the host
$ ls ~/Desktop/moolmeow/services/jenkins
# Nothing there! The data is only inside the VM 😭

4️⃣ Final Choice: NFS – “The Best Compromise” 🤝

I needed a way to share data between the host and VM in real-time while supporting all filesystem features, and NFS was the answer!

What is NFS? 📚

NFS (Network File System) is a distributed file system protocol developed by Sun Microsystems in 1984. Despite being almost 40 years old, there are good reasons it’s still widely used!

  • Basic Concept: It allows you to mount remote computer file systems locally, accessing them as if they were local files.
  • How It Works: It operates on a client-server model based on RPC (Remote Procedure Call).
  • Versions: Currently, NFSv3 and NFSv4 are commonly used, with NFSv4.2 being the latest.

Advantages of NFS 🌟

  • Standard Linux Filesystem Compatibility: Properly supports all system calls like fsync, flock.
  • Network Efficiency: Optimized protocol for efficient file access over networks.
  • Security Options: Since NFSv4, Kerberos authentication is supported for enhanced security.
  • Mature Technology: A time-tested and stable solution.

Disadvantages of NFS ⚠️

  • Network Dependency: File system access is affected if the network is unstable.
  • Performance Limitations: Performance may degrade when handling large numbers of small files.
  • Default Security: Default configuration may be less secure, requiring additional setup.

Setting up NFS Server on Mac 🍎

# Edit /etc/exports file
sudo vi /etc/exports

# Add shared directory
/Users/myname/Desktop/moolmeow -network 192.168.56.0 -mask 255.255.255.0 -mapall=501:20

# Restart NFS server
sudo nfsd restart

Mounting NFS on VM 🖥️

# Install NFS client
sudo apt-get install -y nfs-common

# Mount NFS
sudo mount -t nfs 192.168.56.1:/Users/myname/Desktop/moolmeow/services /mnt/nfs/services

Modifying Kubernetes PV ⚙️

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs-storage
  nfs:
    server: 192.168.56.1
    path: /Users/myname/Desktop/moolmeow/services/jenkins

Conclusion: Lessons Learned 🧠

Here are the lessons I learned from this journey:

  1. Avoid Overengineering 🚫

    • Rook-Ceph on a home Mac Mini was overengineering
    • Choose technology appropriate for your environment
  2. Beware of Virtualization Pitfalls ⚠️

    • VirtualBox shared folders are convenient but don’t support all standard Linux filesystem features
    • Applications like Jenkins and MinIO need system calls like fsync
  3. Practical Approaches Matter 💡

    • Choose solutions that actually work reliably over cutting-edge technology
    • NFS is an older technology but still a reliable storage solution for Kubernetes
  4. Testing is Essential 🧪

    • Problems are hard to detect until you actually run applications
    • Without Jenkins, we might have discovered filesystem compatibility issues much later

The storage journey of the MoolMeow project evolved from Rook-Ceph → hostPath → local-storage → NFS. It feels like we started with trendy cloud technology and returned to a traditional but reliable solution. In the end, the most important thing isn’t fancy technology, but a system that actually works. 🌈

Hope your Kubernetes journey goes smoothly! If you have any questions or comments, please leave them below! 🙌

#Kubernetes #Storage #HomeLabK8s #DevOps #NFS

답글 남기기