Minio is a software solution supporting S3 object storage. It used to be the #1 opensource solution to go for software developers. Unfortunately they decided to go for profit instead the community and cut down the features in the community edition severly, removing features entirely or having to build from scratch ourselves.
Below is a working list of steps to implement a small but working minio store in Kubernetes.
This article so far describes creating a regular minio store without encryption. There are several ways to manage encryption depending on your installed version [1]
Prerequisites:
The manifest below installs a working minio store. Adapt the config map and secret to your needs, as well as your PVC. The example below uses an SSHFS storage box, use whatever you have. If you have something like Longhorn, you only will need a PVC.
The current version does not allow any configuration through the web UI, you will have to configure the mc cli and use that one. At first that might be not very convenient for the regular UI user, but in fact allows using scripting like Ansible through git-ops. That also means you have to use 2 ports, 9000 for the API (mc) and 9001 for the web UI.
---
apiVersion: v1
kind: Namespace
metadata:
name: minio
---
apiVersion: v1
kind: ConfigMap
metadata:
name: minio-config
namespace: minio
labels:
app: minio
data:
MINIO_ROOT_USER: <root_user>
---
apiVersion: v1
kind: Secret
metadata:
name: minio-secret
namespace: minio
type: Opaque
stringData:
MINIO_ROOT_PASSWORD: <strong_password>
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: minio-storage-pv
namespace: minio
spec:
capacity:
storage: 150Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: <your_storage_class>
hostPath:
path: /path/to/file
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: minio-storage-pvc
namespace: minio
spec:
storageClassName: <your_storage_class>
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 150Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: minio-deployment
namespace: minio
labels:
app: minio
spec:
replicas: 1
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: quay.io/minio/minio:latest
command:
- /bin/bash
- -c
args:
- minio server /data --console-address :9001
imagePullPolicy: "Always"
ports:
- name: api
containerPort: 9000
protocol: TCP
- name: console
containerPort: 9001
protocol: TCP
envFrom:
- configMapRef:
name: minio-config
- secretRef:
name: minio-secret
volumeMounts:
- name: minio-storage
mountPath: /data
volumes:
- name: minio-storage
persistentVolumeClaim:
claimName: minio-storage-pvc
---
apiVersion: v1
kind: Service
metadata:
labels:
app: minio
name: minio-service
namespace: minio
spec:
type: NodePort
ports:
- name: api
port: 9000
targetPort: 9000
nodePort: 30443
protocol: TCP
- name: console
port: 9001
targetPort: 9001
nodePort: 30533
protocol: TCP
selector:
app: minio
kubectl apply -f minio.yaml
This creates a deployment with 1 replica.
curl https://dl.min.io/client/mc/release/linux-amd64/mc \
--create-dirs \
-o $HOME/minio-binaries/mc
chmod +x $HOME/minio-binaries/mc
export PATH=$PATH:$HOME/minio-binaries/
mc --autocompletion
mc alias set my-minio http://my-minio-url <root_user> <your_strong_password>
mc alias list
play
URL : https://play.min.io
AccessKey : <your_key>
SecretKey : <your_secret>
API : S3v4
Path : auto
Src : /home/user/.mc/config.json
While you have already access to your store using the root user, it is strongly recommended to use regular users for you buckets and create different access keys for every application accessing the bucket.
mc admin user add <your-minio> <your_new_user> >your_new_strong_password>
mc admin user ls <your-minio>
mc admin accesskey create <your-minio>/ <your_new_user> \
--access-key "<your_new_access_key>" \
--secret-key "<your_strong_secret>" \
--name "<your_new_access_key>"
mc admin accesskey list <your_minio>/
User: <your_user>
Access Keys:
<your_new_access_key>, expires: never, sts: false
It is recommended to use different policies for different use cases. For instance an application storing backups in your bucket, you may need all 4 actions, others may only need ListBucket and GetObject.
Create a local file do-all-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListAllMyBuckets"],
"Resource": ["arn:aws:s3:::*"]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::your-bucket",
"arn:aws:s3:::your-bucket/*"
]
}
]
}
mc admin policy create <your-minio> do-all-policy do-all-policy.json
mc admin policy attach <your-minio> do-all-policy --user "your_new_access_key"
Congratulations, you now have a minio store, a user, an access key and can start adding buckets and add files to it!
User Access Keys (often called the "username" and "password" in MinIO terminology) are primary identities used for interactive login to the MinIO Console or management via the mc command line tool. A user account consists of a unique access key and secret key pair, and can be assigned policies directly or inherited through group membership. These credentials are designed for human administrators or managers who need to log in visually or execute administrative commands.
Service Account Access Keys (formerly known as service accounts) are child identities of an existing MinIO user. They are designed exclusively for programmatic access by applications and services. Key characteristics include:
Inheritance: They inherit the access rights of their parent user but can have an additional inline policy to further restrict permissions.
No Console Access: Service accounts cannot be used to log into the MinIO Console; they are strictly for API/S3 programmatic interactions.
Creation: They can be created by the parent user, allowing application owners to generate credentials without administrator intervention, provided the parent user has the necessary permissions.
The following steps are rqeuired in order:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}
mc admin policy create myminio restricted-bucket-access /path/to/my-bucket-policy.json
OR
mc admin user svcacct add ALIAS PARENT_USER --access-key ACCESS_KEY --secret-key SECRET_KEY --policy /path/to/POLICY_FILE
mc admin user svcacct list myminio/ foobar
Now you have a service account underneath your user as created above, which can only access that particular bucket, and only can be used programmatically by an application to manage data in the bucket.
https://docs.min.io/aistor/installation/kubernetes/server-side-encryption/ - server side encryption ↩︎
https://docs.min.io/aistor/reference/cli/ - mc installation ↩︎