Applications need to store files: attachments, images, backups, evidence. Block storage (PVC) is not ideal for this; object storage is.
MinIO offers an S3-compatible API within the cluster. It is lightweight, runs on Kubernetes, and scales with erasure coding.
Course seal: tested on Kubernetes 1.35 with MinIO Operator and a 4-server Tenant.
Object Storage in 30 Seconds
- Bucket: container of objects.
- Object: file + metadata, accessed by key.
- S3 API: HTTP with signature (SigV4).
- Presigned URL: temporary URL for upload/download without credential.
Unlike a PVC, you do not mount it; the application talks HTTP with the bucket. This facilitates multiple pods and external access.
The MinIO Tenant
The operator creates a Tenant with N servers. Each server has its PVC; the set forms a pool with erasure coding.
apiVersion: minio.min.io/v2
kind: Tenant
metadata:
name: portal-minio
namespace: portal
spec:
features:
bucketDNS: false
requestAutoCert: false
configuration:
name: minio-tenant-config
pools:
- name: pool-0
servers: 4
volumesPerServer: 1
volumeClaimTemplate:
metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: portal-nfs
resources:
requests:
storage: 10Gi
With 4 servers, MinIO uses erasure coding: it tolerates the loss of servers/disks without losing data, as long as there is quorum (half + 1).
Typical services:
minio-s3(S3 API, port 9000).minio(console/API, according to the manifest).portal-minio-hl(headless).
Credentials: Root Is Not for the Application
The operator creates a root secret (minio-tenant-creds) with accesskey/secretkey. Do not use root in the application.
Create users/service accounts with minimal policy:
mc alias set local http://minio-s3:9000 "$ROOT_USER" "$ROOT_PASS"
mc admin user add local portal-backend '<secret-forte>'
mc admin policy attach local readwrite --user portal-backend
Or service account (credential linked to a user):
mc admin user svcacct add local portal-backend
For production, create a policy restricted to the necessary buckets (e.g., portal-storage, whatsapp-backup) instead of global readwrite.
The INF-SEC-01 Case
Our app used minioadmin as access/secret. The new image had a guard that refuses default credentials in production. The deploy failed — and the guard was right.
Lesson: the application should never use the MinIO root credential, and default credentials must be rotated before deployment.
Buckets, Versioning, and Lifecycle
mc mb local/portal-storage
mc version enable local/portal-storage
mc ilm add local/portal-storage --expiry-days 90
- Versioning: protects against accidental overwrite/deletion.
- Lifecycle: moves/expires old objects.
- Object lock/WORM: legal retention (compliance), when necessary.
Each bucket has a policy. Do not make everything public; prefer presigned URLs.
External Access
Options:
- Ingress with path
/minio→ MinIO Service. - Dedicated subdomain
minio.exemplo.com. - Internal access only (the application talks to
http://minio-s3:9000).
Beware of presigned URL: it uses the configured endpoint. If the internal endpoint is minio-s3, the URL does not work in the browser. Configure the public URL (MINIO_PUBLIC_URL) correctly.
Lab
- Check the Tenant:
kubectl -n portal get tenant.minio.min.io
kubectl -n portal get pods -l v1.min.io/tenant=portal-minio
kubectl -n portal get pvc | grep minio
- Use
mcfrom inside a MinIO pod:
kubectl -n portal exec portal-minio-pool-0-0 -c minio -- sh
mc --config-dir /tmp/.mc alias set local http://127.0.0.1:9000 "$ROOT_USER" "$ROOT_PASS"
mc --config-dir /tmp/.mc ls local
-
Create a bucket and an application user with minimal policy.
-
Upload/download:
echo hello > /tmp/hello.txt
mc --config-dir /tmp/.mc cp /tmp/hello.txt local/portal-storage/
mc --config-dir /tmp/.mc cat local/portal-storage/hello.txt
- Generate a presigned URL and test in the browser.
Common Errors
| Symptom | Cause |
|---|---|
Tenant does not become Ready |
PVC, resource, image, or config |
ImagePullBackOff |
image not on node/registry |
| App receives 403 | wrong policy/user |
| Presigned URL does not open | wrong public endpoint |
| Console 404 on Ingress | wrong path rewrite |
| Poor performance | slow NFS or few disks |
Checklist
- [ ] Tenant with 4 servers and Bound PVCs.
- [ ] Root creds outside the application.
- [ ] Service account/minimal policy per app.
- [ ] Versioning/lifecycle defined.
- [ ] Public endpoint and presigned URLs tested.
- [ ] Bucket backup (Velero or
mc mirror). - [ ] Documented credential rotation.
Glossary
- Tenant: MinIO Operator resource.
- erasure coding: redundancy by fragmentation.
- bucket: container of objects.
- presigned URL: temporary signed URL.
- service account: credential linked to a MinIO user.
- lifecycle: expiration/migration rules.
Next
Now that we have database and object storage, let's go to queues and cache: RabbitMQ and Redis with quorum, sentinel, and PDB.
Next: Kubernetes Course 17 — RabbitMQ and Redis: Quorum, Sentinel, and PDB
Keep reading
Read also

StorCLI - Complete Cheat Sheet
StorCLI is the official and modern tool for managing Broadcom/LSI RAID controllers. This guide covers essential commands, syntax and use cases.
12 min de leitura
Portal ITSMBusiness Services in Nyverra Portal: Translating IT into Business
The business doesn't feel a server go down — it feels email stop. The Business Services (Service Mapping) module of Nyverra ITSM Portal connects services like Email, ERP or PACS to CMDB assets, revealing the real impact of each failure.
5 min de leitura
SegurançaRPO vs RTO: How to Define Before Buying Backup (and Why Most Companies Get It Wrong)
Most companies buy backup asking the wrong question: "how much does it cost?". The right question is: how much data can I lose (RPO) and how long can I be down (RTO). Discover how to define these numbers per system and avoid purchasing protection based on price, not on real need.
9 min de leitura
Comments
No comments yet
Be the first to share your thoughts on this article.

Leave a comment