본문 바로가기
Kubernetes/Storage

MinIO - Distributed Mode

by 여행을 떠나자! 2021. 11. 11.

1. 개요

- MinIO?

   ✓ Amazon S3와 호환하는 오브젝트 스토리지를 제공하는 오픈소스 소프트웨어이다.

   ✓ MinIO는 Standalone(Single), Distributed 모드로 구성할 수 있다. 

   ✓ Kubernetes, docker, OS (linux, macOS, Windows)등 다양한 운영 환경을 지원한다. 

 

- MinIO Distributed 모드

   ✓ 분산 모드에서는 1개 이상의 인스턴스(서버)가 관리하는 최소 4개 이상의 디스크/볼륨으로 구성한다.

   ✓ 분산 모드에서는 모든 서버가 엔드포인트가 되기 때문에 아무 서버에 접속하여 사용할 수 있으며, 로드 밸랜서 사용을 권고한다.

   ✓ Erasure coding으로 데이터 중복 허용 및 가용성을 지원한다.

        Erasure Coding은 파일을 N개 블록으로 나누면서 M개의 Parity 블록을 생성하여 Fault-tolerance를 보장하는 방식

        MINIO_STORAGE_CLASS_STANDARD 환경 변수로 parity blocks 수를 설정하며 기본값은 4이다.

        1개 노드에 16개 1TB 디스크로 구성해서 배포한 경우 erasure code parity별 결과는 다음과 같다.

https://docs.min.io/minio/baremetal/concepts/erasure-coding.html#id1

       Eraure Code Calulator를 사용하면 Erasure code stripe size/parity별 사용 용량과 장애 허용 범위를 쉽게 산정할 수 있다.

   ✓ 볼륨 사이즈가 상이할 경우는 최소 사이즈를 기준으로 사용되며, 나머지 공간들은 버려진다.

   ✓ 최적의 성능을 내기 위해서 JBOD(Just a bunch of disks), xfs를 권고한다.

   ✓ 권고하는 Linux OS는 RHEL8+ 또는 Ubuntu 18.04+이다.

https://narbeh.org/blog/wp-content/uploads/2021/01/Architecture-diagram_distributed_nm-2.png

 

 

2. 환경

- MinOS 2021-11-09T03:21:45Z

- MicIO Client (mc) RELEASE.2021-11-05T10-05-06Z

- HAproxy 2.0.14

- CentOS Linux release 7.8.2003 (Core)

 

- 용도

   설치할 MinIO는 개발용으로 사용 중인 Kubernetes를 Velero를 이용하여 백업할 때 저장소로 사용하고자 한다. 

- 서버/디스크 구성

   MinIO를 Kubernetes에 구성할 경우 장애 발생 시 복구로 사용할 수 없을 수 있기 때문에 별도로 구성하였다.

   서버 2대에 각각 SSD 1개를 LV(Logical volume) 2개 생성하여 구성하였다.

[root@iap12 ~]# lsblk /dev/sdc
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sdc               8:32   0  3.5T  0 disk
└─sdc1            8:33   0  3.5T  0 part
  ├─vg0-data_01 253:4    0  1.8T  0 lvm  /data_01
  └─vg0-data_02 253:5    0  1.8T  0 lvm  /data_02
[root@iap12 ~]#

- 네트워크 구성

   L4 대신 keepalived / haproxy를 사용하여 로드 밸런싱 하였다. 참고 문서: keepalived, haproxy for K8s

   

 

3. 분산 환경의 MinIO Server 구성

- 참고: https://docs.min.io/minio/baremetal/installation/deploy-minio-distributed.html

 

a. 사전 작업

- 호스트 명

   ✓ MinIO requires using expansion notation {x...y} to denote a sequential series of MinIO hosts when creating a server pool.

   ✓ 사용 호스트 명 : minio-{1...2}.acp.kt.co.kr

   ✓ MinIO server에서 사용되는 호스트 명을 DNS에 등록하지 않고 MinIO server가 설치되는 서버의 /etc/hosts에 등록하였다.

# cat /etc/hosts
...
# for MinIO
14.52.244.216 minio-1.acp.kt.co.kr
14.52.244.217 minio-2.acp.kt.co.kr
#

   

- 볼륨 명

   ✓ MinIO requires using expansion notation {x...y} to denote a sequential series of disks when creating a server pool.

   ✓사용 볼륨 명:  data_0{0...1}

 

b. Minio Server 설치

 

