Informacje wstępne o projekcie s3store
Opis projektu s3store obejmuje 2 wpisy na tym blogu:
- https://itadmin.vblog.ovh/klaster-okd-4-19-openshift-projekt-s3store-oparty-na-minio-s3store-manager/
- https://itadmin.vblog.ovh/klaster-okd-4-19-openshift-projekt-s3store-oparty-na-minio-s3store-gui/
Opis rozwiązania MinIO
MinIO to lekka i „budżetowa” obiektowa pamięć masowa, w 100% zgodna z API Amazon S3 (Simple Storage Service). Najlepiej sprawdza się do trzymania danych nieustrukturyzowanych, czyli np. zdjęć, filmów, logów, plików eksportów czy różnych „artefaktów” z systemów.
Jest uniwersalne, bo możesz je wykorzystać m.in. do:
- archiwizacji danych,
- składowania i analizy dużych zbiorów danych,
- backupów oraz odtwarzania awaryjnego (DR).
MinIO pozwala też łatwo zbudować klaster z wielu mniejszych instancji storage’u (tzw. podejście „microstorage” – dużo małych elementów zamiast jednego dużego). Dzięki temu rozwiązanie jest proste do skalowania (dokładasz kolejne nody) i potrafi zapewnić wysoką dostępność, bo awaria pojedynczej instancji nie musi zatrzymać całej usługi.
S3 (i MinIO jako „S3-compatible”) nie jest filesystemem, tylko API do obiektów:
- Bucket = logiczny „kontener”
- Object = plik + metadane, identyfikowany przez klucz (np. uploads/mors.1.0.0_openshift.tar.gz)
Nie ma „montowania S3 jako PVC” w naturalny sposób. Więcej informacji:
Założenia projektu s3store


