MLOps/MinIO

Minio SNSD on Kubernetes (1/2)

ai-notes 2024. 7. 4. 17:04
반응형

 

2024.07.01 - [MLOps/Kubernetes] - 쿠버네티스 실행

 

쿠버네티스 실행

2024.06.17 - [MLOps/Kubernetes] - 쿠버네티스 개요 및 설치 쿠버네티스 개요 및 설치MinIO 서버를 구성하면서 최소 3개의 서버를 사용하게 될 예정인데, 향후 확장 및 관리의 편리성을 위해 쿠버네티스를

ainotes.tistory.com

 

쿠버네티스 실행에 이어, 이번에는 쿠버네티스 위에 SNSD (앞서 말한 File Server) 를 올렸던 작업에 대해 설명하려고 합니다. 이전글에서는 MNMD를 구현한다고 했으나, 속도 이슈가 있어서 SNSD 두 개를 구현하는 것으로 마무리 했습니다. 자세한 내용은 차근차근 풀어가도록 하겠습니다.

용어 정리

File Server : 문서 / 비교적 가벼운 단일 파일 (5GB 이내) 등을 저장할 서버

Data Server : 학습에 사용할 데이터를 저장할 서버

SNSD : Single Node Single Disk

SNMD : Single Node Multi Disk

MNMD : Multi Node Multi Disk


이번 minio 설치는 좀 더 날 것(?)으로 시도해보기 위해 helm이 아닌 yaml 파일로 설정하여 실행하였으며, Kubernetes에서 minio를 실행하기 위해 필요한 설정 파일로는 아래 4개가 있다.

사전 설정

kubectl create namespace minio-file

Data 서버와 구분하기 위해 namespace를 minio-file로 구분하였다.

.env file
MINIO_ROOT_USER=<Your ID>
MINIO_ROOT_PASSWORD=<Your Password>

kubectl create secret generic minio-secret --from-env-file=.env -n minio-file

minio에 접근할때 사용할 아이디와 비밀번호를 노출하지 않기 위해 .env에 위와 같이 설정하고, kubectl을 통해 key를 생성한다. 이를 이용하여 pod를 생성할 때, 아이디와 비밀번호를 노출하지 않을 수 있다.

PV(Persistent Volume)

PV는 실제 스토리지 리소스로, PVC(Persistent Volume Claim)에 의해 요청되고 바인딩 된다. PV는 다양한 유형(NFS, AWS EBS, GEC PD 등)을 지원하며, 데이터를 저장하기 위한 용도로 사용된다.

Docker에서 -v 옵션으로 Mount 할 때, ":" 앞부분의 local 폴더라고 생각하면 될 듯 하다.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-minio-folder
  namespace: minio-file
spec:
  capacity:
    storage: 900Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: minio-file
  local:
    path: /mnt/minio-file-folder
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - server1

 

이번 SNSD에 사용할 스토리지 용량은 900Gi으로 설정했다. 폴더 경로는 /mnt/minio-file-folder로 미리 링킹(ln -s) 해뒀다.

server1에서만 오픈을 할 예정이므로, nodeAffinity를 통해 server1이라는 호스트 이름을 가진 노드에서만 사용될 수 있도록 제한한다.
또한 Minio는 파드(Pod)가 삭제되더라도 데이터가 보존되어야 하므로, Retain 옵션을 사용한다.

PVC(Persistent Volume Claim)

PVC는 파드가 사용할(스토리지 리소스를 요청) PV에 대해 정의하는 것을 말한다. PVC는 적절한 PV에 바인딩되어 파드에 스토리지를 제공하는데, PV에 정의한 용량보다 크면 Bound 되지 않는다.

Statefulsets에서 volumeClaimTemplates와 volumeMounts 참조

Service

서비스는 파드 그룹에 대한 접근을 제어하는 리소스이다.

NodePort 서비스는 클러스터 외부에서의 접근을 가능하게 하고, Headless 서비스는 내부 DNS를 통해 파드들을 직접 주소로 사용할 수 있게 해준다.

apiVersion: v1
kind: Service
metadata:
  name: minio-nodeport
  namespace: minio-file