$ wget https://dl.min.io/server/minio/release/linux-amd64/minio.rpm
...
# rpm -ivh minio.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:minio-0:20211109032145.0.0-1     ################################# [100%]
#
# rpm -ql minio
/etc/systemd/system/minio.service
/usr/local/bin/minio
# minio --version
minio version RELEASE.2021-11-09T03-21-45Z
#

 

c. 계정 생성 및 볼륨 소유권 변경

- MinIO Server가 실행 시 사용할 사용자명과 그룹명을 minio-user에서 minio로 변경한다.

- MinIO Server가 사용할 볼륨의 소유자를 변경한다. 

# vi /etc/systemd/system/minio.service 
...
User=minio
Group=minio
...
#
# groupadd minio
# useradd -r -m -g minio -d /home/minio -s /bin/bash minio
# chown minio:minio /data_01 /data_02
#

 

d. MinIO 설정 파일 생성

- MinIO Server가 실행 시 사용할 환경 변수들을 정의한다.

   분산 모드로 운영하고자 할 경우 MINIO_VOLUMES 변수를 설정하면 된다. (서버, 볼륨 정보 설정)

- MinIO Sever가 실행되는 서버마다 동일하게 설정한다.

- MINIO_SERVER_URL 변수를 설정한 경우 Console 로그인 시 에러가 발생되어 설정하지 않았다.

- 환경 변수 

  https://docs.min.io/minio/baremetal/reference/minio-server/minio-server.html#environment-variables

# vi /etc/default/minio
# Set the hosts and volumes MinIO uses at startup
# The command uses MinIO expansion notation {x...y} to denote a
# sequential series.
MINIO_VOLUMES="https://minio-{1...2}.acp.kt.co.kr/data_0{1...2}/minio"

# Set all MinIO server options
#
# The following explicitly sets the MinIO Console listen address to
# port 9001 on all network interfaces. The default behavior is dynamic
# port selection.
MINIO_OPTS="--address :9000 --console-address :9001"

# Set the root username. This user has unrestricted permissions to
# perform S3 and administrative API operations on any resource in the
# deployment.
#
# Defer to your organizations requirements for superadmin user name.
MINIO_ROOT_USER=minioadmin

# Set the root password
#
# Use a long, random, unique string that meets your organizations
# requirements for passwords.
MINIO_ROOT_PASSWORD=*****

# Set to the URL of the load balancer for the MinIO deployment
# This value *must* match across all MinIO servers. If you do
# not have a load balancer, set this value to to any *one* of the
# MinIO hosts in the deployment as a temporary measure.
MINIO_SERVER_URL="https://api.acp.kt.co.kr:9000"

 

e. TLS 설정

- 참고: https://docs.min.io/docs/how-to-secure-access-to-minio-server-with-tls

 

- self-singed certificate를 생성

   ✓ cert-manager 또는 openssl 명령어로 인증서를 생성한다.

   ✓ 생성한 인증서를 MinIO Server가 실행되는 모든 서버의 "~minio/. minio/certs"에 복사한다. 

   ✓ self-singed certificate를 사용하는 경우 Velero 소프트웨어의 경우 MinIO 접속 시 인증을 위해 CA 파일을 제공해야 한다.

 

- cert-manager로 인증서 생성 

   commonName에 로드벨랜서 도메인 명을,  ipAddresses / dnsNames절에 MinIO Server들의 IP주소와 호스트명과 도메인명을 설정한다.

      로드벨랜서 도메인: api.acp.kt.co.kr (기 등록된 도메인명을 사용)

      MinIO Server: minio-1.acp.kt.co.kr(14.52.244.216), minio-2.acp.kt.co.kr(14.52.244.217)

$ vi minio-cert.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: self-signed-issuer
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: minio-cert
  namespace: yoosung-jeon
spec:
  commonName: api.acp.kt.co.kr
  # Use ipAddresses if your LoadBalancer issues an IP
  # ipAddresses:
  # - 14.52.244.216
  # - 14.52.244.217
  
  # Use dnsNames if your LoadBalancer issues a hostname (eg on AWS)
  dnsNames:
  - api.acp.kt.co.kr
  - minio-1.acp.kt.co.kr
  - minio-2.acp.kt.co.kr
  isCA: true
  issuerRef:
    name: self-signed-issuer
    kind: ClusterIssuer
    group: cert-manager.io
  secretName: minio-certs
