MinIO ist ein offenes, AWS/S3 API kompatibles Object-Storage System, welches hervorragend dazu geeignet ist, in Kubernetes betrieben zu werden. Die Installation einer produktionsreifen Konfiguration gestaltet sich äußerst einfach.
Die einzigen beiden Voraussetzungen sind der Zugriff auf einen Kubernetes Cluster und HELM (in Version 3). Sollte der Cluster noch nicht bereit stehen, kannst du natürlich Minikube verwenden oder dir einmal k3s ansehen, damit kann man in wenigen Sekunden einen schlüsselfertigen Single-Node Kubernetes Cluster aufsetzen. Den Kubernetes Paketmanager HELM werden wir für die Installation von MinIO verwenden.
Starten wir mit der..
Generierung von Zugangsdaten
Nachfolgend erzeugen wir eine access key ID und einen secret access key, welche alsbald die administrativen Zugangsdaten zu unserem MinIO Konto (aws:PrincipalType == “account”) darstellen werden. Sie entsprechen im Prinzip Benutzernamen und Passwort.
Im Beispiel verwende ich openssl
, aber es kann natürlich jede andere Methode für die Generierung verwendet werden:
AKEY="$(openssl rand -hex 32)"
SKEY="$(openssl rand -hex 32)"
Vorbereitung von HELM
Danach fügen wir der lokalen HELM Installation das MinIO chart repository hinzu und aktualisieren die Metadaten:
helm repo add minio https://helm.min.io/
helm repo update
Nun ist alles bereit, um MinIO im Kubernetes Cluster zu installieren.
Update: Mittlerweile wurde das HELM Chart für die Installation von MinIO als veraltet markiert. Das offizielle Chart wird nunmehr nur noch sporadisch gepflegt und die Installation des MinIO Operators empfohlen!
Stand 24.02.2021 funktioniert jedoch alles noch ohne Einschränkungen und das verwendete Container Image entspricht nahezu dem aktuellen Release.
MinIO Cluster Installation
Wir erstellen einen neuen Namespace und starten die Installation:
kubectl create ns minio
helm install --namespace minio \
--set "accessKey=${AKEY},secretKey=${SKEY}" \
--set "persistence.size=100Gi" \
--set "service.type=LoadBalancer" \
--set "mode=distributed,replicas=3" \
minio minio/minio
Info:
Mit helm show values minio/minio
kann man sich alle verfügbaren HELM Parameter und deren Standardwerte anzeigen lassen.
Einrichtung von TLS
Für ein produktives Setup sollte man in jedem Fall TLS aktivieren, andernfalls werden die Logindaten im Klartext übertragen! Hierzu muss man lediglich die HELM Parameter “tls.enabled=true” und “tls.certSecret=minio-tls-secret” setzen. Letzteres muss auf ein Kubernetes TLS Secret verweisen, welches public.crt und private.key beinhaltet.
Das Kubernetes Secret kann auf folgende Weise erstellt werden:
kubectl create secret -n minio tls minio-tls-secret \
--cert=/Pfad/zur/Zertifikatsdatei \
--key=/Pfad/zur/Schlüsseldatei
Um nachträglich MinIO auf TLS hören zu lassen, kann man einfach via helm
ein Upgrade durchführen und die zusätzlichen Parameter anhängen:
helm upgrade --namespace minio \
--set "accessKey=${AKEY},secretKey=${SKEY}" \
--set "persistence.size=100Gi" \
--set "service.type=LoadBalancer" \
--set "mode=distributed,replicas=3" \
--set "tls.enabled=true" \
--set "tls.certSecret=minio-tls-secret" \
minio minio/minio
Administrative Aufgaben
Lokaler Zugriff auf Weboberfläche
Um mit dem Browser auf die MinIO Weboberfläche zugreifen zu können muss man nichts weiter tun, als via kubectl
eine Portweiterleitung auf
den MinIO Kubernetes Service einzurichten. Hierzu genügt:
kubectl port-forward -n minio svc/minio 9000:9000
Danach kann man sich über http://localhost:9000 mit den zuvor erstellten Admin-Zugangsdaten (ACCESS KEY ID/SECRET ACCESS KEY) anmelden, um administrative Aufgaben durchzuführen, wie z.B. eingeschränkte Nutzer und Buckets verwalten, Dateien hochladen oder löschen, etc..
Verwaltung mit MinIO Client aus Cluster
Alternativ und vermutlich auch komfortabler kann man die MinIO Installation mit dem Minio Client, direkt aus dem Kubernetes Cluster heraus, verwalten.
Benutzer mit eingeschränkten Rechten anlegen
Nachfolgend beschreibe ich, wie man mit Hilfe eines “MinIO-CLI-Pods” einen neuen Benutzer (aws:PrincipalType == “user”) mit eingeschränkten Rechten und einem primären bucket aus dem Kubernetes Cluster heraus anlegt.
export MINIO_ACCESS_KEY="$AKEY" # Eingabe der zuvor
export MINIO_SECRET_KEY="$SKEY" # erzeugten Zugangsdaten
NEW_ACCESS_KEY="$(openssl rand -hex 6)" # Generierung zusätzlicher Schlüssel
NEW_SECRET_KEY="$(openssl rand -hex 32)" # für den neuen Benutzer
# Das Stammverzeichnis für neue Benutzer kann frei gewählt werden
BUCKET_BASE_NAME="users"
# Der Name des "buckets" des neuen Benutzers entspricht seiner "ACCESS KEY ID"
USER_BUCKET_NAME="${NEW_ACCESS_KEY}"
Anschließend erstellen wir einen neuen Kubernetes Pod, auf Basis des Bitnami MinIO Client Container-Images. Die Umgebungsvariablen mit den Zugangsdaten werden an den Pod weitergegeben.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: minio-client
spec:
containers:
- image: bitnami/minio-client
imagePullPolicy: Always
name: minio-client
env:
- name: MC_HOST_minio
value: "http://${MINIO_ACCESS_KEY}:${MINIO_SECRET_KEY}@minio-svc.minio.svc.cluster.local:9000"
- name: MC_HOST_test
value: "http://${NEW_ACCESS_KEY}:${NEW_SECRET_KEY}@minio-svc.minio.svc.cluster.local:9000"
- name: MC_USER_ID
value: "${NEW_ACCESS_KEY}"
command: ["sh", "-c", "sleep 5000"]
EOF
Wir warten, bis sich der Pod im Zustand “Running” befindet:
kubectl get po minio-client -w
Und können dann mit kubectl exec
Befehle an den MinIO Client senden, die im Container ausgeführt werden:
kubectl exec -i minio-client -- /bin/bash - <<-EOF
# Der primäre bucket des neuen Nutzers wird auf dem MinIO Server erzeugt.
# 'minio' referenziert hier die Host-Konfiguration aus der
# Umgebungsvariable 'MC_HOST_minio'
mc mb "minio/${BUCKET_BASE_NAME}/${USER_BUCKET_NAME}"
# Wir listen in einer Baumansicht alle Verzeichnisse auf
mc tree minio
# legen den neuen Benutzer an
mc admin user add minio "${NEW_ACCESS_KEY}" "${NEW_SECRET_KEY}"
# und listen anschließend alle existierenden Benutzer auf
mc admin user list minio
# Dann schreiben wir das Regelwerk für den neuen Benutzer
# welches den ausschließlichen Zugriff auf einen primären bucket
# gestattet in eine Datei auf dem Container
cat > /tmp/bucket_policy.json << END
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAllActions",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::${BUCKET_BASE_NAME}/\\\${aws:username}/*"
]
},
{
"Sid": "AllowAllBucketActionsRead",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::${BUCKET_BASE_NAME}/*"
]
}
]
}
END
# Und laden die Richtlinie auf in den MinIO Cluster
mc admin policy add minio \
"${NEW_ACCESS_KEY}-bucket-policy" /tmp/bucket_policy.json
# Anschließend weisen wir sie dem neuen Benutzer zu
mc admin policy set minio \
"${NEW_ACCESS_KEY}-bucket-policy" user="${NEW_ACCESS_KEY}"
# Dann lassen wir uns die Berechtigungen des Nutzers anzeigen
mc admin user info minio "${NEW_ACCESS_KEY}"
EOF
Abschließend testen wir die Berechtigungen des Nutzers mit folgendem Befehl:
kubectl exec -i minio-client -- /bin/bash - <<-EOF
# Bitte beachtet die Referenz der Host-Konfiguration
mc tree test
EOF
Wenn alles funktioniert hat, wird ausschließlich der Pfad zum Benutzer-Bucket in der Baumansicht dargestellt. Ähnlich wie hier:
users
└─ 55a2dd82fa98
Um die Zugangsdaten zu speichern, kann man sie sich noch einmal gesammelt ausgeben lassen:
echo "ADMIN ACCESS_KEY: $MINIO_ACCESS_KEY"
echo "ADMIN SECRET_KEY: $MINIO_SECRET_KEY"
echo "USER ACCESS_KEY: $NEW_ACCESS_KEY"
echo "USER SECRET_KEY: $NEW_SECRET_KEY"
Dann wird der MinIO-Client Pod nicht mehr benötigt und kann gelöscht werden:
kubectl delete po minio-client
Die S3 URI zum Benutzer-Bucket setzt sich wie folgt zusammen:
https://${A_KEY}:${S_KEY}@minio-svc.minio.svc.cluster.local:9000/Pfad/zum/Bucket
Deinstallation des MinIO Clusters
Die Deinstallation gestaltet sich Dank HELM auch sehr einfach:
helm --namespace minio uninstall minio