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별 결과는 다음과 같다.
Eraure Code Calulator를 사용하면 Erasure code stripe size/parity별 사용 용량과 장애 허용 범위를 쉽게 산정할 수 있다.
✓ 볼륨 사이즈가 상이할 경우는 최소 사이즈를 기준으로 사용되며, 나머지 공간들은 버려진다.
✓ 최적의 성능을 내기 위해서 JBOD(Just a bunch of disks), xfs를 권고한다.
✓ 권고하는 Linux OS는 RHEL8+ 또는 Ubuntu 18.04+이다.
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에서 아래와 같이 다양한 정보를 제공한다.
'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 |
댓글