$ k apply -f minio-cert.yaml
certificate.cert-manager.io/minio-cert created
$
$ k get secrets minio-certs -n yoosung-jeon -o jsonpath='{.data.ca\.crt}' | base64 --decode > ca.crt
$ k get secrets minio-certs -n yoosung-jeon -o jsonpath='{.data.tls\.crt}' | base64 --decode > public.crt
$ k get secrets minio-certs -n yoosung-jeon -o jsonpath='{.data.tls\.key}' | base64 --decode > private.key
$ scp ca.crt private.key public.crt minio@iap12:/home/minio/.minio/certs
…
$

 

- openssl 명령어로 인증서 생성 

   CN에 도메인 명을,  alt_names절에 MinIO Server들의 IP주소와 호스트명과 도메인명을 설정한다.

   MinIO에 접속하는 클라이언트에게 CA를 제공해야 하는 경우 public.crt를 제공한다.

$ mkdir -p ~/.minio/certs
$ openssl genrsa -out private.key 2048
Generating RSA private key, 2048 bit long modulus
.................................................................................................................................................+++
........+++
e is 65537 (0x10001)
$ vi openssl.conf
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
C = KR
ST = Sejong
L = Sejong
O = MyOrg
OU = KT
CN = api.acp.kt.co.kr

[v3_req]
subjectAltName = @alt_names

[alt_names]
IP.1 = ***.***.244.216
IP.2 = ***.***.244.217
DNS.1 = minio-1.acp.kt.co.kr
DNS.2 = minio-2.acp.kt.co.kr
DNS.3 = api.acp.kt.co.kr
$ openssl req -new -x509 -nodes -days 730 -key private.key -out public.crt -config openssl.conf
$

 

- 공식 문서에서 설명한 certgen 명령어를 사용할 경우 아래와 같이 에러가 발생되니 참고 바란다.

   certgen is a simple Go tool to generate self-signed certificates, and provides SAN certificates with DNS and IP entries:

# wget https://github.com/minio/certgen/releases/download/v0.0.2/certgen-linux-amd64
...
# ./certgen-linux-amd64 -ca -host "minio-1.acp.kt.co.kr,minio-2.acp.kt.co.kr,api.acp.kt.co.kr"
...
#
[root@iap12 ~]# journalctl -u minio -f
...
Nov 10 14:58:22 iap12 systemd[1]: Started MinIO.
Nov 10 14:58:38 iap12 minio[111190]: ERROR Unable to load the TLS configuration: Invalid TLS certificate
Nov 10 14:58:38 iap12 minio[111190]: > Please check the content of your certificate data
Nov 10 14:58:38 iap12 minio[111190]: HINT:
Nov 10 14:58:38 iap12 minio[111190]: Only PEM (x.509) format is accepted as valid public & private certificates
Nov 10 14:58:38 iap12 systemd[1]: minio.service: main process exited, code=exited, status=1/FAILURE

 

f. MinIO Server 실행

- MinIO Server를 실행한다.

# systemctl enable minio
Created symlink from /etc/systemd/system/multi-user.target.wants/minio.service to /etc/systemd/system/minio.service.
# systemctl start minio
#

 

- MinIO Server가 정상적으로 실행되었는지 확인한다.