Projekt s3store składa się z 2 aplikacji:
1. Aplikacja s3store-manager, która obsługuje funkcjonalność
- MinIO Server (S3 API)
- MinIO Console (admin)
i zawiera elementy
- Secret z root credentials (admin) MinIO (np. MINIO_ROOT_USER, MINIO_ROOT_PASSWORD)
- Deployment
- Service port 9000 → S3 API, port 9001 → MinIO Console
- Route(y): route do Console (żeby adminowo klikać z przeglądarki). route do S3 API (jeśli chcesz upload bezpośrednio z laptopa / presigned URLs)
MinIO ma wbudowaną konsolę web i standardowo wystawia ją na osobnym porcie.
ewentualnie Job „init” do bucket/user/policy
2. Aplikacja s3store-gui, który obsługuje funkcjonalność
- PHP: upload + listing + download link
- PHP odbiera upload
- PHP robi putObject() do MinIO przez S3 API
- PHP pokazuje link/listę obiektów w bucket
Przygotowanie PV pod S3 MinIO na storage.okdlab.local
Tworzymy nowy wolumen lvm o nazwie lv_pvc_06 o rozmiarze 32 GB w grupie vg_datastore na serwerze 192.168.40.20 (storage.okdlab.local). Więcej informacji o przygotowaniu maszyny wirtualnej storage.okdlab.local https://itadmin.vblog.ovh/klaster-okd-openshift-na-maszynach-wirtualnych-proxmox-przygotowanie-maszyny-storage-nfs/
# na serwerze 192.168.40.20 (storage.okdlab.local) sprawdzamy ilośc wolnego miejsca na grupie vg_datastore vgdisplay vg_datastore | egrep -i "VG Size|Free PE|PE Size" VG Size <64.00 GiB PE Size 4.00 MiB Free PE / Size 11007 / <43.00 GiB # przygotowanie volumenu lv o rozmiarze 32GB lvcreate -L 32G -n lv_pvc_06 vg_datastore mkfs.xfs /dev/vg_datastore/lv_pvc_06 mkdir -p /mnt/lv_pvc_06 mount /dev/vg_datastore/lv_pvc_06 /mnt/lv_pvc_06 # Do /etc/fstab zwykle lepiej dodać po UUID blkid /dev/vg_datastore/lv_pvc_06 /dev/vg_datastore/lv_pvc_06: UUID="9269f680-f5fe-488a-ae8c-17b739bf5c20" BLOCK_SIZE="512" TYPE="xfs" # dodać taki wpis do /etc/fstab UUID=9269f680-f5fe-488a-ae8c-17b739bf5c20 /mnt/lv_pvc_06 xfs defaults 0 0 # dodajemy w /etc/exports /mnt/lv_pvc_06 192.168.40.0/24(rw,sync,no_root_squash,no_all_squash,no_wdelay) sudo systemctl restart nfs-server showmount -e localhost # dodajemy uprawnienia sudo chmod 0777 /mnt/lv_pvc_06 sudo chown -R nobody:nobody lv_pvc_06
Struktura aplikacji s3store-manager w projekcie s3store-prod
/repo/pakiety/s3store/1.0.0/s3store-manager drwxr-xr-x 3 bastuser bastuser 29 Feb 14 10:27 .. -rw-r--r-- 1 bastuser bastuser 128 Feb 14 11:10 cm-s3store-minio-config.yaml -rw-r--r-- 1 bastuser bastuser 1260 Feb 14 11:16 deploy-s3store-manager.yaml -rw-r--r-- 1 bastuser bastuser 461 Feb 14 11:03 Dockerfile -rw-r--r-- 1 bastuser bastuser 355 Feb 14 11:00 pv-06.yaml -rw-r--r-- 1 bastuser bastuser 339 Feb 14 11:01 pvc-06.yaml -rw-r--r-- 1 bastuser bastuser 546 Feb 14 14:04 s3store-gui-policy.json -rw-r--r-- 1 bastuser bastuser 178 Feb 14 11:12 secret-s3store-minio-root.yaml -rw-r--r-- 1 bastuser bastuser 254 Feb 14 11:18 svc-s3store-manager.yaml
Definicja PVC na potrzeby aplikacji s3store-manager
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv-s3store
spec:
capacity:
storage: 32Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
storageClassName: s3store-nfs-manual
persistentVolumeReclaimPolicy: Retain
mountOptions:
- vers=4.1
nfs:
path: /mnt/lv_pvc_06
server: 192.168.40.20
readOnly: falsePrzygotowanie Dockerfile na potrzeby zbudowania obrazu aplikacji
OpenShift odpali z własnym UID, najważniejsze są uprawnienia na /data.
FROM quay.io/minio/minio:latest
# (root group 0 + mirror perms g=u)
USER 0
RUN mkdir -p /data /tmp/minio && \
chgrp -R 0 /data /tmp/minio && \
chmod -R g+rwX /data /tmp/minio && \
chmod -R g=u /data /tmp/minio
# Wróć do nie-root (OpenShift i tak odpali z własnym UID; ale to nie szkodzi)
USER 1001
EXPOSE 9000 9001
# MinIO image ma entrypoint "minio", więc CMD to parametry dla "minio ..."
CMD ["server", "/data", "--console-address", ":9001"]ConfigMapa dla aplikacji s3store-manager
apiVersion: v1 kind: ConfigMap metadata: name: s3store-minio-config namespace: s3store-prod data: MINIO_REGION_NAME: "homelab"
Secret z root credentials (admin MinIO) dla aplikacji s3store-manager
apiVersion: v1 kind: Secret metadata: name: s3store-minio-root namespace: s3store-prod type: Opaque stringData: MINIO_ROOT_USER: "minioadmin" MINIO_ROOT_PASSWORD: "1234abcd."
Przygotowanie aplikacji s3store-manager w projekcie s3store-prod
cd /repo/pakiety/s3store/1.0.0/s3store-manager/ # PV (cluster-scope) oc apply -f pv-06.yaml oc get pv | grep nfs-pv-s3store oc describe pv nfs-pv-s3store # Projekt / namespace oc new-project s3store-prod # albo jeśli już istnieje: oc project s3store-prod # PVC oc apply -f pvc-06.yaml oc get pvc oc describe pvc s3store-manager-data # Secret z root credentials (admin MinIO) oc apply -f /repo/pakiety/s3store/1.0.0/s3store-manager/secret-s3store-minio-root.yaml # ConfigMap (opcjonalna, ale przydatna) oc apply -f /repo/pakiety/s3store/1.0.0/s3store-manager/cm-s3store-minio-config.yaml # utwórz BuildConfig typu docker, build z lokalnego katalogu oc new-build --name=s3store-manager --binary --strategy=docker -n s3store-prod # wystartuj build, biorąc Dockerfile z tego katalogu oc start-build s3store-manager --from-dir=. --follow -n s3store-prod # sprawdź image stream oc get is -n s3store-prod oc describe is s3store-manager -n s3store-prod
Uruchomienie aplikacji s3store-manager w projekcie s3store-prod
Deployment MinIO (s3store-manager)
apiVersion: apps/v1
kind: Deployment
metadata:
name: s3store-manager
namespace: s3store-prod
spec:
replicas: 1
selector:
matchLabels:
app: s3store-manager
template:
metadata:
labels:
app: s3store-manager
spec:
containers:
- name: minio
image: image-registry.openshift-image-registry.svc:5000/s3store-prod/s3store-manager:latest
imagePullPolicy: Always
envFrom:
- secretRef:
name: s3store-minio-root
- configMapRef:
name: s3store-minio-config
ports:
- name: s3api
containerPort: 9000
- name: console
containerPort: 9001
volumeMounts:
- name: data
mountPath: /data
readinessProbe:
httpGet:
path: /minio/health/ready
port: 9000
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /minio/health/live
port: 9000
initialDelaySeconds: 20
periodSeconds: 20
volumes:
- name: data
persistentVolumeClaim:
claimName: s3store-manager-data
oc apply -f deploy-s3store-manager.yaml oc rollout status deployment/s3store-manager oc get pods -o wide oc logs deployment/s3store-manager -f
Service (API + Console) aplikacji s3store-manager
apiVersion: v1
kind: Service
metadata:
name: s3store-manager
namespace: s3store-prod
spec:
selector:
app: s3store-manager
ports:
- name: s3api
port: 9000
targetPort: 9000
- name: console
port: 9001
targetPort: 9001oc apply -f svc-s3store-manager.yaml oc get svc s3store-manager -n s3store-prod oc describe svc s3store-manager -n s3store-prod
Route edge TLS (oddzielnie dla API i dla Console) aplikacji s3store-manager
# S3 API (9000) oc create route edge s3store-s3api \ --service=s3store-manager \ --port=s3api \ -n s3store-prod # Console (9001) - to jest TA właściwa konsola admin oc create route edge s3store-console \ --service=s3store-manager \ --port=console \ -n s3store-prod oc get route -n s3store-prod
oc rollout restart deployment/s3store-manager oc rollout status deployment/s3store-manager oc get pods -o wide oc logs deployment/s3store-manager -f
Problem z PersistentVolumeClaims po usunięciu projektu s3store-prod
To jest efekt Retain po skasowaniu starego projektu s3store. Dopóki ten claimRef siedzi w PV, nowy PVC w s3store-prod nie zbinduje się, więc pody będą Pending
# jeśli pv jest statusie Released
[bastuser@bastion s3store-manager]$ oc get pv | egrep "nfs-pv-s3store|s3store"
nfs-pv-s3store 32Gi RWX Retain Released s3store/s3store-manager-data s3store-nfs-manual <unset> 65m
# to należy zwolnić PV usuwając claimRef
oc project s3store-prod
oc patch pv nfs-pv-s3store --type=merge -p '{"spec":{"claimRef": null}}'
# teraz powinien być status Available
[bastuser@bastion s3store-manager]$ oc get pv nfs-pv-s3store
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
nfs-pv-s3store 32Gi RWX Retain Available s3store-nfs-manual <unset> 67mPrzygotowanie bucket w MinIO GUI