spec:
  type: NodePort
  ports:
  - port: 9001
    targetPort: 9001
    nodePort: 30000
    protocol: TCP
    name: console
  selector:
    app: minio-file
---
apiVersion: v1
kind: Service
metadata:
  name: minio-file
  namespace: minio-file
spec:
  clusterIP: None
  selector:
    app: minio-file
  ports:
  - port: 9001
    name: console
  - port: 9000
    name: minio

외부에서 접근할 Console은 NodePort를 통해 30000번 포트로 접근 가능하게 했다.
[Server1 IP]:30000으로 웹 UI에 접근할 수 있다.

Headless Service는 클러스터 IP 대신 DNS로 접근 가능하게 하는데, 후에 설명 예정이다.

Statefulset

Statefulset은 Deployment와 다르게 각각의 파드가 고유한 식별자와 네트워크 식별자를 가지며, 상태를 지속적으로 관리한다. Deployment는 Web서버, API 서버 등과 같이 상태를 저장하지 않고, 요청에 의한 처리를 수행하는 서비스들에 적합하며, Statefulset은 DB 서버와 같은 상태를 관리하는 서비스에 적합하다.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: minio-file
  namespace: minio-file
spec:
  serviceName: "minio-file"
  replicas: 1
  selector:
    matchLabels:
      app: minio-file
  template:
    metadata:
      labels:
        app: minio-file
    spec:
      containers:
      - name: minio-file
        image: minio/minio
        args:
        - server
        - /data
        - --console-address
        - ":9001"
        env:
        - name: MINIO_ROOT_USER
          valueFrom:
            secretKeyRef:
              name: minio-secret
              key: MINIO_ROOT_USER
        - name: MINIO_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: minio-secret
              key: MINIO_ROOT_PASSWORD
        ports:
        - containerPort: 9000
        - containerPort: 9001
        volumeMounts:
        - name: pvc
          mountPath: /data

  volumeClaimTemplates:
  - metadata:
      name: pvc
      labels:
        app: minio-file
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 900Gi
      storageClassName: minio-file

minio는 DB의 한 종류이므로, StatefulSet으로 설정하였다. SNSD를 가정했기 때문에 replicas는 1로 설정하였고, 사용하는 폴더도 /data 하나를 사용했다. 또한 앞서 설정한 secretKey를 통해 아이디와 비밀번호를 전달하게 했다.

volumeClaimTemplates에서는 storageClassName과 요구하는 storage양에 맞춰 가능한 PV에 자동으로 Bound 된다. 이때 설정한 metadata의 name으로 volumeMounts 단계에서 사용할 수 있다.

실행

이렇게 파일들을 준비하고 kubectl을 통해 차례대로 클러스터에 적용한다.

kubectl apply -f pv.yaml
kubectl apply -f service.yaml
kubectl apply -f statefulset.yaml

 

클러스터에 적용하면, 일정시간 이후 pod가 실행된다. pod가 running이 되면,

위와 같이 NodePort에서 설정한 Port 값으로 web console에 접근할 수 있게 된다.

 

마치며

앞서 백업에 대한 문제때문에 ' MNMD로 두개의 서버와 두개의 디스크(3T, 3T)를 묶어서 관리'한다 했으나, 업로드 및 다운로드 속도에 문제가 발생하여 SNSD 두 개를 구성하게 되었습니다. 속도 저하의 문제는 Single Node에 HDD를 사용하는 것이 원인이였고, 최종적으로는 SSD(Main), HDD(Backup)로 구성했습니다.

글이 길어지는 관계로 이에 대한 자세한 내용은 2편에서 마저 작성하는 것으로 하겠습니다.

 

반응형

'MLOps > MinIO' 카테고리의 다른 글

MinIO 부하 테스트 with NginX  (1) 2024.07.16
MinIO MNMD on Kubernetes with Prometheus  (0) 2024.07.09
Minio SNSD on Kubernetes (2/2)  (1) 2024.07.08
MinIO SNSD, SNMD  (2) 2024.06.11
MinIO 개요  (1) 2024.06.10