[root@iap12 ~]# journalctl -u minio.service
...
Nov 11 11:34:09 iap12 systemd[1]: Starting MinIO...
Nov 11 11:34:09 iap12 systemd[1]: Started MinIO.
Nov 11 11:34:27 iap12 minio[52152]: Waiting for all MinIO sub-systems to be initialized.. lock acquired
Nov 11 11:34:27 iap12 minio[52152]: Verifying if 2 buckets are consistent across drives...
Nov 11 11:34:27 iap12 minio[52152]: Automatically configured API requests per node based on available memory on the system: 821
Nov 11 11:34:27 iap12 minio[52152]: All MinIO sub-systems initialized successfully
Nov 11 11:34:27 iap12 minio[52152]: Waiting for all MinIO IAM sub-system to be initialized.. lock acquired
Nov 11 11:34:27 iap12 minio[52152]: Status:         4 Online, 0 Offline.
Nov 11 11:34:27 iap12 minio[52152]: API: https://***.***.244.216:9000  https://10.244.2.1:9000  https://172.17.0.1:9000  https://10.244.2.0:9000  https://127.0.0.1:9000
Nov 11 11:34:27 iap12 minio[52152]: Console: https://***.***.244.216:9001 https://10.244.2.1:9001 https://172.17.0.1:9001 https://10.244.2.0:9001 https://127.0.0.1:9001
Nov 11 11:34:27 iap12 minio[52152]: Documentation: https://docs.min.io
[root@iap13 ~]# journalctl -u minio.service
...
Nov 11 11:32:22 iap13 systemd[1]: Starting MinIO...
Nov 11 11:32:22 iap13 systemd[1]: Started MinIO.
...
Nov 11 11:34:27 iap13 minio[90381]: Client https://minio-1.acp.kt.co.kr:9000/minio/storage/data_02/minio/v41 online
Nov 11 11:34:27 iap13 minio[90381]: Client https://minio-1.acp.kt.co.kr:9000/minio/lock/v7 online
Nov 11 11:34:27 iap13 minio[90381]: Client https://minio-1.acp.kt.co.kr:9000/minio/storage/data_01/minio/v41 online
Nov 11 11:34:27 iap13 minio[90381]: Waiting for all MinIO sub-systems to be initialized.. lock acquired
Nov 11 11:34:27 iap13 minio[90381]: Verifying if 2 buckets are consistent across drives...
Nov 11 11:34:27 iap13 minio[90381]: Waiting for all MinIO sub-systems to be initialized.. possible cause (Unable to list buckets to heal: Storage resources are insufficient for the write operation test/)
Nov 11 11:34:29 iap13 minio[90381]: Waiting for all MinIO sub-systems to be initialized.. lock acquired
Nov 11 11:34:29 iap13 minio[90381]: Verifying if 2 buckets are consistent across drives...
Nov 11 11:34:29 iap13 minio[90381]: Automatically configured API requests per node based on available memory on the system: 1769
Nov 11 11:34:29 iap13 minio[90381]: All MinIO sub-systems initialized successfully
Nov 11 11:34:29 iap13 minio[90381]: Waiting for all MinIO IAM sub-system to be initialized.. lock acquired
Nov 11 11:34:29 iap13 minio[90381]: Status:         4 Online, 0 Offline.
Nov 11 11:34:29 iap13 minio[90381]: API: https://***.***.244.217:9000  https://10.244.9.1:9000  https://172.17.0.1:9000  https://10.244.9.0:9000  https://127.0.0.1:9000
Nov 11 11:34:29 iap13 minio[90381]: Console: https://***.***.244.217:9001 https://10.244.9.1:9001 https://172.17.0.1:9001 https://10.244.9.0:9001 https://127.0.0.1:9001
Nov 11 11:34:29 iap13 minio[90381]: Documentation: https://docs.min.io

 

g. HAProxy 설정

- keepalived / haproxy에 대한 자세한 설정은 'keepalived, haproxy for K8s'를 참고하기 바란다.

- HAProxy에 MinIO 서비스 포트(9000)와 콘솔 포트(9001)에 대한 프락시 설정을 한다.

# vi /etc/haproxy
...
#---------------------------------------------------------------------
# MinIO (Obejct storage)
#---------------------------------------------------------------------
frontend minio_service
    bind *:9000
    mode tcp
    option tcplog
    default_backend minio_servce_backend

backend minio_servce_backend
    option httpchk GET /healthz
    http-check expect status 200
    mode tcp
    option ssl-hello-chk
    balance     leastconn
        server iap12 ***.***.244.216:9000 check
        server iap13 ***.***.244.217:9000 check

frontend minio_console
    bind *:9001
    mode tcp
    option tcplog
    default_backend minio_console_backend

backend minio_console_backend
    option httpchk GET /healthz
    http-check expect status 200
    mode tcp
    option ssl-hello-chk
    balance     leastconn
        server iap12 ***.***.244.216:9001 check
        server iap13 ***.***.244.217:9001 check
# systemctl restart haproxy

#

 

h. MinIO Console 접속

- 분산 모드에서는 모든 서버가 엔드포인트가 되기 때문에 아무 서버에 접속해도 동일한다.

   로드 밸랜서 접근: https://api.acp.kt.co.kr:9001

   개별 서버 접근: https://minio-1.acp.kt.co.kr:9001, https://minio-2.acp.kt.co.kr:9001

- Console 접속

   ✓ Chrome v80 이상:  루트 인증서(CA)를 신뢰하지 않기 때문에 "NET::ERR_CERT_INVALID" 에러로 접속 불가

       우회 방법: 에러 화면에서 빈 여백을 선택 후 'thisisunsafe'를 입력하면 접근됨. (Chrome v95 테스트)

   ✓ Firefox : 경고 무시하고 접속 가능 - 'Advanced...' ⇢ 'Accept the Risk and Continuer'