Logujemy się na stronie https://s3store-console-s3store-prod.apps.testcluster.okdlab.local/login
- użytkownik: minioadmin
- hasło: 1234abcd.
Powyższe informacje ustawiliśmy w pliku /repo/pakiety/s3store/1.0.0/s3store-manager/secret-s3store-minio-root.yaml

Klikamy na Create Bucket
Bucket Name: uploads
bucket musi być zwykle lowercase, bez spacji, najlepiej bez podkreśleń
web UI w CE zostało ograniczone do przeglądania obiektów i podstawowowych operacji na bucker
Najpewniej z oficjalnej dystrybucji MinIO (opis instalacji jest w dokumentacji/stronie MinIO).
Jeśli wolisz “na szybko” i masz internet na bastionie, zwykle robisz to curl’em (tu podaję jako przykład – dopasuj do swojej dystrybucji):
Przygotowanie bucket,uzytkownika, policy, kluczy w Secret w MinIO przy użyciu narzędzia mc (mcli)
Uwaga występuje klasyczny konflikt nazw: mc = Midnight Commander na Linuksie, a MinIO Client też chce się nazywać mc.
Dlatego w moim przypadku narzędzie zamiast mc będzie nazywało się mcli.
curl -sSL -o /tmp/mcli https://dl.min.io/client/mc/release/linux-amd64/mc chmod +x /tmp/mcli sudo mv /tmp/mcli /usr/local/bin/mcli mcli --version which mc which mcli
Utworzenie aliasu o wygodnej nazwie mys3store aby nie podawać w kółko całego urla i loginu oraz trybu insecure
mcli alias set mys3store \
https://s3store-s3api-s3store-prod.apps.testcluster.okdlab.local \
minioadmin '1234abcd.' \
--insecure
mcli: Configuration written to `/home/bastuser/.mcli/config.json`. Please update your access credentials.
mcli: Successfully created `/home/bastuser/.mcli/share`.
mcli: Initialized share uploads `/home/bastuser/.mcli/share/uploads.json` file.
mcli: Initialized share downloads `/home/bastuser/.mcli/share/downloads.json` file.
Added `mys3store` successfully.Wyświetlenie listy zapisanych aliasów
mcli alias list gcs URL : https://storage.googleapis.com AccessKey : YOUR-ACCESS-KEY-HERE SecretKey : YOUR-SECRET-KEY-HERE API : S3v2 Path : dns Src : /home/bastuser/.mcli/config.json local URL : http://localhost:9000 AccessKey : SecretKey : API : Path : auto Src : /home/bastuser/.mcli/config.json mys3store URL : https://s3store-s3api-s3store-prod.apps.testcluster.okdlab.local AccessKey : minioadmin SecretKey : 1234abcd. API : s3v4 Path : auto Src : /home/bastuser/.mcli/config.json play URL : https://play.min.io AccessKey : Q3AM3UQ867SPQQA43P2F SecretKey : zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG API : S3v4 Path : auto Src : /home/bastuser/.mcli/config.json s3 URL : https://s3.amazonaws.com AccessKey : YOUR-ACCESS-KEY-HERE SecretKey : YOUR-SECRET-KEY-HERE API : S3v4 Path : dns Src : /home/bastuser/.mcli/config.json
Utworzenie bucketu o nazwie uploads
mcli mb --ignore-existing mys3store/uploads --insecure # wyświetl wszystkie buckety mcli ls mys3store --insecure # wyświetl zawartości bucketu mcli ls mys3store/uploads --insecure # wrzucenie lokalnego pliku na bucket cd /repo/pakiety/s3store/1.0.0/s3store-manager tar -czf s3storemanager_1.0.0_coo_openshift.tar.gz . mcli cp s3storemanager_1.0.0_coo_openshift.tar.gz mys3store/uploads/ --insecure # usunięcie obiektu z bucketa mcli rm mys3store/uploads/s3storemanager_1.0.0_coo_openshift.tar.gz --insecure
Utworzenie policy dla aplikacji s3store-gui (tylko bucket uploads)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket",
"s3:ListBucketMultipartUploads"
],
"Resource": [
"arn:aws:s3:::uploads"
]
},
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:GetObject",
"s3:ListMultipartUploadParts",
"s3:PutObject",
"s3:GetObjectTagging",
"s3:PutObjectTagging"
],
"Resource": [
"arn:aws:s3:::uploads/*"
]
}
]
}mcli admin policy create mys3store s3store-gui-policy s3store-gui-policy.json --insecure \ || mcli admin policy update mys3store s3store-gui-policy s3store-gui-policy.json --insecure # weryfikacja mcli admin policy info mys3store s3store-gui-policy --insecure
Jeśli dokonano jakiś zmian w /repo/pakiety/s3store/1.0.0/s3store-manager/s3store-gui-policy.json to można zaktualizować polisę poleceniem:
mcli admin policy create mys3store s3store-gui-policy ./s3store-gui-policy.json --insecure # weryfikacja mcli admin policy info mys3store s3store-gui-policy --insecure
Utworzenie usera aplikacyjnego s3store-gui oraz podpięcie policy
#generujemy sobie losowy secret dla bezpieczeństwa openssl rand -base64 36 | tr -d '\n' | cut -c1-32 cGW8oKh0mleGaNKvWHecLCApaDYj+w2S # Dodaj usera i podepnij policy: mcli admin user add mys3store s3store-gui-user cGW8oKh0mleGaNKvWHecLCApaDYj+w2S --insecure || true Added user `s3store-gui-user` successfully. mcli admin policy attach mys3store s3store-gui-policy --user s3store-gui-user --insecure Attached Policies: [s3store-gui-policy] To User: s3store-gui-user # lista użytkowników w buckecie mcli admin user list mys3store --insecure enabled s3store-gui-user s3store-gui-policy # lista polis w buckecie mcli admin policy list mys3store --insecure readwrite s3store-gui-policy writeonly consoleAdmin diagnostics readonly # lista podpiętych polis do użytkownika w buckecie mcli admin user info mys3store s3store-gui-user --insecure AccessKey: s3store-gui-user Status: enabled PolicyName: s3store-gui-policy MemberOf: []
Sprawdzenie zajętości i wolnego miejsca w bucket
# Suma rozmiaru w bucketcie mcli du mys3store/uploads --insecure # Lista obiektów z rozmiarami (manualna kontrola) mcli ls --recursive mys3store/uploads --insecure oc -n s3store-prod rsh deploy/s3store-manager df -h /data exit
Ustawienia quota na bucket
# informacje o quota mcli quota info mys3store/uploads --insecure # ustawienia quota mcli quota set mys3store/uploads --size 10Gi --insecure # usunięcie quota mcli quota clear mys3store/uploads --insecure