- Console 로그인 시 사용자명과 암호는 '/etc/default/minio'에 설정한 MINIO_ROOT_USER, MINIO_ROOT_PASSWORD를 입력한다.

 

h. Region 설정

- AWS S3 클라이언트가 MinIO에 접근할 경우 region을 지정해야 하므로 MinIO Console에서 값을 설정한다.

- AWS에서 서울에 대한 region 코드명은 ap-northeast-2이다.

- Console 화면에서 Settings > Region을 선택 후 Server location 항목에 입력하고 저장 후에 MinIO를 재기동한다.

 

 

4. MinIO Client (mc) 설치 및 사용

a. mc 설치

# curl https://dl.min.io/client/mc/release/linux-amd64/mc -o mc
# mv mc /usr/local/bin
# chmod +x /usr/local/bin/mc
#

 

b. MinIO 서버 접속 정보 생성

- MinIO 접속 서버 주소는 로드 밸래서(keepalived) 주소를 사용하였다. Self-signed 인증서를 사용하고 있기 때문에 '--insecure' 옵션을 추가하였다.

$ mc alias set minio-1 https://api.acp.kt.co.kr:9000 minioadmin ***** --insecure
Added `minio` successfully.
$
$ mc alias list minio
minio
  URL       : https://api.acp.kt.co.kr:9000
  AccessKey : minioadmin
  SecretKey : *****
  API       : s3v4
  Path      : auto

$ mc admin info minio --insecure
●  minio-1.acp.kt.co.kr:9000
   Uptime: 31 minutes
   Version: 2021-11-09T03:21:45Z
   Network: 2/2 OK
   Drives: 2/2 OK

●  minio-2.acp.kt.co.kr:9000
   Uptime: 31 minutes
   Version: 2021-11-09T03:21:45Z
   Network: 2/2 OK
   Drives: 2/2 OK

1.4 MiB Used, 1 Bucket, 1 Object
4 drives online, 0 drives offline
$

 

c. 사용자 추가

- 참고: https://docs.min.io/docs/minio-multi-user-quickstart-guide.html

 

- 신규 사용자가 사용할 bucket을 생성한다.

   minio : target (mc alias 명령어로 생성)

   velero : bucket 명

$ mc mb minio/velero --insecure
Bucket created successfully `minio/velero`.
$

 

- 신규 사용자에게 적용할 정책을 생성한다.

   ✓ Action: "s3:*" ⇠ 권한 부여: *(Read/Write), PutObject(WriteOnly), GetObject(ReadOnly)

   ✓ Resource: velero ⇠ 객체를 생성/삭제할 수 있는 bucket 명

$ vi velero-readwrite.json
{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Effect": "Allow",
   "Action": [
    "s3:*"
   ],
   "Effect": "Allow",
   "Resource": [
    "arn:aws:s3:::velero/*"
   ]
  }
 ]
}
$ mc admin policy add minio velero-readwrite velero-readwrite.json --insecure
Added policy `velero-readwrite` successfully.
$

 

- 신규 사용자를 생성하고 생성한 정책을 적용한다.

$ mc admin user add minio velero velero12#$ --insecure
Added user `velero` successfully.
$ mc admin policy set minio velero-readwrite user=velero --insecure
Policy `velero-readwrite` is set on user `velero`
$
$ mc admin user list minio --insecure
enabled    velero                velero-readwrite
$

 

- MinIO Console에 신규 사용자(velero)로 접속하면 아래와 같다. velero bucket 안에 파일을 추가하거나 삭제할 수 있다.

 

 

5. Metric

- Prometheus로 MinIO Metric 데이터를 수집 시 MinIO Console에서 아래와 같이 다양한 정보를 제공한다.

- 참고: https://docs.min.io/minio/baremetal/monitoring/metrics-alerts/minio-metrics-and-alerts.html#metrics-and-alerts

'Kubernetes > Storage' 카테고리의 다른 글

NFS subdir external provisioner  (0) 2022.01.11
NFS-Client Provisioner - PV 마운트 위치  (0) 2021.10.22
Rook Ceph - DiskPressure  (0) 2021.09.16
Rook Ceph - scrub error  (0) 2021.09.16
Rook Ceph - rook-ceph-osd POD is CrashLoopBackOff  (0) 2021.09.16

댓글